Skip to content

Commit

Permalink
change in calcs + logs
Browse files Browse the repository at this point in the history
  • Loading branch information
0xnogo committed Nov 8, 2024
1 parent f49fe84 commit d109d64
Show file tree
Hide file tree
Showing 2 changed files with 314 additions and 262 deletions.
72 changes: 64 additions & 8 deletions execute/exectypes/costly_messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import (

"github.com/smartcontractkit/chainlink-ccip/execute/internal/gas"

"github.com/smartcontractkit/chainlink-ccip/internal/libs/mathslib"
"github.com/smartcontractkit/chainlink-ccip/internal/plugintypes"
readerpkg "github.com/smartcontractkit/chainlink-ccip/pkg/reader"
cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3"
"github.com/smartcontractkit/chainlink-common/pkg/types"
)

const (
Expand Down Expand Up @@ -118,7 +120,12 @@ func (o *CCIPCostlyMessageObserver) Observe(
return nil, fmt.Errorf("missing exec cost for message %s", msg.Header.MessageID)
}
if fee.Cmp(execCost) < 0 {
o.lggr.Warnw("message is too costly to execute", "messageID",
msg.Header.MessageID.String(), "fee", fee, "execCost", execCost, "seqNum", msg.Header.SequenceNumber)
costlyMessages = append(costlyMessages, msg.Header.MessageID)
} else {
o.lggr.Warnw("message is not too costly to execute", "messageID",
msg.Header.MessageID.String(), "fee", fee, "execCost", execCost, "seqNum", msg.Header.SequenceNumber)
}
}

Expand Down Expand Up @@ -297,16 +304,20 @@ func (c *CCIPMessageFeeUSD18Calculator) MessageFeeUSD18(

messageFees := make(map[cciptypes.Bytes32]plugintypes.USD18)
for _, msg := range messages {
feeUSD18 := new(big.Int).Mul(linkPriceUSD.Int, msg.FeeValueJuels.Int)
feeUSD18 := new(big.Int).Div(
new(big.Int).Mul(linkPriceUSD.Int, msg.FeeValueJuels.Int),
new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil),
)
timestamp, ok := messageTimeStamps[msg.Header.MessageID]
if !ok {
// If a timestamp is missing we can't do fee boosting, but we still record the fee. In the worst case, the
// message will not be executed (as it will be considered too costly).
c.lggr.Warnw("missing timestamp for message", "messageID", msg.Header.MessageID)
} else {
feeUSD18 = waitBoostedFee(c.now().Sub(timestamp), feeUSD18, c.relativeBoostPerWaitHour)
feeUSD18 = waitBoostedFee(c.lggr, c.now().Sub(timestamp), feeUSD18, c.relativeBoostPerWaitHour)
}

c.lggr.Warnw("message fee", "messageID", msg.Header.MessageID.String(), "fee", feeUSD18,
"linkPriceUSD", linkPriceUSD, "feeValueJuels", msg.FeeValueJuels)
messageFees[msg.Header.MessageID] = feeUSD18
}

