github.com/aergoio/aergo@v1.3.1/types/blockchain.go (about)

     1  /**
     2   *  @file
     3   *  @copyright defined in aergo/LICENSE.txt
     4   */
     5  
     6  package types
     7  
     8  import (
     9  	"bytes"
    10  	"encoding/binary"
    11  	"io"
    12  	"math"
    13  	"math/big"
    14  	"reflect"
    15  	"runtime"
    16  	"sync/atomic"
    17  	"time"
    18  
    19  	"github.com/aergoio/aergo/internal/enc"
    20  	"github.com/aergoio/aergo/internal/merkle"
    21  	"github.com/gogo/protobuf/proto"
    22  	"github.com/libp2p/go-libp2p-core/crypto"
    23  	"github.com/minio/sha256-simd"
    24  )
    25  
    26  const (
    27  	// DefaultMaxBlockSize is the maximum block size (currently 1MiB)
    28  	DefaultMaxBlockSize = 1 << 20
    29  	DefaultTxVerifyTime = time.Microsecond * 200
    30  	DefaultEvictPeriod  = 12
    31  
    32  	// DefaultMaxHdrSize is the max size of the proto-buf serialized non-body
    33  	// fields. For the estimation detail, check 'TestBlockHeaderLimit' in
    34  	// 'blockchain_test.go.' Caution: Be sure to adjust the value below if the
    35  	// structure of the header is changed.
    36  	DefaultMaxHdrSize = 400
    37  	lastFieldOfBH     = "Sign"
    38  )
    39  
    40  type TxHash = []byte
    41  type AvgTime struct {
    42  	val  atomic.Value
    43  	mavg *MovingAverage
    44  }
    45  
    46  var (
    47  	DefaultVerifierCnt          = int(math.Max(float64(runtime.NumCPU()/2), float64(1)))
    48  	DefaultAvgTimeSize          = 60 * 60 * 24
    49  	AvgTxVerifyTime    *AvgTime = NewAvgTime(DefaultAvgTimeSize)
    50  )
    51  
    52  //MaxAER is maximum value of aergo
    53  var MaxAER *big.Int
    54  
    55  //StakingMinimum is minimum amount for staking
    56  var StakingMinimum *big.Int
    57  
    58  ///NamePrice is default value of creating and updating name
    59  var NamePrice *big.Int
    60  
    61  var lastIndexOfBH int
    62  
    63  func init() {
    64  	MaxAER, _ = new(big.Int).SetString("500000000000000000000000000", 10)
    65  	StakingMinimum, _ = new(big.Int).SetString("10000000000000000000000", 10)
    66  	NamePrice, _ = new(big.Int).SetString("1000000000000000000", 10)
    67  	lastIndexOfBH = getLastIndexOfBH()
    68  }
    69  
    70  // GetStakingMinimum returns the minimum limit of staking.
    71  func GetStakingMinimum() *big.Int {
    72  	return StakingMinimum
    73  }
    74  
    75  func NewAvgTime(sizeMavg int) *AvgTime {
    76  	avgTime := &AvgTime{}
    77  	avgTime.mavg = NewMovingAverage(sizeMavg)
    78  	avgTime.val.Store(time.Duration(0))
    79  	return avgTime
    80  }
    81  
    82  func (avgTime *AvgTime) Get() time.Duration {
    83  	var avg time.Duration
    84  	aopv := avgTime.val.Load()
    85  	if aopv != nil {
    86  		avg = aopv.(time.Duration)
    87  	} else {
    88  		panic("AvgTxSignTime is not set")
    89  	}
    90  	return avg
    91  }
    92  
    93  func (avgTime *AvgTime) UpdateAverage(cur time.Duration) time.Duration {
    94  	newAvg := time.Duration(avgTime.mavg.Add(int64(cur)))
    95  	avgTime.set(newAvg)
    96  
    97  	return newAvg
    98  }
    99  
   100  func (avgTime *AvgTime) set(val time.Duration) {
   101  	avgTime.val.Store(val)
   102  }
   103  
   104  func getLastIndexOfBH() (lastIndex int) {
   105  	v := reflect.ValueOf(BlockHeader{})
   106  
   107  	nField := v.NumField()
   108  	var i int
   109  	for i = 0; i < nField; i++ {
   110  		name := v.Type().Field(i).Name
   111  		if name == lastFieldOfBH {
   112  			lastIndex = i
   113  			break
   114  		}
   115  	}
   116  
   117  	return i
   118  }
   119  
   120  type SystemValue int
   121  
   122  const (
   123  	StakingTotal SystemValue = 0 + iota
   124  	StakingMin
   125  )
   126  
   127  func (s SystemValue) String() string {
   128  	return [...]string{"StakingTotal", "StakingMin"}[s]
   129  }
   130  
   131  // ChainAccessor is an interface for a another actor module to get info of chain
   132  type ChainAccessor interface {
   133  	GetGenesisInfo() *Genesis
   134  	GetConsensusInfo() string
   135  	GetBestBlock() (*Block, error)
   136  	// GetBlock return block of blockHash. It return nil and error if not found block of that hash or there is a problem in db store
   137  	GetBlock(blockHash []byte) (*Block, error)
   138  	// GetHashByNo returns hash of block. It return nil and error if not found block of that number or there is a problem in db store
   139  	GetHashByNo(blockNo BlockNo) ([]byte, error)
   140  	GetChainStats() string
   141  	GetSystemValue(key SystemValue) (*big.Int, error)
   142  
   143  	// GetEnterpriseConfig always return non-nil object if there is no error, but it can return EnterpriseConfig with empty values
   144  	GetEnterpriseConfig(key string) (*EnterpriseConfig, error)
   145  }
   146  
   147  type SyncContext struct {
   148  	Seq uint64
   149  
   150  	PeerID PeerID
   151  
   152  	BestNo   BlockNo
   153  	TargetNo BlockNo //sync target blockno
   154  
   155  	CommonAncestor *Block
   156  
   157  	TotalCnt   uint64
   158  	RemainCnt  uint64
   159  	LastAnchor BlockNo
   160  
   161  	NotifyC chan error
   162  }
   163  
   164  func NewSyncCtx(seq uint64, peerID PeerID, targetNo uint64, bestNo uint64, notifyC chan error) *SyncContext {
   165  	return &SyncContext{Seq: seq, PeerID: peerID, TargetNo: targetNo, BestNo: bestNo, LastAnchor: 0, NotifyC: notifyC}
   166  }
   167  
   168  func (ctx *SyncContext) SetAncestor(ancestor *Block) {
   169  	ctx.CommonAncestor = ancestor
   170  	ctx.TotalCnt = ctx.TargetNo - ctx.CommonAncestor.BlockNo()
   171  	ctx.RemainCnt = ctx.TotalCnt
   172  }
   173  
   174  // NodeInfo is used for actor message to send block info
   175  type BlockInfo struct {
   176  	Hash []byte
   177  	No   BlockNo
   178  }
   179  
   180  func (bi *BlockInfo) Equal(target *BlockInfo) bool {
   181  	if target == nil {
   182  		return false
   183  	}
   184  
   185  	if bi.No == target.No && bytes.Equal(bi.Hash, target.Hash) {
   186  		return true
   187  	} else {
   188  		return false
   189  	}
   190  }
   191  
   192  // BlockNo is the height of a block, which starts from 0 (genesis block).
   193  type BlockNo = uint64
   194  
   195  func Uint64ToBytes(num uint64) []byte {
   196  	buf := make([]byte, 8)
   197  	binary.LittleEndian.PutUint64(buf, num)
   198  	return buf
   199  }
   200  
   201  func BytesToUint64(data []byte) uint64 {
   202  	buf := binary.LittleEndian.Uint64(data)
   203  	return buf
   204  }
   205  
   206  // BlockNoToBytes represents to serialize block no to bytes
   207  func BlockNoToBytes(bn BlockNo) []byte {
   208  	return Uint64ToBytes(bn)
   209  }
   210  
   211  // BlockNoFromBytes represents to deserialize bytes to block no
   212  func BlockNoFromBytes(raw []byte) BlockNo {
   213  	buf := BytesToUint64(raw)
   214  	return BlockNo(buf)
   215  }
   216  
   217  // NewBlock represents to create a block to store transactions.
   218  func NewBlock(prevBlock *Block, blockRoot []byte, receipts *Receipts, txs []*Tx, coinbaseAcc []byte, ts int64) *Block {
   219  	var (
   220  		chainID       []byte
   221  		prevBlockHash []byte
   222  		blockNo       BlockNo
   223  	)
   224  
   225  	if prevBlock != nil {
   226  		prevBlockHash = prevBlock.BlockHash()
   227  		blockNo = prevBlock.Header.BlockNo + 1
   228  		chainID = prevBlock.GetHeader().GetChainID()
   229  	}
   230  
   231  	body := BlockBody{
   232  		Txs: txs,
   233  	}
   234  	header := BlockHeader{
   235  		ChainID:         chainID,
   236  		PrevBlockHash:   prevBlockHash,
   237  		BlockNo:         blockNo,
   238  		Timestamp:       ts,
   239  		BlocksRootHash:  blockRoot,
   240  		CoinbaseAccount: coinbaseAcc,
   241  	}
   242  	block := Block{
   243  		Header: &header,
   244  		Body:   &body,
   245  	}
   246  
   247  	block.Header.TxsRootHash = CalculateTxsRootHash(body.Txs)
   248  	block.Header.ReceiptsRootHash = receipts.MerkleRoot()
   249  
   250  	return &block
   251  }
   252  
   253  // Localtime retrurns a time.Time object, which is coverted from block
   254  // timestamp.
   255  func (block *Block) Localtime() time.Time {
   256  	return time.Unix(0, block.GetHeader().GetTimestamp())
   257  }
   258  
   259  // calculateBlockHash computes sha256 hash of block header.
   260  func (block *Block) calculateBlockHash() []byte {
   261  	digest := sha256.New()
   262  	serializeBH(digest, block.Header)
   263  
   264  	return digest.Sum(nil)
   265  }
   266  
   267  func serializeStruct(w io.Writer, s interface{}, stopIndex int) error {
   268  	v := reflect.Indirect(reflect.ValueOf(s))
   269  
   270  	var i int
   271  	for i = 0; i <= stopIndex; i++ {
   272  		if err := binary.Write(w, binary.LittleEndian, v.Field(i).Interface()); err != nil {
   273  			return err
   274  		}
   275  	}
   276  
   277  	return nil
   278  }
   279  
   280  func serializeBH(w io.Writer, bh *BlockHeader) error {
   281  	return serializeStruct(w, bh, lastIndexOfBH)
   282  }
   283  
   284  func serializeBhForDigest(w io.Writer, bh *BlockHeader) error {
   285  	return serializeStruct(w, bh, lastIndexOfBH-1)
   286  }
   287  
   288  func writeBlockHeaderOld(w io.Writer, bh *BlockHeader) error {
   289  	for _, f := range []interface{}{
   290  		bh.PrevBlockHash,
   291  		bh.BlockNo,
   292  		bh.Timestamp,
   293  		bh.BlocksRootHash,
   294  		bh.TxsRootHash,
   295  		bh.ReceiptsRootHash,
   296  		bh.Confirms,
   297  		bh.PubKey,
   298  		bh.Sign,
   299  	} {
   300  		if err := binary.Write(w, binary.LittleEndian, f); err != nil {
   301  			return err
   302  		}
   303  	}
   304  
   305  	return nil
   306  }
   307  
   308  // BlockHash returns block hash. It returns a calculated value if the hash is nil.
   309  func (block *Block) BlockHash() []byte {
   310  	hash := block.GetHash()
   311  	if len(hash) == 0 {
   312  		block.Hash = block.calculateBlockHash()
   313  	}
   314  
   315  	return block.GetHash()
   316  }
   317  
   318  // BlockID converts block hash ([]byte) to BlockID.
   319  func (block *Block) BlockID() BlockID {
   320  	return ToBlockID(block.BlockHash())
   321  }
   322  
   323  // PrevBlockID converts parent block hash ([]byte) to BlockID.
   324  func (block *Block) PrevBlockID() BlockID {
   325  	return ToBlockID(block.GetHeader().GetPrevBlockHash())
   326  }
   327  
   328  // SetChainID sets id to block.ChainID
   329  func (block *Block) SetChainID(id []byte) {
   330  	block.Header.ChainID = id
   331  }
   332  
   333  // ValidChildOf reports whether block is a varid child of parent.
   334  func (block *Block) ValidChildOf(parent *Block) bool {
   335  	parChainID := parent.GetHeader().GetChainID()
   336  	curChainID := block.GetHeader().GetChainID()
   337  
   338  	// empty chain id case: an older verion of block has no chain id in its
   339  	// block header.
   340  	if len(parChainID) == 0 && len(curChainID) == 0 {
   341  		return true
   342  	}
   343  
   344  	return bytes.Compare(parChainID, curChainID) == 0
   345  }
   346  
   347  // Size returns a block size where the tx size is individually calculated. A
   348  // similar method is used to limit the block size by the block factory.
   349  //
   350  // THE REASON WHY THE BLOCK FACTORY DOESN'T USE THE EXACT SIZE OF A MARSHALED
   351  // BLOCK: The actual size of a marshaled block is larger than this because it
   352  // includes an additional data associated with the marshaling of the
   353  // transations array in the block body. It is ineffective that the (DPoS) block
   354  // factory measures the exact size of the additional probuf data when it
   355  // produces a block. Thus we use the slightly(?) different and less expensive
   356  // estimation of the block size.
   357  func (block *Block) Size() int {
   358  	size := proto.Size(block.GetHeader()) + len(block.GetHash())
   359  	for _, tx := range block.GetBody().GetTxs() {
   360  		size += proto.Size(tx)
   361  	}
   362  	return size
   363  }
   364  
   365  // Confirms returns block.Header.Confirms which indicates how many block is confirmed
   366  // by block.
   367  func (block *Block) Confirms() BlockNo {
   368  	return block.GetHeader().GetConfirms()
   369  }
   370  
   371  // SetConfirms sets block.Header.Confirms to confirms.
   372  func (block *Block) SetConfirms(confirms BlockNo) {
   373  	block.Header.Confirms = confirms
   374  }
   375  
   376  // BlockNo returns the block number of block.
   377  func (block *Block) BlockNo() BlockNo {
   378  	return block.GetHeader().GetBlockNo()
   379  }
   380  
   381  // Sign adds a pubkey and a block signature to block.
   382  func (block *Block) Sign(privKey crypto.PrivKey) error {
   383  	var err error
   384  
   385  	if err = block.setPubKey(privKey.GetPublic()); err != nil {
   386  		return err
   387  	}
   388  
   389  	var msg []byte
   390  	if msg, err = block.Header.bytesForDigest(); err != nil {
   391  		return err
   392  	}
   393  
   394  	var sig []byte
   395  	if sig, err = privKey.Sign(msg); err != nil {
   396  		return err
   397  	}
   398  	block.Header.Sign = sig
   399  
   400  	return nil
   401  }
   402  
   403  func (bh *BlockHeader) bytesForDigest() ([]byte, error) {
   404  	var buf bytes.Buffer
   405  
   406  	if err := serializeBhForDigest(&buf, bh); err != nil {
   407  		return nil, err
   408  	}
   409  
   410  	return buf.Bytes(), nil
   411  }
   412  
   413  // VerifySign verifies the signature of block.
   414  func (block *Block) VerifySign() (valid bool, err error) {
   415  	var pubKey crypto.PubKey
   416  	if pubKey, err = crypto.UnmarshalPublicKey(block.Header.PubKey); err != nil {
   417  		return false, err
   418  	}
   419  
   420  	var msg []byte
   421  	if msg, err = block.Header.bytesForDigest(); err != nil {
   422  		return false, err
   423  	}
   424  
   425  	if valid, err = pubKey.Verify(msg, block.Header.Sign); err != nil {
   426  		return
   427  	}
   428  
   429  	return valid, nil
   430  }
   431  
   432  // BPID returns its Block Producer's ID from block.
   433  func (block *Block) BPID() (id PeerID, err error) {
   434  	var pubKey crypto.PubKey
   435  	if pubKey, err = crypto.UnmarshalPublicKey(block.Header.PubKey); err != nil {
   436  		return PeerID(""), err
   437  	}
   438  
   439  	if id, err = IDFromPublicKey(pubKey); err != nil {
   440  		return PeerID(""), err
   441  	}
   442  
   443  	return
   444  }
   445  
   446  // BpID2Str returns its Block Producer's ID in base64 format.
   447  func (block *Block) BPID2Str() string {
   448  	id, err := block.BPID()
   449  	if err != nil {
   450  		return ""
   451  	}
   452  
   453  	return enc.ToString([]byte(id))
   454  }
   455  
   456  // ID returns the base64 encoded formated ID (hash) of block.
   457  func (block *Block) ID() string {
   458  	hash := block.BlockHash()
   459  	if hash != nil {
   460  		return enc.ToString(hash)
   461  	}
   462  
   463  	return ""
   464  
   465  }
   466  
   467  // PrevID returns the base64 encoded formated ID (hash) of the parent block.
   468  func (block *Block) PrevID() string {
   469  	hash := block.GetHeader().GetPrevBlockHash()
   470  	if hash != nil {
   471  		return enc.ToString(hash)
   472  	}
   473  
   474  	return ""
   475  
   476  }
   477  
   478  // SetPubKey sets block.Header.PubKey to pubkey.
   479  func (block *Block) setPubKey(pubKey crypto.PubKey) error {
   480  	var pk []byte
   481  	var err error
   482  	if pk, err = pubKey.Bytes(); err != nil {
   483  		return err
   484  	}
   485  	block.Header.PubKey = pk
   486  
   487  	return nil
   488  }
   489  
   490  func (block *Block) SetBlocksRootHash(blockRootHash []byte) {
   491  	block.GetHeader().BlocksRootHash = blockRootHash
   492  }
   493  
   494  // GetMetadata generates Metadata object for block
   495  func (block *Block) GetMetadata() *BlockMetadata {
   496  	return &BlockMetadata{
   497  		Hash:    block.BlockHash(),
   498  		Header:  block.GetHeader(),
   499  		Txcount: int32(len(block.GetBody().GetTxs())),
   500  		Size:    int64(proto.Size(block)),
   501  	}
   502  }
   503  
   504  // CalculateTxsRootHash generates merkle tree of transactions and returns root hash.
   505  func CalculateTxsRootHash(txs []*Tx) []byte {
   506  	mes := make([]merkle.MerkleEntry, len(txs))
   507  	for i, tx := range txs {
   508  		mes[i] = tx
   509  	}
   510  	return merkle.CalculateMerkleRoot(mes)
   511  }
   512  
   513  func NewTx() *Tx {
   514  	tx := &Tx{
   515  		Body: &TxBody{
   516  			Nonce: uint64(1),
   517  		},
   518  	}
   519  	return tx
   520  }
   521  
   522  func (tx *Tx) CalculateTxHash() []byte {
   523  	txBody := tx.Body
   524  	digest := sha256.New()
   525  	binary.Write(digest, binary.LittleEndian, txBody.Nonce)
   526  
   527  	digest.Write(txBody.Account)
   528  	digest.Write(txBody.Recipient)
   529  	digest.Write(txBody.Amount)
   530  	digest.Write(txBody.Payload)
   531  	binary.Write(digest, binary.LittleEndian, txBody.GasLimit)
   532  	digest.Write(txBody.GasPrice)
   533  	binary.Write(digest, binary.LittleEndian, txBody.Type)
   534  	digest.Write(txBody.ChainIdHash)
   535  	digest.Write(txBody.Sign)
   536  	return digest.Sum(nil)
   537  }
   538  
   539  func (tx *Tx) NeedNameVerify() bool {
   540  	return tx.HasNameAccount()
   541  }
   542  
   543  func (tx *Tx) HasNameAccount() bool {
   544  	return len(tx.Body.Account) <= NameLength
   545  }
   546  
   547  func (tx *Tx) HasNameRecipient() bool {
   548  	return tx.Body.Recipient != nil && len(tx.Body.Recipient) <= NameLength
   549  }
   550  
   551  func (tx *Tx) Clone() *Tx {
   552  	if tx == nil {
   553  		return nil
   554  	}
   555  	if tx.Body == nil {
   556  		return &Tx{}
   557  	}
   558  	body := &TxBody{
   559  		Nonce:       tx.Body.Nonce,
   560  		Account:     Clone(tx.Body.Account).([]byte),
   561  		Recipient:   Clone(tx.Body.Recipient).([]byte),
   562  		Amount:      Clone(tx.Body.Amount).([]byte),
   563  		Payload:     Clone(tx.Body.Payload).([]byte),
   564  		GasLimit:    tx.Body.GasLimit,
   565  		GasPrice:    Clone(tx.Body.GasPrice).([]byte),
   566  		Type:        tx.Body.Type,
   567  		ChainIdHash: Clone(tx.Body.ChainIdHash).([]byte),
   568  		Sign:        Clone(tx.Body.Sign).([]byte),
   569  	}
   570  	res := &Tx{
   571  		Body: body,
   572  	}
   573  	res.Hash = res.CalculateTxHash()
   574  	return res
   575  }
   576  
   577  func (b *TxBody) GetAmountBigInt() *big.Int {
   578  	return new(big.Int).SetBytes(b.GetAmount())
   579  }
   580  
   581  func (b *TxBody) GetGasPriceBigInt() *big.Int {
   582  	return new(big.Int).SetBytes(b.GetGasPrice())
   583  }
   584  
   585  type MovingAverage struct {
   586  	values []int64
   587  	size   int
   588  	count  int
   589  
   590  	sum        int64
   591  	removedVal int64
   592  	curPos     int
   593  }
   594  
   595  func NewMovingAverage(size int) *MovingAverage {
   596  	return &MovingAverage{
   597  		values:     make([]int64, size),
   598  		size:       size,
   599  		removedVal: 0,
   600  		sum:        0,
   601  		curPos:     -1,
   602  		count:      0,
   603  	}
   604  }
   605  
   606  func (ma *MovingAverage) Add(val int64) int64 {
   607  	ma.curPos = (ma.curPos + 1) % ma.size
   608  	ma.removedVal = ma.values[ma.curPos]
   609  	ma.values[ma.curPos] = val
   610  
   611  	if ma.count != ma.size {
   612  		ma.count++
   613  	}
   614  
   615  	return ma.calculateAvg()
   616  }
   617  
   618  func (ma *MovingAverage) calculateAvg() int64 {
   619  	//values is empty
   620  	if ma.count == 0 {
   621  		return 0
   622  	}
   623  
   624  	ma.sum = ma.sum - ma.removedVal + ma.values[ma.curPos]
   625  
   626  	// Finalize average and return
   627  	avg := ma.sum / int64(ma.count)
   628  	return avg
   629  }