Skip to content

Commit

Permalink
Added exchageRate, quaiToQi and qiToQuai in header
Browse files Browse the repository at this point in the history
  • Loading branch information
kiltsonfire authored and gameofpointers committed Oct 1, 2024
1 parent 33c4789 commit e04794d
Show file tree
Hide file tree
Showing 12 changed files with 187 additions and 7 deletions.
5 changes: 5 additions & 0 deletions consensus/misc/rewards.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ func CalculateQiReward(header *types.WorkObjectHeader) *big.Int {
return big.NewInt(1000)
}

// CalculateExchangeRate based on the quai to qi and qi to quai exchange rates
func CalculateExchangeRate(quaiToQi *big.Int, qiToQuai *big.Int) *big.Int {
return new(big.Int).Div(quaiToQi, qiToQuai)
}

// FindMinDenominations finds the minimum number of denominations to make up the reward
func FindMinDenominations(reward *big.Int) map[uint8]uint64 {
// Store the count of each denomination used (map denomination to count)
Expand Down
4 changes: 4 additions & 0 deletions core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,10 @@ func (g *Genesis) ToBlock(startingExpansionNumber uint64) *types.WorkObject {
wo.Header().SetStateUsed(0)
wo.Header().SetEtxSetRoot(types.EmptyRootHash)
wo.Header().SetSecondaryCoinbase(common.Zero)
wo.Header().SetExchangeRate(params.ExchangeRate)
wo.Header().SetQuaiToQi(params.QuaiToQiConversionBase)
wo.Header().SetQiToQuai(params.QiToQuaiConversionBase)

if g.GasLimit == 0 {
wo.Header().SetGasLimit(params.GenesisGasLimit)
}
Expand Down
5 changes: 4 additions & 1 deletion core/slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ func (sl *Slice) asyncPendingHeaderLoop() {
case asyncPh := <-sl.asyncPhCh:
sl.hc.headermu.Lock()
bestPh := sl.ReadBestPh()
if bestPh.ParentHash(common.ZONE_CTX) == asyncPh.ParentHash(common.ZONE_CTX) {
if asyncPh != nil && bestPh != nil && bestPh.ParentHash(common.ZONE_CTX) == asyncPh.ParentHash(common.ZONE_CTX) {
combinedPendingHeader := sl.combinePendingHeader(asyncPh, bestPh, common.ZONE_CTX, true)
sl.SetBestPh(combinedPendingHeader)
}
Expand Down Expand Up @@ -898,6 +898,9 @@ func (sl *Slice) combinePendingHeader(header *types.WorkObject, slPendingHeader
combinedPendingHeader.Header().SetExpansionNumber(header.ExpansionNumber())
combinedPendingHeader.Header().SetEtxEligibleSlices(header.EtxEligibleSlices())
combinedPendingHeader.Header().SetInterlinkRootHash(header.InterlinkRootHash())
combinedPendingHeader.Header().SetExchangeRate(header.ExchangeRate())
combinedPendingHeader.Header().SetQiToQuai(header.QiToQuai())
combinedPendingHeader.Header().SetQuaiToQi(header.QuaiToQi())
}

if inSlice {
Expand Down
57 changes: 57 additions & 0 deletions core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ type Header struct {
stateLimit uint64 `json:"stateLimit" gencodec:"required"`
stateUsed uint64 `json:"stateUsed" gencodec:"required"`
secondaryCoinbase common.Address `json:secondaryCoinbase gencodec:"required"`
exchangeRate *big.Int `json:"exchangeRate" gencodec:"required"`
quaiToQi *big.Int `json:"quaiToQi" gencodec:"required"`
qiToQuai *big.Int `json:"qiToQuai" gencodec:"required"`

// caches
hash atomic.Value
Expand Down Expand Up @@ -150,6 +153,9 @@ func EmptyHeader() *Header {
h.primeTerminusHash = EmptyRootHash
h.interlinkRootHash = EmptyRootHash
h.secondaryCoinbase = common.Address{}
h.exchangeRate = big.NewInt(0)
h.quaiToQi = big.NewInt(0)
h.qiToQuai = big.NewInt(0)

for i := 0; i < common.HierarchyDepth; i++ {
h.manifestHash[i] = EmptyRootHash
Expand Down Expand Up @@ -219,6 +225,9 @@ func (h *Header) ProtoEncode() (*ProtoHeader, error) {
efficiencyScore := uint64(h.EfficiencyScore())
thresholdCount := uint64(h.ThresholdCount())
expansionNumber := uint64(h.ExpansionNumber())
exchangeRate := h.exchangeRate.Bytes()
quaiToQi := h.quaiToQi.Bytes()
qiToQuai := h.qiToQuai.Bytes()

protoHeader := &ProtoHeader{
UncleHash: &uncleHash,
Expand All @@ -244,6 +253,9 @@ func (h *Header) ProtoEncode() (*ProtoHeader, error) {
StateLimit: &stateLimit,
StateUsed: &stateUsed,
Extra: h.Extra(),
ExchangeRate: exchangeRate,
QuaiToQi: quaiToQi,
QiToQuai: qiToQuai,
}

for i := 0; i < common.HierarchyDepth; i++ {
Expand Down Expand Up @@ -342,6 +354,15 @@ func (h *Header) ProtoDecode(protoHeader *ProtoHeader, location common.Location)
if protoHeader.SecondaryCoinbase == nil {
return errors.New("missing required field 'secondaryCoinbase' in Header")
}
if protoHeader.ExchangeRate == nil {
return errors.New("missing required field 'ExchangeRate' in Header")
}
if protoHeader.QuaiToQi == nil {
return errors.New("missing required field 'QuaiToQi' in Header")
}
if protoHeader.QiToQuai == nil {
return errors.New("missing required field 'QiToQuai' in Header")
}

// Initialize the array fields before setting
h.parentHash = make([]common.Hash, common.HierarchyDepth-1)
Expand Down Expand Up @@ -385,6 +406,9 @@ func (h *Header) ProtoDecode(protoHeader *ProtoHeader, location common.Location)
h.SetExpansionNumber(uint8(protoHeader.GetExpansionNumber()))
h.SetEtxEligibleSlices(common.BytesToHash(protoHeader.GetEtxEligibleSlices().GetValue()))
h.SetSecondaryCoinbase(common.BytesToAddress(protoHeader.GetSecondaryCoinbase(), location))
h.SetExchangeRate(new(big.Int).SetBytes(protoHeader.GetExchangeRate()))
h.SetQuaiToQi(new(big.Int).SetBytes(protoHeader.GetQuaiToQi()))
h.SetQiToQuai(new(big.Int).SetBytes(protoHeader.GetQiToQuai()))

return nil
}
Expand Down Expand Up @@ -424,6 +448,9 @@ func (h *Header) RPCMarshalHeader() map[string]interface{} {
"stateLimit": hexutil.Uint64(h.StateLimit()),
"stateUsed": hexutil.Uint64(h.StateUsed()),
"secondaryCoinbase": h.SecondaryCoinbase().Hex(),
"exchangeRate": (*hexutil.Big)(h.ExchangeRate()),
"quaiToQi": (*hexutil.Big)(h.QuaiToQi()),
"qiToQuai": (*hexutil.Big)(h.QiToQuai()),
}

number := make([]*hexutil.Big, common.HierarchyDepth-1)
Expand Down Expand Up @@ -536,6 +563,9 @@ func (h *Header) InterlinkRootHash() common.Hash { return h.interlinkRootHash }
func (h *Header) SecondaryCoinbase() common.Address {
return h.secondaryCoinbase
}
func (h *Header) ExchangeRate() *big.Int { return h.exchangeRate }
func (h *Header) QuaiToQi() *big.Int { return h.quaiToQi }
func (h *Header) QiToQuai() *big.Int { return h.qiToQuai }

func (h *Header) SetParentHash(val common.Hash, nodeCtx int) {
h.hash = atomic.Value{} // clear hash cache
Expand Down Expand Up @@ -688,6 +718,24 @@ func (h *Header) SetSecondaryCoinbase(val common.Address) {
h.secondaryCoinbase = val
}

func (h *Header) SetExchangeRate(val *big.Int) {
h.hash = atomic.Value{}
h.sealHash = atomic.Value{}
h.exchangeRate = new(big.Int).Set(val)
}

func (h *Header) SetQuaiToQi(val *big.Int) {
h.hash = atomic.Value{}
h.sealHash = atomic.Value{}
h.quaiToQi = new(big.Int).Set(val)
}

func (h *Header) SetQiToQuai(val *big.Int) {
h.hash = atomic.Value{}
h.sealHash = atomic.Value{}
h.qiToQuai = new(big.Int).Set(val)
}

// Array accessors
func (h *Header) ParentHashArray() []common.Hash { return h.parentHash }
func (h *Header) ManifestHashArray() []common.Hash { return h.manifestHash }
Expand Down Expand Up @@ -716,6 +764,9 @@ func (h *Header) SealEncode() *ProtoHeader {
gasUsed := h.GasUsed()
stateLimit := h.StateLimit()
stateUsed := h.StateUsed()
exchangeRate := h.exchangeRate.Bytes()
quaiToQi := h.quaiToQi.Bytes()
qiToQuai := h.qiToQuai.Bytes()

protoSealData := &ProtoHeader{
UncleHash: &uncleHash,
Expand All @@ -741,6 +792,9 @@ func (h *Header) SealEncode() *ProtoHeader {
ExpansionNumber: &expansionNumber,
Extra: h.Extra(),
SecondaryCoinbase: h.SecondaryCoinbase().Bytes(),
ExchangeRate: exchangeRate,
QuaiToQi: quaiToQi,
QiToQuai: qiToQuai,
}

for i := 0; i < common.HierarchyDepth; i++ {
Expand Down Expand Up @@ -925,6 +979,9 @@ func CopyHeader(h *Header) *Header {
cpy.SetBaseFee(h.BaseFee())
cpy.SetStateLimit(h.StateLimit())
cpy.SetStateUsed(h.StateUsed())
cpy.SetExchangeRate(h.ExchangeRate())
cpy.SetQuaiToQi(h.QuaiToQi())
cpy.SetQiToQuai(h.QiToQuai())
return &cpy
}

Expand Down
21 changes: 21 additions & 0 deletions core/types/gen_header_json.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 37 additions & 3 deletions core/types/proto_block.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions core/types/proto_block.proto
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ message ProtoHeader {
optional uint64 state_used = 31;
optional bytes quai_state_size = 32;
optional bytes secondary_coinbase = 33;
optional bytes exchange_rate = 34;
optional bytes quai_to_qi = 35;
optional bytes qi_to_quai = 36;
}

message ProtoTransaction {
Expand Down
12 changes: 12 additions & 0 deletions core/types/wo.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,18 @@ func (wo *WorkObject) InterlinkHashes() common.Hashes {
return wo.Body().InterlinkHashes()
}

func (wo *WorkObject) ExchangeRate() *big.Int {
return wo.Header().ExchangeRate()
}

func (wo *WorkObject) QuaiToQi() *big.Int {
return wo.Header().QuaiToQi()
}

func (wo *WorkObject) QiToQuai() *big.Int {
return wo.Header().QiToQuai()
}

func (wo *WorkObject) QiTransactions() []*Transaction {
qiTxs := make([]*Transaction, 0)
for _, t := range wo.Transactions() {
Expand Down
39 changes: 39 additions & 0 deletions core/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -1478,6 +1478,45 @@ func (w *worker) prepareWork(genParams *generateParams, wo *types.WorkObject) (*
newWo.Header().SetInterlinkRootHash(interlinkRootHash)
}

// Calculate the new Qi/Quai exchange rate
if nodeCtx == common.PRIME_CTX {
var subRollup types.Transactions
rollup, exists := w.hc.subRollupCache.Peek(parent.Hash())
if exists && rollup != nil {
subRollup = rollup
w.logger.WithFields(log.Fields{
"Hash": parent.Hash(),
"len": len(subRollup),
}).Debug("Found the rollup in cache")
} else {
subRollup, err = w.hc.CollectSubRollup(parent)
if err != nil {
return nil, err
}
w.hc.subRollupCache.Add(parent.Hash(), subRollup)
}
qiToQuai := new(big.Int).Set(common.Big0)
quaiToQi := new(big.Int).Set(common.Big0)
for _, tx := range subRollup {
if types.IsCoinBaseTx(tx) {
if tx.ETXSender().IsInQiLedgerScope() {
qiToQuai = new(big.Int).Add(qiToQuai, tx.Value())
} else if tx.ETXSender().IsInQuaiLedgerScope() {
quaiToQi = new(big.Int).Add(quaiToQi, tx.Value())
}
} else if types.IsConversionTx(tx) {
if tx.To().IsInQiLedgerScope() {
quaiToQi = new(big.Int).Add(quaiToQi, tx.Value())
} else if tx.To().IsInQuaiLedgerScope() {
qiToQuai = new(big.Int).Add(qiToQuai, tx.Value())
}
}
}
newWo.Header().SetQiToQuai(qiToQuai)
newWo.Header().SetQuaiToQi(quaiToQi)
newWo.Header().SetExchangeRate(params.ExchangeRate)
}

// Only zone should calculate state
if nodeCtx == common.ZONE_CTX && w.hc.ProcessingState() {
newWo.Header().SetExtra(w.extra)
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ require (

require (
github.com/DataDog/zstd v1.4.5 // indirect
github.com/Jorropo/jsync v1.0.1 // indirect
github.com/benbjohnson/clock v1.3.5 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
Expand Down
Loading

0 comments on commit e04794d

Please sign in to comment.