Skip to content

Commit

Permalink
Updated the exchange rate calculation sequence and it runs now, stats…
Browse files Browse the repository at this point in the history
… pending
  • Loading branch information
gameofpointers committed Dec 27, 2024
1 parent a1ef75e commit c3f7cad
Show file tree
Hide file tree
Showing 2 changed files with 198 additions and 42 deletions.
124 changes: 99 additions & 25 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -761,36 +773,39 @@ 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) {
value := etx.Value()
// 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()
Expand All @@ -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 {
Expand All @@ -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)
}
Expand Down
116 changes: 99 additions & 17 deletions core/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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()
Expand All @@ -747,31 +764,28 @@ 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
if etx.To().IsInQuaiLedgerScope() {
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 {
Expand All @@ -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
Expand Down

0 comments on commit c3f7cad

Please sign in to comment.