Archway Core Formulas Refinement

Archway Core Formulas Refinement
1)contractfeerewards = (TxFees * TxFeeRebateRatio) * (ContractTxGasUsed / TxGasUsed)

Optimization:
Dynamic adjustment of TxFeeRebateRatio.

Parameter Tuning:
The ratio could be increased during times of low network congestion to incentivize dApp development or decreased during high congestion to prioritize network stability.
During periods of low network congestion, increasing the TxFeeRebateRatio can serve as an incentive for developers to build and deploy decentralized applications (dApps) on the network. A higher rebate ratio means that developers will receive a larger portion of transaction fees, potentially making it more attractive to develop and maintain dApps on the network.
On the other hand, when network congestion levels rise, decreasing the TxFeeRebateRatio can help to alleviate congestion and maintain network stability. By reducing the portion of fees rebated to developers, validators can prioritize transaction processing and ensure that critical network functions remain operational. This adjustment can help prevent network overload and ensure that essential transactions, such as transfers and block confirmations, continue to be processed efficiently.
In addition to balancing network congestion and incentivizing dApp development, dynamic adjustment of the TxFeeRebateRatio can also contribute to fair compensation for validators. By adjusting the rebate ratio based on network conditions, validators can ensure that their rewards are commensurate with their contributions to network stability and security. This dynamic compensation mechanism can help maintain a healthy and engaged validator community, which is essential for the long-term sustainability of the network.

2)Inflationary Rewards
contractinflationrewards = (MintedTokens * InflationRewardsRatio) * (ContractTotalGasUsed / BlockGasLimit)

Optimization:
InflationRewardsRatio could be adjusted regularly based on network metrics.
This could involve an automated system that adjusts the ratio based on factors like total number of transactions, average gas usage, or overall network growth rate.

Parameter Tuning:
By increasing the InflationRewardsRatio during periods of high network growth, the system incentivizes more Dapps to join the network and participate in its activities. This increased Dapps base leads to a larger pool of potential validators and transaction fees, potentially boosting overall chain revenue.

3)Transaction Fees
MinimumTxFee = (MinConsensusFee * TxGasLimit) + Σ[flatfee(ContractAddress_msg)] for each msg

Optimization:
Implementing dynamic adjustment of MinConsensusFee based on network load.

Parameter Tuning:
MinConsensusFee can be increased during peak times to discourage spam transactions and lowered during off-peak times to encourage network usage.
Dynamically adjusting MinConsensusFee based on network load and congestion can optimize transaction throughput and maintain network health.

4)Minimum Consensus Fee
MinConsensusFee = InflationBlockRewards / (BlockGasLimit * (1 - TxFeeRebateRatio))

Adjusting InflationBlockRewards based on the current inflation rate, overall network value, and transaction volume.
Periodic review and adjustment (e.g., every hour or daily) of this parameter could help maintain a balance between ensuring transaction affordability and controlling inflation.
This analysis also aligns with the Inflationary Rewards tuning in 2) point.

                                                **Metric Calculations**

GetNetworkCongestionMetric
This function measure network congestion based on the number of transactions in the mempool, block size and time taken for transactions to be included in a block.

func (k Keeper) GetNetworkCongestionMetric(ctx sdk.Context) float64 {
//granular metric - the number of pending transactions
pendingTxCount := k.GetPendingTxCount(ctx)

// Calculate congestion metric using the granular metric
congestionMetric := float64(pendingTxCount) / float64(k.GetMaxMempoolSize(ctx))
return congestionMetric

}

func (k Keeper) GetNetworkCongestionMetric(ctx sdk.Context) float64 {
// Calculate average transaction lifetime in the mempool
avgTxlifetime := calculateAverageTxlifetime(k.GetMempool(ctx))

// Use average transaction lifetime as a factor in the congestion metric
congestionMetric := avgTxlifetime * k.GetPendingTxCount(ctx) / float64(k.GetMaxMempoolSize(ctx))
return congestionMetric

}

func calculateAverageTxlifetime(mempool Mempool) float64 {
// Initialize variables to track total lifetime and number of transactions
totalTxlifetime := 0.0
numTx := 0

// Iterate through transactions in the mempool
for _, tx := range mempool.Txs {
    // Calculate the transaction lifetime for the current transaction
    txLifetime := tx.CreationTime.Sub(time.Now())

    // Update the total transaction lifetime and number of transactions
    totalTxlifetime += txLifetime.Seconds()
    numTx++
}

// Calculate the average transaction lifetime
avgTxlifetime := totalTxlifetime / float64(numTx)

return avgTxlifetime

}

