github.com/electroneum/electroneum-sc@v0.0.0-20230105223411-3bc1d078281e/consensus/istanbul/backend/emission.go (about)

     1  // Copyright 2022 Electroneum Ltd
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package backend
    18  
    19  import (
    20  	"encoding/json"
    21  	"math/big"
    22  
    23  	"github.com/electroneum/electroneum-sc/common"
    24  	"github.com/electroneum/electroneum-sc/ethdb"
    25  )
    26  
    27  const (
    28  	dbKeyEmissionPrefix = "istanbul-emission"
    29  )
    30  
    31  // Emission is the state of ETN circulating supply at given point in time
    32  type Emission struct {
    33  	Number            uint64
    34  	Hash              common.Hash
    35  	CirculatingSupply *big.Int
    36  }
    37  
    38  func newEmission(blockNumber uint64, hash common.Hash, circulatingSupply *big.Int) *Emission {
    39  	if circulatingSupply == nil {
    40  		circulatingSupply = big.NewInt(0)
    41  	}
    42  
    43  	emission := &Emission{
    44  		Number:            blockNumber,
    45  		Hash:              hash,
    46  		CirculatingSupply: circulatingSupply,
    47  	}
    48  	return emission
    49  }
    50  
    51  // loadEmission loads an existing emission snapshot from the database.
    52  func loadEmission(hash common.Hash, db ethdb.Database) (*Emission, error) {
    53  	blob, err := db.Get(append([]byte(dbKeyEmissionPrefix), hash[:]...))
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  	emission := new(Emission)
    58  	if err := json.Unmarshal(blob, emission); err != nil {
    59  		return nil, err
    60  	}
    61  
    62  	return emission, nil
    63  }
    64  
    65  // store inserts the emission snapshot into the database.
    66  func (e *Emission) store(db ethdb.Database) error {
    67  	blob, err := json.Marshal(e)
    68  	if err != nil {
    69  		return err
    70  	}
    71  	return db.Put(append([]byte(dbKeyEmissionPrefix), e.Hash[:]...), blob)
    72  }
    73  
    74  // copy creates a deep copy of the emission snapshot
    75  func (e *Emission) copy() *Emission {
    76  	cpy := &Emission{
    77  		Number:            e.Number,
    78  		Hash:              e.Hash,
    79  		CirculatingSupply: e.CirculatingSupply,
    80  	}
    81  
    82  	return cpy
    83  }
    84  
    85  type emissionJSON struct {
    86  	Number            uint64      `json:"number"`
    87  	Hash              common.Hash `json:"hash"`
    88  	CirculatingSupply *big.Int    `json:"circulatingsupply"`
    89  }
    90  
    91  func (e *Emission) toJSONStruct() *emissionJSON {
    92  	return &emissionJSON{
    93  		Number:            e.Number,
    94  		Hash:              e.Hash,
    95  		CirculatingSupply: e.CirculatingSupply,
    96  	}
    97  }
    98  
    99  // Unmarshal from a json byte array
   100  func (e *Emission) UnmarshalJSON(b []byte) error {
   101  	var j emissionJSON
   102  	if err := json.Unmarshal(b, &j); err != nil {
   103  		return err
   104  	}
   105  
   106  	e.Number = j.Number
   107  	e.Hash = j.Hash
   108  	e.CirculatingSupply = j.CirculatingSupply
   109  
   110  	return nil
   111  }
   112  
   113  // Marshal to a json byte array
   114  func (e *Emission) MarshalJSON() ([]byte, error) {
   115  	j := e.toJSONStruct()
   116  	return json.Marshal(j)
   117  }