Skip to content
Draft
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
129 changes: 85 additions & 44 deletions capabilities/blockchain/aptos/client_sdk.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

// Capability ID: aptos:ChainSelector:<chainSelector>@1.0.0, method "View".

package aptos
Expand Down Expand Up @@ -100,6 +99,8 @@ func (c *Client) View(runtime cre.Runtime, input *ViewRequest) cre.Promise[*View

// decodeWriteReportReply decodes capabilities.blockchain.aptos.v1alpha.WriteReportReply
// via protobuf wire parsing to avoid runtime reflection panics under WASM.
// It accepts both the currently deployed Aptos capability wire layout and the
// newer SDK layout for receiver_contract_execution_status during rollout.
func decodeWriteReportReply(b []byte) (*WriteReportReply, error) {
out := &WriteReportReply{}
for len(b) > 0 {
Expand All @@ -119,50 +120,90 @@ func decodeWriteReportReply(b []byte) (*WriteReportReply, error) {
}
out.TxStatus = TxStatus(v)
b = b[m:]
case 2: // receiver_contract_execution_status enum (varint)
if typ != protowire.VarintType {
return nil, fmt.Errorf("decode WriteReportReply.receiver_contract_execution_status: unexpected wire type %d", typ)
}
v, m := protowire.ConsumeVarint(b)
if m < 0 {
return nil, fmt.Errorf("decode WriteReportReply.receiver_contract_execution_status varint: %v", protowire.ParseError(m))
}
status := ReceiverContractExecutionStatus(v)
out.ReceiverContractExecutionStatus = &status
b = b[m:]
case 3: // tx_hash string
if typ != protowire.BytesType {
return nil, fmt.Errorf("decode WriteReportReply.tx_hash: unexpected wire type %d", typ)
}
v, m := protowire.ConsumeBytes(b)
if m < 0 {
return nil, fmt.Errorf("decode WriteReportReply.tx_hash bytes: %v", protowire.ParseError(m))
}
txHash := string(v)
out.TxHash = &txHash
b = b[m:]
case 4: // transaction_fee varint
if typ != protowire.VarintType {
return nil, fmt.Errorf("decode WriteReportReply.transaction_fee: unexpected wire type %d", typ)
}
v, m := protowire.ConsumeVarint(b)
if m < 0 {
return nil, fmt.Errorf("decode WriteReportReply.transaction_fee varint: %v", protowire.ParseError(m))
}
fee := uint64(v)
out.TransactionFee = &fee
b = b[m:]
case 5: // error_message string
if typ != protowire.BytesType {
return nil, fmt.Errorf("decode WriteReportReply.error_message: unexpected wire type %d", typ)
}
v, m := protowire.ConsumeBytes(b)
if m < 0 {
return nil, fmt.Errorf("decode WriteReportReply.error_message bytes: %v", protowire.ParseError(m))
case 2: // deployed layout: tx_hash string; newer layout: receiver status enum
switch typ {
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
if m < 0 {
return nil, fmt.Errorf("decode WriteReportReply.tx_hash bytes: %v", protowire.ParseError(m))
}
txHash := string(v)
out.TxHash = &txHash
b = b[m:]
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
if m < 0 {
return nil, fmt.Errorf("decode WriteReportReply.receiver_contract_execution_status varint: %v", protowire.ParseError(m))
}
status := ReceiverContractExecutionStatus(v)
out.ReceiverContractExecutionStatus = &status
b = b[m:]
default:
return nil, fmt.Errorf("decode WriteReportReply field 2: unexpected wire type %d", typ)
}
case 3: // deployed layout: transaction_fee varint; newer layout: tx_hash string
switch typ {
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
if m < 0 {
return nil, fmt.Errorf("decode WriteReportReply.transaction_fee varint: %v", protowire.ParseError(m))
}
fee := uint64(v)
out.TransactionFee = &fee
b = b[m:]
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
if m < 0 {
return nil, fmt.Errorf("decode WriteReportReply.tx_hash bytes: %v", protowire.ParseError(m))
}
txHash := string(v)
out.TxHash = &txHash
b = b[m:]
default:
return nil, fmt.Errorf("decode WriteReportReply field 3: unexpected wire type %d", typ)
}
case 4: // deployed layout: error_message string; newer layout: transaction_fee varint
switch typ {
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
if m < 0 {
return nil, fmt.Errorf("decode WriteReportReply.error_message bytes: %v", protowire.ParseError(m))
}
msg := string(v)
out.ErrorMessage = &msg
b = b[m:]
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
if m < 0 {
return nil, fmt.Errorf("decode WriteReportReply.transaction_fee varint: %v", protowire.ParseError(m))
}
fee := uint64(v)
out.TransactionFee = &fee
b = b[m:]
default:
return nil, fmt.Errorf("decode WriteReportReply field 4: unexpected wire type %d", typ)
}
case 5: // deployed layout: receiver status enum; newer layout: error_message string
switch typ {
case protowire.VarintType:
v, m := protowire.ConsumeVarint(b)
if m < 0 {
return nil, fmt.Errorf("decode WriteReportReply.receiver_contract_execution_status varint: %v", protowire.ParseError(m))
}
status := ReceiverContractExecutionStatus(v)
out.ReceiverContractExecutionStatus = &status
b = b[m:]
case protowire.BytesType:
v, m := protowire.ConsumeBytes(b)
if m < 0 {
return nil, fmt.Errorf("decode WriteReportReply.error_message bytes: %v", protowire.ParseError(m))
}
msg := string(v)
out.ErrorMessage = &msg
b = b[m:]
default:
return nil, fmt.Errorf("decode WriteReportReply field 5: unexpected wire type %d", typ)
}
msg := string(v)
out.ErrorMessage = &msg
b = b[m:]
default:
m := protowire.ConsumeFieldValue(num, typ, b)
if m < 0 {
Expand Down
29 changes: 29 additions & 0 deletions capabilities/blockchain/aptos/client_sdk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

"github.com/stretchr/testify/require"
"google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/proto"
)

Expand Down Expand Up @@ -34,3 +35,31 @@ func TestDecodeWriteReportReply_NewWireShape(t *testing.T) {
require.NotNil(t, reply.ErrorMessage)
require.Equal(t, errMsg, *reply.ErrorMessage)
}

func TestDecodeWriteReportReply_DeployedWireShape(t *testing.T) {
t.Parallel()

var replyBytes []byte
replyBytes = protowire.AppendTag(replyBytes, 1, protowire.VarintType)
replyBytes = protowire.AppendVarint(replyBytes, uint64(TxStatus_TX_STATUS_ABORTED))
replyBytes = protowire.AppendTag(replyBytes, 2, protowire.BytesType)
replyBytes = protowire.AppendString(replyBytes, "0xabc123")
replyBytes = protowire.AppendTag(replyBytes, 3, protowire.VarintType)
replyBytes = protowire.AppendVarint(replyBytes, 42)
replyBytes = protowire.AppendTag(replyBytes, 4, protowire.BytesType)
replyBytes = protowire.AppendString(replyBytes, "receiver execution failed")
replyBytes = protowire.AppendTag(replyBytes, 5, protowire.VarintType)
replyBytes = protowire.AppendVarint(replyBytes, uint64(ReceiverContractExecutionStatus_RECEIVER_CONTRACT_EXECUTION_STATUS_REVERTED))

reply, err := decodeWriteReportReply(replyBytes)
require.NoError(t, err)
require.Equal(t, TxStatus_TX_STATUS_ABORTED, reply.TxStatus)
require.NotNil(t, reply.ReceiverContractExecutionStatus)
require.Equal(t, ReceiverContractExecutionStatus_RECEIVER_CONTRACT_EXECUTION_STATUS_REVERTED, *reply.ReceiverContractExecutionStatus)
require.NotNil(t, reply.TxHash)
require.Equal(t, "0xabc123", *reply.TxHash)
require.NotNil(t, reply.TransactionFee)
require.Equal(t, uint64(42), *reply.TransactionFee)
require.NotNil(t, reply.ErrorMessage)
require.Equal(t, "receiver execution failed", *reply.ErrorMessage)
}
Loading