From c3f7cad3619e2a47db4db957f36f7cb3fe6a492b Mon Sep 17 00:00:00 2001 From: gop Date: Fri, 27 Dec 2024 16:54:16 -0600 Subject: [PATCH] Updated the exchange rate calculation sequence and it runs now, stats pending --- core/state_processor.go | 124 ++++++++++++++++++++++++++++++++-------- core/worker.go | 116 +++++++++++++++++++++++++++++++------ 2 files changed, 198 insertions(+), 42 deletions(-) diff --git a/core/state_processor.go b/core/state_processor.go index 1183272c2..2a6ff807c 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -732,6 +732,7 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty actualConversionAmountInHash := big.NewInt(0) realizedConversionAmountInHash := big.NewInt(0) + var exchangeRate *big.Int if block.NumberU64(common.ZONE_CTX) < params.GoldenAgeForkNumberV3 { for _, etx := range emittedEtxs { // If the etx is conversion @@ -750,8 +751,19 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty etx.SetValue(value) } } + + exchangeRate = parent.ExchangeRate() } else { + // There are 6 steps to the exchange rate calculation + // 1. Convert the amounts using the parent exchange rate + // 2. Using the parent K Quai apply a discount to the converted amount + // 3. Calculate the new exchange rate for this block + // 4. Convert the amounts using this newly computed exchange rate + // 5. Apply the K Quai discount using the new exchange rate + // 6. Apply the quadratic Conversion Flow discount + + ///////// Step 1 ////////// var conversionFlowAmount *big.Int if block.NumberU64(common.ZONE_CTX) == params.GoldenAgeForkNumberV3 { conversionFlowAmount = new(big.Int).Set(params.StartingConversionFlowAmount) @@ -761,7 +773,6 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty } conversionAmountInHash := big.NewInt(0) - for _, etx := range emittedEtxs { // If the etx is conversion if types.IsConversionTx(etx) { @@ -769,28 +780,32 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty // If to is in Qi, convert the value into Qi if etx.To().IsInQiLedgerScope() { value = misc.QuaiToQi(parent, value) - conversionAmountInHash = new(big.Int).Add(conversionAmountInHash, misc.QiToHash(block, value)) + conversionAmountInHash = new(big.Int).Add(conversionAmountInHash, misc.QiToHash(parent, value)) } // If To is in Quai, convert the value into Quai if etx.To().IsInQuaiLedgerScope() { value = misc.QiToQuai(parent, value) - conversionAmountInHash = new(big.Int).Add(conversionAmountInHash, misc.QuaiToHash(block, value)) + conversionAmountInHash = new(big.Int).Add(conversionAmountInHash, misc.QuaiToHash(parent, value)) } } } - // Apply K Quai discount before applying the quadratic discount, conversionAmount = (1-kQuaiDiscount)*conversionAmountInHash - kQuaiDiscount := p.hc.ComputeKQuaiDiscount(block) - rawdb.WriteKQuaiDiscount(batch, block.Hash(), kQuaiDiscount) + // compute and write the conversion flow amount based on the current block + currentBlockConversionFlowAmount := p.hc.ComputeConversionFlowAmount(block, new(big.Int).Set(conversionAmountInHash)) + rawdb.WriteConversionFlowAmount(p.hc.headerDb, block.Hash(), currentBlockConversionFlowAmount) + ///////// Step 2 ///////// + // Apply K Quai discount before applying the quadratic discount, conversionAmount = (1-kQuaiDiscount)*conversionAmountInHash + kQuaiDiscount := p.hc.ComputeKQuaiDiscount(parent) conversionAmountAfterKQuaiDiscount := new(big.Int).Mul(conversionAmountInHash, new(big.Int).Sub(big.NewInt(100), kQuaiDiscount)) - discountedConversionAmount := p.hc.ApplyQuadraticDiscount(conversionAmountAfterKQuaiDiscount, conversionFlowAmount) - discountedConversionAmountInInt, _ := discountedConversionAmount.Int64() + originalEtxValues := make([]*big.Int, len(emittedEtxs)) - newConversionAmount := big.NewInt(0) + for i, etx := range emittedEtxs { + + // store the original etx values + originalEtxValues[i] = new(big.Int).Set(etx.Value()) - for _, etx := range emittedEtxs { // If the etx is conversion if types.IsConversionTx(etx) { value := etx.Value() @@ -799,37 +814,28 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty value = misc.QuaiToQi(parent, value) // Apply the slip to each conversion - value = new(big.Int).Mul(value, big.NewInt(discountedConversionAmountInInt)) + value = new(big.Int).Mul(value, conversionAmountAfterKQuaiDiscount) value = new(big.Int).Div(value, conversionAmountInHash) - - newConversionAmount = new(big.Int).Add(newConversionAmount, misc.QiToHash(block, value)) } // If To is in Quai, convert the value into Quai if etx.To().IsInQuaiLedgerScope() { value = misc.QiToQuai(parent, value) // Apply the slip to each conversion - value = new(big.Int).Mul(value, big.NewInt(discountedConversionAmountInInt)) + value = new(big.Int).Mul(value, conversionAmountAfterKQuaiDiscount) value = new(big.Int).Div(value, conversionAmountInHash) - - newConversionAmount = new(big.Int).Add(newConversionAmount, misc.QuaiToHash(block, value)) } etx.SetValue(value) } } + //////// Step 3 ///////// + minerDifficulty := p.hc.ComputeMinerDifficulty(block) + // save the actual and realized conversion amount actualConversionAmountInHash = new(big.Int).Set(conversionAmountInHash) - realizedConversionAmountInHash = big.NewInt(discountedConversionAmountInInt) - - rawdb.WriteConversionFlowAmount(p.hc.headerDb, block.Hash(), p.hc.ComputeConversionFlowAmount(block, newConversionAmount)) - } + realizedConversionAmountInHash = new(big.Int).Set(conversionAmountAfterKQuaiDiscount) - var exchangeRate *big.Int - if block.NumberU64(common.ZONE_CTX) < params.GoldenAgeForkNumberV3 { - exchangeRate = parent.ExchangeRate() - } else { - minerDifficulty := p.hc.ComputeMinerDifficulty(block) // calculate the token choice set and write it to the disk updatedTokenChoiceSet, err := CalculateTokenChoicesSet(p.hc, block, parent, emittedEtxs, actualConversionAmountInHash, realizedConversionAmountInHash, minerDifficulty) if err != nil { @@ -843,7 +849,75 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty if err != nil { return nil, nil, nil, nil, 0, 0, 0, nil, nil, err } + + //////// Step 4 //////// + newConversionAmountInHash := big.NewInt(0) + for i, etx := range emittedEtxs { + // If the etx is conversion + if types.IsConversionTx(etx) { + // Use the original etx values + value := originalEtxValues[i] + // If to is in Qi, convert the value into Qi + if etx.To().IsInQiLedgerScope() { + value = misc.QuaiToQi(block, value) + newConversionAmountInHash = new(big.Int).Add(newConversionAmountInHash, misc.QiToHash(block, value)) + } + // If To is in Quai, convert the value into Quai + if etx.To().IsInQuaiLedgerScope() { + value = misc.QiToQuai(block, value) + newConversionAmountInHash = new(big.Int).Add(newConversionAmountInHash, misc.QiToHash(block, value)) + } + etx.SetValue(value) + } + } + + //////// Step 5 /////// + newkQuaiDiscount := p.hc.ComputeKQuaiDiscount(block) + newConversionAmountAfterKQuaiDiscount := new(big.Int).Mul(newConversionAmountInHash, new(big.Int).Sub(big.NewInt(100), newkQuaiDiscount)) + for _, etx := range emittedEtxs { + // If the etx is conversion + if types.IsConversionTx(etx) { + value := etx.Value() + // If to is in Qi, convert the value into Qi + if etx.To().IsInQiLedgerScope() { + // Apply the slip to each conversion + value = new(big.Int).Mul(value, newConversionAmountAfterKQuaiDiscount) + value = new(big.Int).Div(value, newConversionAmountInHash) + } + // If To is in Quai, convert the value into Quai + if etx.To().IsInQuaiLedgerScope() { + // Apply the slip to each conversion + value = new(big.Int).Mul(value, newConversionAmountAfterKQuaiDiscount) + value = new(big.Int).Div(value, newConversionAmountInHash) + } + etx.SetValue(value) + } + } + + /////// Step 6 //////// + discountedConversionAmount := p.hc.ApplyQuadraticDiscount(newConversionAmountInHash, conversionFlowAmount) + discountedConversionAmountInInt, _ := discountedConversionAmount.Int64() + for _, etx := range emittedEtxs { + // If the etx is conversion + if types.IsConversionTx(etx) { + value := etx.Value() + // If to is in Qi, convert the value into Qi + if etx.To().IsInQiLedgerScope() { + // Apply the slip to each conversion + value = new(big.Int).Mul(value, big.NewInt(discountedConversionAmountInInt)) + value = new(big.Int).Div(value, newConversionAmountAfterKQuaiDiscount) + } + // If To is in Quai, convert the value into Quai + if etx.To().IsInQuaiLedgerScope() { + // Apply the slip to each conversion + value = new(big.Int).Mul(value, big.NewInt(discountedConversionAmountInInt)) + value = new(big.Int).Div(value, newConversionAmountAfterKQuaiDiscount) + } + etx.SetValue(value) + } + } } + if block.ExchangeRate().Cmp(exchangeRate) != 0 { return nil, nil, nil, nil, 0, 0, 0, nil, nil, fmt.Errorf("invalid exchange rate used (remote: %d local: %d)", block.ExchangeRate(), exchangeRate) } diff --git a/core/worker.go b/core/worker.go index 556a7fa96..ec5b3772e 100644 --- a/core/worker.go +++ b/core/worker.go @@ -678,6 +678,7 @@ func (w *worker) GeneratePendingHeader(block *types.WorkObject, fill bool, txs t var exchangeRate *big.Int if w.hc.IsGenesisHash(block.Hash()) { exchangeRate = params.ExchangeRate + work.wo.Header().SetExchangeRate(exchangeRate) } else { actualConversionAmountInHash := big.NewInt(0) @@ -701,8 +702,21 @@ func (w *worker) GeneratePendingHeader(block *types.WorkObject, fill bool, txs t etx.SetValue(value) } } + + exchangeRate = block.ExchangeRate() + work.wo.Header().SetExchangeRate(exchangeRate) + } else { + // There are 6 steps to the exchange rate calculation + // 1. Convert the amounts using the parent exchange rate + // 2. Using the parent K Quai apply a discount to the converted amount + // 3. Calculate the new exchange rate for this block + // 4. Convert the amounts using this newly computed exchange rate + // 5. Apply the K Quai discount using the new exchange rate + // 6. Apply the quadratic Conversion Flow discount + + ///////// Step 1 ////////// var conversionFlowAmount *big.Int if work.wo.NumberU64(common.ZONE_CTX) == params.GoldenAgeForkNumberV3 { conversionFlowAmount = new(big.Int).Set(params.StartingConversionFlowAmount) @@ -712,7 +726,6 @@ func (w *worker) GeneratePendingHeader(block *types.WorkObject, fill bool, txs t } conversionAmountInHash := big.NewInt(0) - // Calculate the total conversion amount in hash for _, etx := range work.etxs { // If the etx is conversion @@ -721,24 +734,28 @@ func (w *worker) GeneratePendingHeader(block *types.WorkObject, fill bool, txs t // If to is in Qi, convert the value into Qi if etx.To().IsInQiLedgerScope() { value = misc.QuaiToQi(block, value) - conversionAmountInHash = new(big.Int).Add(conversionAmountInHash, misc.QiToHash(work.wo, value)) + conversionAmountInHash = new(big.Int).Add(conversionAmountInHash, misc.QiToHash(block, value)) } // If To is in Quai, convert the value into Quai if etx.To().IsInQuaiLedgerScope() { value = misc.QiToQuai(block, value) - conversionAmountInHash = new(big.Int).Add(conversionAmountInHash, misc.QuaiToHash(work.wo, value)) + conversionAmountInHash = new(big.Int).Add(conversionAmountInHash, misc.QuaiToHash(block, value)) } } } + ///////// Step 2 ///////// // Apply K Quai discount before applying the quadratic discount, conversionAmount = (1-kQuaiDiscount)*conversionAmountInHash - kQuaiDiscount := w.hc.ComputeKQuaiDiscount(work.wo) + kQuaiDiscount := w.hc.ComputeKQuaiDiscount(block) conversionAmountAfterKQuaiDiscount := new(big.Int).Mul(conversionAmountInHash, new(big.Int).Sub(big.NewInt(100), kQuaiDiscount)) - discountedConversionAmount := w.hc.ApplyQuadraticDiscount(conversionAmountAfterKQuaiDiscount, conversionFlowAmount) - discountedConversionAmountInInt, _ := discountedConversionAmount.Int64() + originalEtxValues := make([]*big.Int, len(work.etxs)) + + for i, etx := range work.etxs { + + // store the original etx values + originalEtxValues[i] = new(big.Int).Set(etx.Value()) - for _, etx := range work.etxs { // If the etx is conversion if types.IsConversionTx(etx) { value := etx.Value() @@ -747,7 +764,7 @@ func (w *worker) GeneratePendingHeader(block *types.WorkObject, fill bool, txs t value = misc.QuaiToQi(block, value) // Apply the slip to each conversion - value = new(big.Int).Mul(value, big.NewInt(discountedConversionAmountInInt)) + value = new(big.Int).Mul(value, conversionAmountAfterKQuaiDiscount) value = new(big.Int).Div(value, conversionAmountInHash) } // If To is in Quai, convert the value into Quai @@ -755,23 +772,20 @@ func (w *worker) GeneratePendingHeader(block *types.WorkObject, fill bool, txs t value = misc.QiToQuai(block, value) // Apply the slip to each conversion - value = new(big.Int).Mul(value, big.NewInt(discountedConversionAmountInInt)) + value = new(big.Int).Mul(value, conversionAmountAfterKQuaiDiscount) value = new(big.Int).Div(value, conversionAmountInHash) } etx.SetValue(value) } } + //////// Step 3 ///////// + minerDifficulty := w.hc.ComputeMinerDifficulty(work.wo) + // save the actual and realized conversion amount actualConversionAmountInHash = new(big.Int).Set(conversionAmountInHash) - realizedConversionAmountInHash = big.NewInt(discountedConversionAmountInInt) - } + realizedConversionAmountInHash = new(big.Int).Set(conversionAmountAfterKQuaiDiscount) - // Until the goldenage fork number 3 is reached, the exchange rate remains unchanged - if work.wo.NumberU64(common.ZONE_CTX) < params.GoldenAgeForkNumberV3 { - exchangeRate = block.ExchangeRate() - } else { - minerDifficulty := w.hc.ComputeMinerDifficulty(work.wo) // convert map to a slice updatedTokenChoiceSet, err := CalculateTokenChoicesSet(w.hc, work.wo, block, work.etxs, actualConversionAmountInHash, realizedConversionAmountInHash, minerDifficulty) if err != nil { @@ -781,9 +795,77 @@ func (w *worker) GeneratePendingHeader(block *types.WorkObject, fill bool, txs t if err != nil { return nil, err } + // set the calculated exchange rate + work.wo.Header().SetExchangeRate(exchangeRate) + + //////// Step 4 //////// + newConversionAmountInHash := big.NewInt(0) + for i, etx := range work.etxs { + // If the etx is conversion + if types.IsConversionTx(etx) { + // Use the original etx values + value := originalEtxValues[i] + // If to is in Qi, convert the value into Qi + if etx.To().IsInQiLedgerScope() { + value = misc.QuaiToQi(work.wo, value) + newConversionAmountInHash = new(big.Int).Add(newConversionAmountInHash, misc.QiToHash(work.wo, value)) + } + // If To is in Quai, convert the value into Quai + if etx.To().IsInQuaiLedgerScope() { + value = misc.QiToQuai(work.wo, value) + newConversionAmountInHash = new(big.Int).Add(newConversionAmountInHash, misc.QiToHash(work.wo, value)) + } + etx.SetValue(value) + } + } + + //////// Step 5 /////// + newkQuaiDiscount := w.hc.ComputeKQuaiDiscount(work.wo) + newConversionAmountAfterKQuaiDiscount := new(big.Int).Mul(newConversionAmountInHash, new(big.Int).Sub(big.NewInt(100), newkQuaiDiscount)) + for _, etx := range work.etxs { + // If the etx is conversion + if types.IsConversionTx(etx) { + value := etx.Value() + // If to is in Qi, convert the value into Qi + if etx.To().IsInQiLedgerScope() { + // Apply the slip to each conversion + value = new(big.Int).Mul(value, newConversionAmountAfterKQuaiDiscount) + value = new(big.Int).Div(value, newConversionAmountInHash) + } + // If To is in Quai, convert the value into Quai + if etx.To().IsInQuaiLedgerScope() { + // Apply the slip to each conversion + value = new(big.Int).Mul(value, newConversionAmountAfterKQuaiDiscount) + value = new(big.Int).Div(value, newConversionAmountInHash) + } + etx.SetValue(value) + } + } + + /////// Step 6 //////// + discountedConversionAmount := w.hc.ApplyQuadraticDiscount(newConversionAmountInHash, conversionFlowAmount) + discountedConversionAmountInInt, _ := discountedConversionAmount.Int64() + for _, etx := range work.etxs { + // If the etx is conversion + if types.IsConversionTx(etx) { + value := etx.Value() + // If to is in Qi, convert the value into Qi + if etx.To().IsInQiLedgerScope() { + // Apply the slip to each conversion + value = new(big.Int).Mul(value, big.NewInt(discountedConversionAmountInInt)) + value = new(big.Int).Div(value, newConversionAmountAfterKQuaiDiscount) + } + // If To is in Quai, convert the value into Quai + if etx.To().IsInQuaiLedgerScope() { + // Apply the slip to each conversion + value = new(big.Int).Mul(value, big.NewInt(discountedConversionAmountInInt)) + value = new(big.Int).Div(value, newConversionAmountAfterKQuaiDiscount) + } + etx.SetValue(value) + } + } } } - work.wo.Header().SetExchangeRate(exchangeRate) } // Need a variable to calculate the total hash value that is being converted