func (k Keeper) GetNetworkCongestionMetric(ctx sdk.Context) float64 {
// Calculate a dynamic congestion threshold based on recent network activity
dynamicThreshold := calculateDynamicThreshold(k.GetRecentTxHistory(ctx))

// Use the dynamic threshold in the congestion metric calculation
congestionMetric := k.GetPendingTxCount(ctx) / float64(dynamicThreshold)
return congestionMetric

}

func calculateDynamicThreshold(txHistory Transaction) float64 {
// Calculate the average transaction arrival rate over the recent history
averageTxArrivalRate := calculateAverageTxArrivalRate(txHistory)

// Calculate the target mempool occupancy based on the average arrival rate
targetMempoolOccupancy := calculateTargetMempoolOccupancy(averageTxArrivalRate)

// Calculate the dynamic threshold based on the target occupancy and maximum mempool size
dynamicThreshold := targetMempoolOccupancy * k.GetMaxMempoolSize(ctx)
return dynamicThreshold

}

func calculateTargetMempoolOccupancy(averageTxArrivalRate float64, networkLoadMetric float64) float64 {
// Define a base safety margin
baseSafetyMargin := 0.2

// Calculate a dynamic safety margin based on transaction arrival rate
dynamicSafetyMargin := 0.1 * (averageTxArrivalRate - targetTxProcessingRate) / targetTxProcessingRate

// Apply the combined safety margin
safetyMargin := baseSafetyMargin + dynamicSafetyMargin

// Calculate the target mempool occupancy
targetMempoolSize := targetTxProcessingRate * avgTxSize * float64(time.Second) * networkLoadMetric
targetMempoolOccupancy := targetMempoolSize / float64(k.GetMaxMempoolSize(ctx))
targetMempoolOccupancy = (1.0 - safetyMargin) * targetMempoolOccupancy

return targetMempoolOccupancy

}
calculateAverageTxArrivalRate: This function analyzes the timestamps of recent transactions to determine the average number of transactions arriving per unit of time.

calculateAverageTxlifetime: This function takes a Mempool object as input and calculates the average transaction lifetime by iterating through the transactions in the mempool. For each transaction, it calculates the transaction lifetime by subtracting the current time from the transaction’s creation time. It then adds the transaction lifetime to a running total and increments a counter for the number of transactions. Finally, it divides the total transaction lifetime by the number of transactions to get the average transaction lifetime.

calculateTargetMempoolOccupancy: This function determines the target mempool occupancy by multiplying the target transaction processing rate by the average transaction size and the network load metric. The result is then divided by the maximum mempool size and multiplied by (1 - safety margin) to apply the combined safety margin. This ensures that the target mempool occupancy is adjusted based on both the network load and the transaction arrival rate. If the arrival rate is higher than the target rate, the safety margin is increased to prevent excessive mempool growth. Conversely, if the arrival rate is lower than the target rate, the safety margin is decreased to allow for more transactions to be held in the mempool.

calculateDynamicThreshold: This function multiplies the target mempool occupancy by the maximum mempool size to determine the dynamic threshold. This ensures that the threshold remains within the bounds of the mempool’s capacity.

Measuring Congestion Using Pending Transactions:

The function GetNetworkCongestionMetric, directly utilizes the number of pending transactions in the mempool (pendingTxCount) as a measure of network congestion. This approach provides a simple and immediate indication of the network’s workload. A higher number of pending transactions suggests that the network is processing transactions more slowly than they are being submitted, leading to congestion.

Measuring Congestion Using Transaction Lifetime:

The function, GetNetworkCongestionMetric, measures the average transaction lifetime in the mempool (avgTxlifetime) and incorporates it into the congestion metric. Transaction lifetime represents the time a transaction spends in the mempool before being included in a block. A longer transaction lifetime indicates that transactions are taking longer to be processed and confirmed, suggesting network congestion.

Measuring Congestion Using Dynamic Threshold:

The function, GetNetworkCongestionMetric, employs a dynamic congestion threshold (dynamicThreshold) based on recent network activity. This approach adapts the congestion metric to the network’s current state and avoids relying on fixed thresholds that may not accurately reflect real-time congestion levels.

Calculating Dynamic Threshold:

The calculateDynamicThreshold function determines the dynamic threshold based on the average transaction arrival rate (averageTxArrivalRate) and the target mempool occupancy (targetMempoolOccupancy). The average arrival rate reflects the network’s transaction volume, while the target occupancy represents the desired proportion of the maximum mempool size that should be occupied by pending transactions.

Calculating Target Mempool Occupancy:

