Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/CI.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
env:
# Ensure that a cached go version is used:
# https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md#go
GO_VERSION: 1.26.4
GO_VERSION: 1.26.6
GOPRIVATE: github.com/smartcontractkit/capabilities

jobs:
Expand Down
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
nodejs 20.18.1
pnpm 10.6.5
golang 1.26.4
golang 1.26.6
golangci-lint 2.11.4
10 changes: 5 additions & 5 deletions chain_capabilities/aptos/actions/forwarder_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ package actions
import (
"context"
"encoding/binary"
"encoding/hex"
"encoding/json"
"fmt"
"slices"

aptos_sdk "github.com/aptos-labs/aptos-go-sdk"
"github.com/aptos-labs/aptos-go-sdk/bcs"
"github.com/ethereum/go-ethereum/common"
aptos_forwarder "github.com/smartcontractkit/chainlink-aptos/bindings/platform/forwarder"
aptoscap "github.com/smartcontractkit/chainlink-common/pkg/capabilities/v2/chain-capabilities/aptos"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
Expand Down Expand Up @@ -109,7 +109,7 @@ func (fc *forwarderClient) InvokeOnReport(ctx context.Context, receiver []byte,
"forwarderAddress", fmt.Sprintf("%x", fc.forwarderAddress),
"moduleName", moduleInformation.ModuleName,
)
reply, err := fc.AptosService.SubmitTransaction(ctx, aptostypes.SubmitTransactionRequest{
reply, err := fc.SubmitTransaction(ctx, aptostypes.SubmitTransactionRequest{
// TODO: do i really need ReceiverModuleID if my EncodedPayload is of type EntryFunction which has all the details ?
ReceiverModuleID: aptostypes.ModuleID{
Address: aptostypes.AccountAddress(fc.forwarderAddress),
Expand All @@ -134,7 +134,7 @@ type TransmissionID struct {
}

func (t TransmissionID) GetDebugID() string {
return fmt.Sprintf("receiver: %s, reportID: %s, workflowExecutionID %s", t.Receiver.String(), common.Bytes2Hex(t.ReportID[:]), common.Bytes2Hex(t.WorkflowExecutionID[:]))
return fmt.Sprintf("receiver: %s, reportID: %s, workflowExecutionID %s", t.Receiver.String(), hex.EncodeToString(t.ReportID[:]), hex.EncodeToString(t.WorkflowExecutionID[:]))
}

type TransmissionInfo struct {
Expand Down Expand Up @@ -170,7 +170,7 @@ func (fc *forwarderClient) GetTransmissionInfo(ctx context.Context, transmission
return TransmissionInfo{}, fmt.Errorf("failed to encode GetTransmitter: %w", err)
}

viewReply, err := fc.AptosService.View(ctx, aptostypes.ViewRequest{
viewReply, err := fc.View(ctx, aptostypes.ViewRequest{
Payload: &aptostypes.ViewPayload{
Module: aptostypes.ModuleID{
Address: aptostypes.AccountAddress(moduleInfo.Address),
Expand Down Expand Up @@ -218,7 +218,7 @@ func (fc *forwarderClient) GetTransmitterTransactions(ctx context.Context, trans
"hasStart", start != nil,
"hasLimit", limit != nil,
)
reply, err := fc.AptosService.AccountTransactions(ctx, aptostypes.AccountTransactionsRequest{
reply, err := fc.AccountTransactions(ctx, aptostypes.AccountTransactionsRequest{
Address: aptostypes.AccountAddress(transmitter),
Start: start,
Limit: limit,
Expand Down
6 changes: 1 addition & 5 deletions chain_capabilities/aptos/actions/tx_info_retriever.go
Original file line number Diff line number Diff line change
Expand Up @@ -470,11 +470,7 @@ func (thr *TxInfoRetriever) matchesTransmissionByReport(arguments []any) bool {

reportHex, _ := arguments[1].(string)
expectedReportHex := hex.EncodeToString(slices.Concat(thr.report.ReportContext, thr.report.RawReport))
if strings.TrimPrefix(reportHex, "0x") != expectedReportHex {
return false
}

return true
return strings.TrimPrefix(reportHex, "0x") == expectedReportHex
}

// receiverAddressesEqual compares a hex-encoded receiver from chain tx arguments
Expand Down
49 changes: 7 additions & 42 deletions chain_capabilities/aptos/actions/write_report.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"encoding/json"
"fmt"
"math"
"math/big"
"slices"
"strings"
"time"
Expand Down Expand Up @@ -38,11 +37,6 @@ import (
// Set to 2x with margin for gas schedule changes.
const ForwarderGasOverhead uint64 = 4000

// aptosOctasToAPT converts a fee in octas (10^-8 APT) to a *big.Float in APT.
func aptosOctasToAPT(octas uint64) *big.Float {
return new(big.Float).Quo(new(big.Float).SetUint64(octas), big.NewFloat(1e8))
}

// WriteReport validates and submits a signed report to the Aptos chain via the CRE forwarder.
func (s *Aptos) WriteReport(
ctx context.Context,
Expand Down Expand Up @@ -231,14 +225,13 @@ func (wr *writeReport) execute(
ownLedgerVersion, ownFeeInOctas, ownVMStatus, ownBlockTimestamp, feeErr := wr.getTxnInfoFromChain(ctx, txReply.TxHash)
if feeErr != nil {
wr.lggr.Errorw("Failed to get transaction fee, using zero for metering", "txHash", txReply.TxHash, "error", feeErr)
ownMeteringMetadata = metering.GetResponseMetadataWriteReport(big.NewFloat(0), wr.chainSelector)
ownMeteringMetadata = metering.GetResponseMetadataWriteReport(0, wr.chainSelector)
monitoring.LogAndEmitError(ctx, wr.lggr, wr.beholderProcessor,
wr.messageBuilder.BuildWriteReportTxFeeCalculationError(telemetryContext, request, txReply.TxHash, feeErr.Error()))
} else {
pinnedLedgerVersion = &ownLedgerVersion
feeInAPT := aptosOctasToAPT(ownFeeInOctas)
ownMeteringMetadata = metering.GetResponseMetadataWriteReport(feeInAPT, wr.chainSelector)
wr.lggr.Debugw("WriteReport fee", "feeInAPT", feeInAPT.String(), "feeInOctas", ownFeeInOctas, "ledgerVersion", ownLedgerVersion)
ownMeteringMetadata = metering.GetResponseMetadataWriteReport(ownFeeInOctas, wr.chainSelector)
wr.lggr.Debugw("WriteReport fee", "feeInOctas", ownFeeInOctas, "ledgerVersion", ownLedgerVersion)
}

// Measured to the transaction's on-chain block timestamp rather than to when the submit call
Expand Down Expand Up @@ -284,17 +277,16 @@ func (wr *writeReport) execute(
return nil, capabilities.ResponseMetadata{}, fmt.Errorf("failed to get successful transmission hash: %w", txHashErr)
}
feeInOctas := successResult.GasUsed * successResult.GasUnitPrice
feeInAPT := aptosOctasToAPT(feeInOctas)
meteringMetadata := metering.GetResponseMetadataWriteReport(feeInAPT, wr.chainSelector)
wr.lggr.Debugw("WriteReport fee", "feeInAPT", feeInAPT.String(), "feeInOctas", feeInOctas)
meteringMetadata := metering.GetResponseMetadataWriteReport(feeInOctas, wr.chainSelector)
wr.lggr.Debugw("WriteReport fee", "feeInOctas", feeInOctas)

monitoring.LogAndEmitSuccess(ctx, "WriteReport sent a duplicate transaction, report already on-chain",
wr.lggr, wr.beholderProcessor,
wr.messageBuilder.BuildWriteReportDuplicateTx(telemetryContext, request, txReply.TxHash, successResult.TxHash))

if txReply.TxStatus == aptostypes.TxFatal {
wr.lggr.Errorw("Transaction failed to get processed, but report was already submitted, this is unexpected and should be investigated", "txHash", txReply.TxHash)
meteringMetadata = metering.GetResponseMetadataWriteReport(big.NewFloat(0), wr.chainSelector)
meteringMetadata = metering.GetResponseMetadataWriteReport(0, wr.chainSelector)
}

return &aptoscap.WriteReportReply{
Expand Down Expand Up @@ -362,8 +354,7 @@ func (wr *writeReport) execute(
// charge the user for the failed txs if it was reverted on user contract
var replyMeta capabilities.ResponseMetadata
if recvStatus != nil && *recvStatus == aptoscap.ReceiverContractExecutionStatus_RECEIVER_CONTRACT_EXECUTION_STATUS_REVERTED {
feeInAPT := aptosOctasToAPT(feeOctas)
replyMeta = metering.GetResponseMetadataWriteReport(feeInAPT, wr.chainSelector)
replyMeta = metering.GetResponseMetadataWriteReport(feeOctas, wr.chainSelector)
}
return &aptoscap.WriteReportReply{
TxStatus: aptoscap.TxStatus_TX_STATUS_FATAL,
Expand All @@ -382,32 +373,6 @@ func (wr *writeReport) execute(
return nil, capabilities.ResponseMetadata{}, nil // should never happen
}

// buildPreSubmissionFatalReply evaluates node 0's failed tx and returns a fatal reply

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we still need this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see it anywhere else in the codebase. The linter had it marked as unused

// if we should NOT submit, or (nil, empty) if we should proceed to submit.
func (wr *writeReport) buildPreSubmissionFatalReply(failedResult TransmissionTxInfo, ourMaxGasAmount uint64) (*aptoscap.WriteReportReply, capabilities.ResponseMetadata) {
if isOutOfGas(failedResult.VMStatus) && ourMaxGasAmount > failedResult.MaxGasAmount {
// We have more gas headroom than node 0 — proceed to submit.
return nil, capabilities.ResponseMetadata{}
}

// Either not OOG (user error, unrecoverable) or our gas isn't higher — return fatal.
// No metering: we never submitted, so we incurred no gas cost.
feeOctas := failedResult.GasUsed * failedResult.GasUnitPrice
return &aptoscap.WriteReportReply{
TxStatus: aptoscap.TxStatus_TX_STATUS_FATAL,
TxHash: &failedResult.TxHash,
TransactionFee: &feeOctas,
ErrorMessage: ptrIfNonEmpty(failedResult.VMStatus),
ReceiverContractExecutionStatus: receiverContractExecutionStatusFromFailedVMStatus(failedResult.VMStatus, wr.forwarderAddress),
}, capabilities.ResponseMetadata{}
}

// isOutOfGas returns true if the VM status string indicates the transaction
// exhausted its total gas budget. The Aptos VM returns exactly "Out of gas".
func isOutOfGas(vmStatus string) bool {
return vmStatus == "Out of gas"
}

// getTxnInfoFromChain returns the committed ledger version, fee in octas (gasUsed * gasUnitPrice),
// and VM status for a submitted tx, looked up via AptosService.TransactionByHash.
func (wr *writeReport) getTxnInfoFromChain(ctx context.Context, txHash string) (uint64, uint64, string, uint64, error) {
Expand Down
17 changes: 8 additions & 9 deletions chain_capabilities/aptos/go.mod
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
module github.com/smartcontractkit/capabilities/chain_capabilities/aptos

go 1.26.4
go 1.26.6

require (
github.com/aptos-labs/aptos-go-sdk v1.12.1
github.com/smartcontractkit/capabilities/chain_capabilities/common v0.0.0-20260729165045-b00a39493e13
github.com/smartcontractkit/capabilities/libs v0.0.0-20260714133332-db2a5f11cd64
github.com/smartcontractkit/chain-selectors v1.0.104
github.com/smartcontractkit/chainlink-aptos v0.0.0-20260506112908-f0d993b5bd6d
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260707203317-661b54b51a33
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260821155228-fa1d775e2138
)

require (
Expand All @@ -20,7 +20,8 @@ require (
github.com/jonboulle/clockwork v0.5.0 // indirect
github.com/jpillora/backoff v1.0.0 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/smartcontractkit/chainlink-protos/metering/go v0.0.0-20260710151514-27b5a126dabe // indirect
github.com/stretchr/objx v0.5.3 // indirect
go.opentelemetry.io/contrib/bridges/prometheus v0.68.0 // indirect
go.uber.org/goleak v1.3.0 // indirect
golang.org/x/sync v0.21.0 // indirect
Expand All @@ -39,9 +40,8 @@ require (
github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.16.1 // indirect
github.com/cloudevents/sdk-go/v2 v2.16.1 // indirect
github.com/coder/websocket v1.8.14 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
github.com/ethereum/go-ethereum v1.17.4
github.com/ethereum/go-ethereum v1.17.4 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
Expand Down Expand Up @@ -82,22 +82,21 @@ require (
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.3.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.1 // indirect
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect
github.com/scylladb/go-reflectx v1.0.1 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260713185857-30ad2e76c0f4
github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.11-0.20260626151909-052e55e62e62 // indirect
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260821143015-dd4fa25f7fee
github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.11-0.20260724142814-45996a1bcb72 // indirect
github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b // indirect
github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260709145319-7782fb89eb16 // indirect
github.com/smartcontractkit/freeport v0.1.3-0.20250716200817-cb5dfd0e369e // indirect
github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect
github.com/smartcontractkit/libocr v0.0.0-20260810200708-618b5bf7f342
github.com/stretchr/testify v1.11.1
github.com/stretchr/testify v1.12.0
github.com/valyala/fastjson v1.6.10 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
github.com/x448/float16 v0.8.4 // indirect
Expand Down
26 changes: 12 additions & 14 deletions chain_capabilities/aptos/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading