Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
62 changes: 61 additions & 1 deletion bindings/generated/test/counter/counter.go

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

17 changes: 17 additions & 0 deletions contracts/test/sources/counter.move
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ module test::counter {
id: UID,
}

public struct SomeObject has key, store {
id: UID,
}

// Pointer to reference both Counter and AdminCap objects
public struct CounterPointer has key, store {
id: UID,
Expand Down Expand Up @@ -459,4 +463,17 @@ module test::counter {
vector::push_back(&mut vectors, @0x4.to_bytes());
vectors
}

#[allow(lint(self_transfer))]
public fun create_many_objects(count: u64, ctx: &mut TxContext) {
let mut i = 0;

while (i < count) {
let obj = SomeObject {
id: object::new(ctx),
};
transfer::transfer(obj, tx_context::sender(ctx));
i = i + 1;
}
}
}
8 changes: 4 additions & 4 deletions relayer/client/mocks/mock_ptb_client.go

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

69 changes: 41 additions & 28 deletions relayer/client/ptb_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ type SuiPTBClient interface {
MoveCall(ctx context.Context, req MoveCallRequest) (TxnMetaData, error)
SendTransaction(ctx context.Context, payload TransactionBlockRequest) (SuiTransactionBlockResponse, error)
ReadOwnedObjects(ctx context.Context, ownerAddress string, cursor *models.ObjectId) ([]models.SuiObjectResponse, error)
ReadFilterOwnedObjectIds(ctx context.Context, ownerAddress string, structType string, limit *uint) ([]models.SuiObjectData, error)
ReadFilterOwnedObjectIds(ctx context.Context, ownerAddress string, structType string, cursor string) ([]models.SuiObjectData, error)
ReadObjectId(ctx context.Context, objectId string) (models.SuiObjectData, error)
ReadFunction(ctx context.Context, signerAddress string, packageId string, module string, function string, args []any, argTypes []string, typeArgs []string) ([]any, error)
SignAndSendTransaction(ctx context.Context, txBytesRaw string, signerPublicKey []byte, executionRequestType TransactionRequestType) (SuiTransactionBlockResponse, error)
Expand Down Expand Up @@ -202,8 +202,6 @@ func (c *PTBClient) WithRateLimit(ctx context.Context, methodName string, f func
c.log.Debugw("WithRateLimit released", "methodName", methodName, "duration", time.Since(start))
}()

c.log.Debugw("WithRateLimit starting work")

// run the user function with the timeout context
// if the function respects the context, it will return and lock will be released in defer
return f(workCtx)
Expand Down Expand Up @@ -309,44 +307,59 @@ func (c *PTBClient) readObjectIdInternal(ctx context.Context, objectId string) (
return *response.Data, nil
}

func (c *PTBClient) ReadFilterOwnedObjectIds(ctx context.Context, ownerAddress string, structType string, limit *uint) ([]models.SuiObjectData, error) {
func (c *PTBClient) ReadFilterOwnedObjectIds(ctx context.Context, ownerAddress string, structType string, cursor string) ([]models.SuiObjectData, error) {
var result []models.SuiObjectData
err := c.WithRateLimit(ctx, "ReadFilterOwnedObjectIds", func(ctx context.Context) error {
limitVal := uint64(maxPageSize)
if limit != nil {
limitVal = uint64(*limit)
}

ownedObjectsReq := models.SuiXGetOwnedObjectsRequest{
Address: ownerAddress,
Query: models.SuiObjectResponseQuery{
Filter: models.ObjectFilterByStructType{
StructType: structType,
},
Options: models.SuiObjectDataOptions{
ShowType: true,
},
},
Limit: limitVal,
}

response, err := c.client.SuiXGetOwnedObjects(ctx, ownedObjectsReq)
err := c.WithRateLimit(ctx, "ReadFilterOwnedObjectIds", func(ctx context.Context) error {
response, err := c.readFilterOwnedObjectIdsInternal(ctx, ownerAddress, structType, cursor)
if err != nil {
return fmt.Errorf("failed to read owned objects: %w", err)
return fmt.Errorf("failed to read filter owned object ids: %w", err)
}

for _, obj := range response.Data {
if obj.Data != nil {
result = append(result, *obj.Data)
}
result = append(result, *obj.Data)
}

return nil
return err
})

return result, err
}

func (c *PTBClient) readFilterOwnedObjectIdsInternal(ctx context.Context, ownerAddress string, structType string, cursor string) (models.PaginatedObjectsResponse, error) {
ownedObjectsReq := models.SuiXGetOwnedObjectsRequest{
Address: ownerAddress,
Query: models.SuiObjectResponseQuery{
Filter: models.ObjectFilterByStructType{
StructType: structType,
},
Options: models.SuiObjectDataOptions{
ShowType: true,
},
},
Limit: uint64(maxPageSize),
}

if cursor != "" {
ownedObjectsReq.Cursor = cursor
}

response, err := c.client.SuiXGetOwnedObjects(ctx, ownedObjectsReq)
if err != nil {
return models.PaginatedObjectsResponse{}, fmt.Errorf("failed to read owned objects: %w", err)
}

if response.HasNextPage {
nextPage, err := c.readFilterOwnedObjectIdsInternal(ctx, ownerAddress, structType, response.NextCursor)
if err != nil {
return models.PaginatedObjectsResponse{}, fmt.Errorf("failed to read next page of owned objects: %w", err)
}
response.Data = append(response.Data, nextPage.Data...)
}

return response, nil
}

func (c *PTBClient) ReadOwnedObjects(ctx context.Context, ownerAddress string, cursor *models.ObjectId) ([]models.SuiObjectResponse, error) {
var result []models.SuiObjectResponse
err := c.WithRateLimit(ctx, "ReadOwnedObjects", func(ctx context.Context) error {
Expand Down
57 changes: 54 additions & 3 deletions relayer/client/ptb_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,19 +286,42 @@ func TestPTBClient(t *testing.T) {
require.True(t, len(objects) > 0)
})

t.Run("ReadFilterOwnedObjectIds", func(t *testing.T) {
t.Run("ReadFilterOwnedObjectIds_(no_cursor)", func(t *testing.T) {
objects, err := relayerClient.ReadFilterOwnedObjectIds(
context.Background(),
accountAddress,
fmt.Sprintf("%s::counter::AdminCap", packageId),
nil,
"",
)
require.NoError(t, err)
require.NotNil(t, objects)
require.Equal(t, 1, len(objects))
require.NotZero(t, len(objects))
require.Equal(t, fmt.Sprintf("%s::counter::AdminCap", packageId), objects[0].Type)
})

t.Run("ReadFilterOwnedObjectIds_(many_pages)", func(t *testing.T) {
for i := 0; i < 5; i++ {
err := testutils.FundWithFaucet(log, testutils.SuiLocalnet, accountAddress)
require.NoError(t, err)
}

CreateManyObjects(t, relayerClient, packageId, accountAddress, publicKeyBytes)

objects, err := relayerClient.ReadFilterOwnedObjectIds(
context.Background(),
accountAddress,
fmt.Sprintf("%s::counter::SomeObject", packageId),
"",
)
require.NoError(t, err)
require.NotNil(t, objects)
require.Equal(t, 100, len(objects))

for _, obj := range objects {
require.Equal(t, fmt.Sprintf("%s::counter::SomeObject", packageId), obj.Type)
}
})

//nolint:paralleltest
t.Run("GetTransactionStatus", func(t *testing.T) {
txDigest := IncrementCounterWithMoveCall(t, relayerClient, packageId, counterObjectId, accountAddress, publicKeyBytes)
Expand Down Expand Up @@ -564,6 +587,34 @@ func IncrementCounterWithMoveCall(t *testing.T, relayerClient *client.PTBClient,
return resp.TxDigest
}

func CreateManyObjects(t *testing.T, relayerClient *client.PTBClient, packageId string, accountAddress string, signerPublicKey []byte) {
t.Helper()
// Prepare arguments for a move call
moveCallReq := client.MoveCallRequest{
Signer: accountAddress,
PackageObjectId: packageId,
Module: "counter",
Function: "create_many_objects",
Arguments: []any{"100"},
TypeArguments: []any{"u64"},
GasBudget: 2000000000,
}

txnMetadata, err := relayerClient.MoveCall(context.Background(), moveCallReq)
require.NoError(t, err)
require.NotEmpty(t, txnMetadata.TxBytes, "Expected non-empty transaction bytes")

// Verify we can execute the transaction
resp, err := relayerClient.SignAndSendTransaction(
context.Background(),
txnMetadata.TxBytes,
signerPublicKey,
"WaitForLocalExecution",
)
require.NoError(t, err)
require.Equal(t, "success", resp.Status.Status, "Expected move call to succeed")
}

func CreateFailedTransaction(t *testing.T, relayerClient *client.PTBClient, packageId string, counterObjectId string, accountAddress string, signerPublicKey []byte) {
t.Helper()
// Prepare arguments for a move call
Expand Down
Loading
Loading