The calculateTargetMempoolOccupancy function dynamically calculates the target mempool occupancy based on the average transaction arrival rate (averageTxArrivalRate), network load metric (networkLoadMetric), and safety margins. The network load metric provides an indication of the network’s ability to handle transaction volume, while the safety margins help prevent excessive mempool growth.

2)Network load computation

func (k Keeper) GetNetworkLoadMetric(ctx sdk.Context) float64 {
// Get CPU usage
var ru syscall.Rusage
err := syscall.Getrusage(syscall.RUSAGE_SELF, &ru)
if err != nil {
return 0
}

cpuTime := ru.Utime.Sec + ru.Stime.Sec
cpuPercentage := float64(cpuTime) / float64(time.Second) * 100

// Get bandwidth usage
bytesRead := ru.Ixrcc.ReadBytes
bytesWritten := ru.Ixwc.WrittenBytes
bandwidthUsage := float64(bytesRead+bytesWritten) / float64(time.Second)

// Calculate network load metric
loadMetric := (cpuPercentage + bandwidthUsage) / 2

return loadMetric

}

func (k Keeper) GetMaxResourceCapacity(ctx sdk.Context) float64 {
// Get maximum CPU capacity
cpuCount := runtime.NumCPU()
maxCPUCapacity := float64(cpuCount) * 100

// Get maximum bandwidth capacity
var networkInterfaces []net.Interface
interfaces, err := net.Interfaces()
if err != nil {
    return 0
}

for _, iface := range interfaces {
    if iface.Flags&net.FlagUp == 0 {
        continue
    }

    linkAttrs, err := iface.LinkAttrs()
    if err != nil {
        continue
    }

    maxBandwidthCapacity := linkAttrs.Speed
    break // Assuming single network interface
}

// Calculate network load metric
maxResourceCapacity := maxCPUCapacity + maxBandwidthCapacity
return maxResourceCapacity

}
GetNetworkGrowthMetric
This function calculate network growth based on the increase in the number of active contract addresses and total transactions over time.

//Get the current block height
currentBlockHeight := tendermintClient.GetBlockHeight(ctx)

// Get the block height at a specific time interval in the past
previousBlockHeight := tendermintClient.GetBlockHeightByTime(ctx, time.Now().Add(-time.Hour))

// Query the blockchain to count transactions in each block
currentTxCount := 0
previousTxCount := 0
for blockHeight := currentBlockHeight; blockHeight >= previousBlockHeight; blockHeight-- {
block := tendermintClient.GetBlockByHeight(ctx, blockHeight)
if block.TxCount > 0 {
if blockHeight == currentBlockHeight {
currentTxCount = block.TxCount
} else {
previousTxCount += block.TxCount
}
}
}

func (k Keeper) GetNetworkGrowthMetric(ctx sdk.Context) float64 {
// Calculate the growth rate as the percentage change in transaction count
growthRate := (currentTxCount - previousTxCount) / previousTxCount

// Convert the growth rate to a percentage and return it
growthMetric := growthRate * 100
return growthMetric

}

// Get the current block height
currentBlockHeight := tendermintClient.GetBlockHeight(ctx)

// Get the block height at a specific time interval in the past
previousBlockHeight := tendermintClient.GetBlockHeightByTime(ctx, time.Now().Add(-time.Hour))

// Query the blockchain to count transactions and smart contracts in each block
currentTxCount := 0
previousTxCount := 0
currentSCCount := 0
previousSCCount := 0

for blockHeight := currentBlockHeight; blockHeight >= previousBlockHeight; blockHeight-- {
block := tendermintClient.GetBlockByHeight(ctx, blockHeight)
if block.TxCount > 0 {
if blockHeight == currentBlockHeight {
currentTxCount = block.TxCount
} else {
previousTxCount += block.TxCount
}
}

// Count smart contracts deployed in the block
for _, tx := range block.Txs {
    if tx.Type == types.TxTypeContract {
        if blockHeight == currentBlockHeight {
            currentSCCount++
        } else {
            previousSCCount++
        }
    }
}

}

func (k Keeper) GetNetworkGrowthMetric(ctx sdk.Context) float64 {
// Calculate the growth rate for transactions and Dapps
txGrowthRate := (currentTxCount - previousTxCount) / previousTxCount
scGrowthRate := (currentSCCount - previousSCCount) / previousSCCount

//weight for transactions and Dapp growth rate on the chain
growthMetric := (0.7 * txGrowthRate) + (0.3 * scGrowthRate)
growthMetric *= 100 // Convert to percentage

return growthMetric

}