Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversion prime Initial header changes #2174

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading