Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: elcontracts/reader new interface for admin and appointees #501

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
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
144 changes: 90 additions & 54 deletions chainio/clients/elcontracts/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -685,111 +685,147 @@ func (r *ChainReader) GetRegisteredSets(

func (r *ChainReader) CanCall(
ctx context.Context,
accountAddress gethcommon.Address,
appointeeAddress gethcommon.Address,
target gethcommon.Address,
selector [4]byte,
) (bool, error) {
request CanCallRequest,
) (CanCallResponse, error) {
if r.permissionController == nil {
return CanCallResponse{}, errors.New("PermissionController contract not provided")
}

canCall, err := r.permissionController.CanCall(
&bind.CallOpts{Context: ctx},
accountAddress,
appointeeAddress,
target,
selector,
&bind.CallOpts{Context: ctx, BlockNumber: request.BlockNumber},
request.AccountAddress,
request.AppointeeAddress,
request.Target,
request.Selector,
)
// This call should not fail since it's a getter
if err != nil {
return false, utils.WrapError("call to permission controller failed", err)
return CanCallResponse{}, utils.WrapError("call to permission controller failed", err)
}
return canCall, nil
return CanCallResponse{CanCall: canCall}, nil
}

// ListAppointees returns the list of appointees of an account
func (r *ChainReader) ListAppointees(
ctx context.Context,
accountAddress gethcommon.Address,
target gethcommon.Address,
selector [4]byte,
) ([]gethcommon.Address, error) {
request AppointeesListRequest,
) (AppointeesResponse, error) {
if r.permissionController == nil {
return AppointeesResponse{}, errors.New("PermissionController contract not provided")
}

appointees, err := r.permissionController.GetAppointees(
&bind.CallOpts{Context: ctx},
accountAddress,
target,
selector,
&bind.CallOpts{Context: ctx, BlockNumber: request.BlockNumber},
request.AccountAddress,
request.TargetAddress,
request.Selector,
)
// This call should not fail since it's a getter
if err != nil {
return nil, utils.WrapError("call to permission controller failed", err)
return AppointeesResponse{}, utils.WrapError("call to permission controller failed", err)
}
return appointees, nil
return AppointeesResponse{Appointees: appointees}, nil
}

// ListAppointeePermissions returns the list of permissions of an appointee
func (r *ChainReader) ListAppointeePermissions(
ctx context.Context,
accountAddress gethcommon.Address,
appointeeAddress gethcommon.Address,
) ([]gethcommon.Address, [][4]byte, error) {
request AppointeePermissionsListRequest,
) (AppointeePermissionsListResponse, error) {
if r.permissionController == nil {
return AppointeePermissionsListResponse{}, errors.New("PermissionController contract not provided")
}

targets, selectors, err := r.permissionController.GetAppointeePermissions(
&bind.CallOpts{Context: ctx},
accountAddress,
appointeeAddress,
&bind.CallOpts{Context: ctx, BlockNumber: request.BlockNumber},
request.AccountAddress,
request.AppointeeAddress,
)
// This call should not fail since it's a getter
if err != nil {
return nil, nil, utils.WrapError("call to permission controller failed", err)
return AppointeePermissionsListResponse{}, utils.WrapError("call to permission controller failed", err)
}
return targets, selectors, nil
return AppointeePermissionsListResponse{TargetAddresses: targets, Selectors: selectors}, nil
}

// ListPendingAdmins returns the list of pending admins of an account
func (r *ChainReader) ListPendingAdmins(
ctx context.Context,
accountAddress gethcommon.Address,
) ([]gethcommon.Address, error) {
pendingAdmins, err := r.permissionController.GetPendingAdmins(&bind.CallOpts{Context: ctx}, accountAddress)
request AccountRequest,
) (PendingAdminsResponse, error) {
if r.permissionController == nil {
return PendingAdminsResponse{}, errors.New("PermissionController contract not provided")
}

pendingAdmins, err := r.permissionController.GetPendingAdmins(
&bind.CallOpts{Context: ctx, BlockNumber: request.BlockNumber},
request.AccountAddress,
)
// This call should not fail since it's a getter
if err != nil {
return nil, utils.WrapError("call to permission controller failed", err)
return PendingAdminsResponse{}, utils.WrapError("call to permission controller failed", err)
}
return pendingAdmins, nil
return PendingAdminsResponse{PendingAdmins: pendingAdmins}, nil
}

// ListAdmins returns the list of admins of an account
func (r *ChainReader) ListAdmins(
ctx context.Context,
accountAddress gethcommon.Address,
) ([]gethcommon.Address, error) {
pendingAdmins, err := r.permissionController.GetAdmins(&bind.CallOpts{Context: ctx}, accountAddress)
request AccountRequest,
) (AdminsResponse, error) {
if r.permissionController == nil {
return AdminsResponse{}, errors.New("PermissionController contract not provided")
}

admins, err := r.permissionController.GetAdmins(
&bind.CallOpts{Context: ctx, BlockNumber: request.BlockNumber},
request.AccountAddress,
)
// This call should not fail since it's a getter
if err != nil {
return nil, utils.WrapError("call to permission controller failed", err)
return AdminsResponse{}, utils.WrapError("call to permission controller failed", err)
}
return pendingAdmins, nil
return AdminsResponse{Admins: admins}, nil
}

// IsPendingAdmin returns if an address is a pending admin of an account
func (r *ChainReader) IsPendingAdmin(
ctx context.Context,
accountAddress gethcommon.Address,
pendingAdminAddress gethcommon.Address,
) (bool, error) {
request PendingAdminCheckRequest,
) (IsPendingAdminResponse, error) {
if r.permissionController == nil {
return IsPendingAdminResponse{}, errors.New("PermissionController contract not provided")
}

isPendingAdmin, err := r.permissionController.IsPendingAdmin(
&bind.CallOpts{Context: ctx},
accountAddress,
pendingAdminAddress,
&bind.CallOpts{Context: ctx, BlockNumber: request.BlockNumber},
request.AccountAddress,
request.PendingAdminAddress,
)
// This call should not fail since it's a getter
if err != nil {
return false, utils.WrapError("call to permission controller failed", err)
return IsPendingAdminResponse{}, utils.WrapError("call to permission controller failed", err)
}
return isPendingAdmin, nil
return IsPendingAdminResponse{IsPendingAdmin: isPendingAdmin}, nil
}

// IsAdmin returns if an address is an admin of an account
func (r *ChainReader) IsAdmin(
ctx context.Context,
accountAddress gethcommon.Address,
adminAddress gethcommon.Address,
) (bool, error) {
isAdmin, err := r.permissionController.IsAdmin(&bind.CallOpts{Context: ctx}, accountAddress, adminAddress)
request AdminCheckRequest,
) (IsAdminResponse, error) {
if r.permissionController == nil {
return IsAdminResponse{}, errors.New("PermissionController contract not provided")
}

isAdmin, err := r.permissionController.IsAdmin(
&bind.CallOpts{Context: ctx, BlockNumber: request.BlockNumber},
request.AccountAddress,
request.AdminAddress,
)
// This call should not fail since it's a getter
if err != nil {
return false, utils.WrapError("call to permission controller failed", err)
return IsAdminResponse{}, utils.WrapError("call to permission controller failed", err)
}
return isAdmin, nil
return IsAdminResponse{IsAdmin: isAdmin}, nil
}
94 changes: 67 additions & 27 deletions chainio/clients/elcontracts/reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -624,15 +624,22 @@ func TestAdminFunctions(t *testing.T) {
assert.NoError(t, err)

t.Run("non-existent pending admin", func(t *testing.T) {
isPendingAdmin, err := chainReader.IsPendingAdmin(context.Background(), operatorAddr, pendingAdminAddr)
pendingAdminRequest := elcontracts.PendingAdminCheckRequest{
AccountAddress: operatorAddr,
PendingAdminAddress: pendingAdminAddr,
}
response, err := chainReader.IsPendingAdmin(context.Background(), pendingAdminRequest)
assert.NoError(t, err)
assert.False(t, isPendingAdmin)
assert.False(t, response.IsPendingAdmin)
})

t.Run("list pending admins when empty", func(t *testing.T) {
listPendingAdmins, err := chainReader.ListPendingAdmins(context.Background(), operatorAddr)
accountRequest := elcontracts.AccountRequest{
AccountAddress: operatorAddr,
}
response, err := chainReader.ListPendingAdmins(context.Background(), accountRequest)
assert.NoError(t, err)
assert.Empty(t, listPendingAdmins)
assert.Empty(t, response.PendingAdmins)
})

t.Run("add pending admin and list", func(t *testing.T) {
Expand All @@ -646,19 +653,30 @@ func TestAdminFunctions(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, receipt.Status, gethtypes.ReceiptStatusSuccessful)

isPendingAdmin, err := chainReader.IsPendingAdmin(context.Background(), operatorAddr, pendingAdminAddr)
pendingAdminRequest := elcontracts.PendingAdminCheckRequest{
AccountAddress: operatorAddr,
PendingAdminAddress: pendingAdminAddr,
}
pendingResponse, err := chainReader.IsPendingAdmin(context.Background(), pendingAdminRequest)
assert.NoError(t, err)
assert.True(t, isPendingAdmin)
assert.True(t, pendingResponse.IsPendingAdmin)

listPendingAdmins, err := chainReader.ListPendingAdmins(context.Background(), operatorAddr)
accountRequest := elcontracts.AccountRequest{
AccountAddress: operatorAddr,
}
pendingAdminResponse, err := chainReader.ListPendingAdmins(context.Background(), accountRequest)
assert.NoError(t, err)
assert.NotEmpty(t, listPendingAdmins)
assert.NotEmpty(t, pendingAdminResponse.PendingAdmins)
})

t.Run("non-existent admin", func(t *testing.T) {
isAdmin, err := chainReader.IsAdmin(context.Background(), operatorAddr, pendingAdminAddr)
adminRequest := elcontracts.AdminCheckRequest{
AccountAddress: operatorAddr,
AdminAddress: pendingAdminAddr,
}
response, err := chainReader.IsAdmin(context.Background(), adminRequest)
assert.NoError(t, err)
assert.False(t, isAdmin)
assert.False(t, response.IsAdmin)
})

t.Run("list admins", func(t *testing.T) {
Expand All @@ -671,14 +689,20 @@ func TestAdminFunctions(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, receipt.Status, gethtypes.ReceiptStatusSuccessful)

listAdmins, err := chainReader.ListAdmins(context.Background(), operatorAddr)
adminsRequest := elcontracts.AccountRequest{
AccountAddress: operatorAddr,
}
adminListResponse, err := chainReader.ListAdmins(context.Background(), adminsRequest)
assert.NoError(t, err)
assert.Len(t, listAdmins, 1)
assert.Len(t, adminListResponse.Admins, 1)

admin := listAdmins[0]
isAdmin, err := chainReader.IsAdmin(context.Background(), operatorAddr, admin)
adminRequest := elcontracts.AdminCheckRequest{
AccountAddress: operatorAddr,
AdminAddress: adminListResponse.Admins[0],
}
adminResponse, err := chainReader.IsAdmin(context.Background(), adminRequest)
assert.NoError(t, err)
assert.True(t, isAdmin)
assert.True(t, adminResponse.IsAdmin)
})
}

Expand Down Expand Up @@ -709,9 +733,14 @@ func TestAppointeesFunctions(t *testing.T) {
selector := [4]byte{0, 1, 2, 3}

t.Run("list appointees when empty", func(t *testing.T) {
appointees, err := chainReader.ListAppointees(context.Background(), accountAddress, target, selector)
appointeesRequest := elcontracts.AppointeesListRequest{
AccountAddress: accountAddress,
TargetAddress: target,
Selector: selector,
}
response, err := chainReader.ListAppointees(context.Background(), appointeesRequest)
assert.NoError(t, err)
assert.Empty(t, appointees)
assert.Empty(t, response.Appointees)
})

t.Run("list appointees", func(t *testing.T) {
Expand All @@ -727,23 +756,34 @@ func TestAppointeesFunctions(t *testing.T) {
require.NoError(t, err)
require.Equal(t, receipt.Status, gethtypes.ReceiptStatusSuccessful)

canCall, err := chainReader.CanCall(context.Background(), accountAddress, appointeeAddress, target, selector)
callRequest := elcontracts.CanCallRequest{
AccountAddress: accountAddress,
AppointeeAddress: appointeeAddress,
Target: target,
Selector: selector,
}
response, err := chainReader.CanCall(context.Background(), callRequest)
require.NoError(t, err)
require.True(t, canCall)
require.True(t, response.CanCall)

appointees, err := chainReader.ListAppointees(context.Background(), accountAddress, target, selector)
appointeesRequest := elcontracts.AppointeesListRequest{
AccountAddress: accountAddress,
TargetAddress: target,
Selector: selector,
}
appointeesResponse, err := chainReader.ListAppointees(context.Background(), appointeesRequest)
assert.NoError(t, err)
assert.NotEmpty(t, appointees)
assert.NotEmpty(t, appointeesResponse.Appointees)
})

t.Run("list appointees permissions", func(t *testing.T) {
appointeesPermission, _, err := chainReader.ListAppointeePermissions(
context.Background(),
accountAddress,
appointeeAddress,
)
request := elcontracts.AppointeePermissionsListRequest{
AccountAddress: accountAddress,
AppointeeAddress: appointeeAddress,
}
response, err := chainReader.ListAppointeePermissions(context.Background(), request)
assert.NoError(t, err)
assert.NotEmpty(t, appointeesPermission)
assert.NotEmpty(t, response.TargetAddresses)
})
}

Expand Down
Loading