Expand All @@ -319,12 +330,18 @@ func (c *CCIPMessageFeeUSD18Calculator) MessageFeeUSD18(
// At the same time, messages that are slightly underpaid will start going through after waiting for a little bit.
//
// wait_boosted_fee(m) = (1 + (now - m.send_time).hours * RELATIVE_BOOST_PER_WAIT_HOUR) * fee(m)
func waitBoostedFee(waitTime time.Duration, fee *big.Int, relativeBoostPerWaitHour float64) *big.Int {
func waitBoostedFee(
lggr logger.Logger,
waitTime time.Duration,
fee *big.Int,
relativeBoostPerWaitHour float64) *big.Int {
k := 1.0 + waitTime.Hours()*relativeBoostPerWaitHour

boostedFee := big.NewFloat(0).Mul(big.NewFloat(k), new(big.Float).SetInt(fee))
res, _ := boostedFee.Int(nil)

lggr.Warnw("waitBoostedFee", "feeBefore", fee, "waitTime", waitTime, "feeAfter", res)

return res
}

Expand All @@ -350,21 +367,55 @@ func (c *CCIPMessageExecCostUSD18Calculator) MessageExecCostUSD18(
if feeComponents.DataAvailabilityFee == nil {
return nil, fmt.Errorf("missing data availability fee")
}

executionFee, daFee, err := c.getFeesUSD18(ctx, feeComponents, messages[0].Header.DestChainSelector)
if err != nil {
return nil, fmt.Errorf("unable to convert fee components to USD18: %w", err)
}

daConfig, err := c.ccipReader.GetMedianDataAvailabilityGasConfig(ctx)
if err != nil {
return nil, fmt.Errorf("unable to get data availability gas config: %w", err)
}

for _, msg := range messages {
executionCostUSD18 := c.computeExecutionCostUSD18(feeComponents.ExecutionFee, msg)
dataAvailabilityCostUSD18 := computeDataAvailabilityCostUSD18(feeComponents.DataAvailabilityFee, daConfig, msg)
executionCostUSD18 := c.computeExecutionCostUSD18(executionFee, msg)
dataAvailabilityCostUSD18 := c.computeDataAvailabilityCostUSD18(daFee, daConfig, msg)
totalCostUSD18 := new(big.Int).Add(executionCostUSD18, dataAvailabilityCostUSD18)
messageExecCosts[msg.Header.MessageID] = totalCostUSD18
}

return messageExecCosts, nil
}

func (c *CCIPMessageExecCostUSD18Calculator) getFeesUSD18(
ctx context.Context,
feeComponents types.ChainFeeComponents,
destChainSelector cciptypes.ChainSelector,
) (plugintypes.USD18, plugintypes.USD18, error) {
nativeTokenPrices := c.ccipReader.GetWrappedNativeTokenPriceUSD(
ctx,
[]cciptypes.ChainSelector{destChainSelector})
if nativeTokenPrices == nil {
return nil, nil, fmt.Errorf("unable to get native token prices")
}
nativeTokenPrice, ok := nativeTokenPrices[destChainSelector]
if !ok {
return nil, nil, fmt.Errorf("missing native token price for chain %s", destChainSelector)
}

executionFee := mathslib.CalculateUsdPerUnitGas(feeComponents.ExecutionFee, nativeTokenPrice.Int)
dataAvailabilityFee := mathslib.CalculateUsdPerUnitGas(feeComponents.DataAvailabilityFee, nativeTokenPrice.Int)

c.lggr.Warnw("getFeesUSD18", "nativeTokenPrice", nativeTokenPrice,
"feeComponents.ExecutionFee", feeComponents.ExecutionFee,
"feeComponents.DataAvailabilityFee", feeComponents.DataAvailabilityFee,
"executionFee", executionFee,
"dataAvailabilityFee", dataAvailabilityFee)

return executionFee, dataAvailabilityFee, nil
}

// computeExecutionCostUSD18 computes the execution cost of a message in USD18s.
// The cost is:
// messageGas (gas) * executionFee (USD18/gas) = USD18
Expand All @@ -374,11 +425,13 @@ func (c *CCIPMessageExecCostUSD18Calculator) computeExecutionCostUSD18(
) plugintypes.USD18 {
messageGas := new(big.Int).SetUint64(c.estimateProvider.CalculateMessageMaxGas(message))
cost := new(big.Int).Mul(messageGas, executionFee)
c.lggr.Warnw("computeExecutionCostUSD18", "messageID", message.Header.MessageID.String(), "messageGas",
messageGas, "executionFee", executionFee, "cost", cost)
return cost
}

// computeDataAvailabilityCostUSD18 computes the data availability cost of a message in USD18s.
func computeDataAvailabilityCostUSD18(
func (c *CCIPMessageExecCostUSD18Calculator) computeDataAvailabilityCostUSD18(
dataAvailabilityFee *big.Int,
daConfig cciptypes.DataAvailabilityGasConfig,
message cciptypes.Message,
Expand All @@ -388,7 +441,10 @@ func computeDataAvailabilityCostUSD18(
}

messageGas := calculateMessageMaxDAGas(message, daConfig)
return big.NewInt(0).Mul(messageGas, dataAvailabilityFee)
cost := big.NewInt(0).Mul(messageGas, dataAvailabilityFee)
c.lggr.Warnw("computeDataAvailabilityCostUSD18", "messageID", message.Header.MessageID.String(), "messageGas",
messageGas, "daConfig", daConfig, "cost", cost)
return cost
}

// calculateMessageMaxDAGas calculates the total DA gas needed for a CCIP message
Expand Down
Loading

0 comments on commit d109d64

Please sign in to comment.