Skip to content
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
20 changes: 18 additions & 2 deletions chain_capabilities/stellar/actions/forwarder_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,22 @@ func (fc *forwarderClient) ResolveSigningAccount(ctx context.Context) (string, e
return fc.resolveSigningAccount(ctx)
}

// ValidateSigningAccountAddress verifies the relayer signer is a plain Stellar account
// address suitable for both the forwarder transmitter argument and SubmitTransaction.FromAddress.
func ValidateSigningAccountAddress(accountAddress string) error {
if accountAddress == "" {
return errors.New("relayer returned empty signing account")
}
accountBytes, err := strkey.Decode(strkey.VersionByteAccountID, accountAddress)
if err != nil {
return fmt.Errorf("relayer returned invalid signing account %q: %w", accountAddress, err)
}
if len(accountBytes) != 32 {
return fmt.Errorf("relayer signing account must decode to 32 bytes, got %d", len(accountBytes))
}
return nil
}

func (fc *forwarderClient) InvokeOnReport(
ctx context.Context,
transmitter, receiver string,
Expand Down Expand Up @@ -341,8 +357,8 @@ func (fc *forwarderClient) resolveSigningAccount(ctx context.Context) (string, e
if err != nil {
return "", err
}
if resp.AccountAddress == "" {
return "", errors.New("relayer returned empty signing account")
if err := ValidateSigningAccountAddress(resp.AccountAddress); err != nil {
return "", err
}
return resp.AccountAddress, nil
}
21 changes: 20 additions & 1 deletion chain_capabilities/stellar/actions/forwarder_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"testing"

"github.com/stellar/go-stellar-sdk/strkey"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"

Expand Down Expand Up @@ -61,6 +62,18 @@ func TestForwarderClient_ResolveSigningAccount(t *testing.T) {
require.Error(t, err)
require.Contains(t, err.Error(), "empty signing account")
})

t.Run("invalid signing account type", func(t *testing.T) {
t.Parallel()
svc := mocks.NewStellarService(t)
svc.EXPECT().GetSigningAccount(mock.Anything).
Return(stellartypes.GetSigningAccountResponse{AccountAddress: testReceiverAddress}, nil).Once()
client := newForwarderClient(svc, lggr, testForwarderAddress, 100)

_, err := client.ResolveSigningAccount(t.Context())
require.Error(t, err)
require.Contains(t, err.Error(), "invalid signing account")
})
}

func TestForwarderClient_InvokeOnReport(t *testing.T) {
Expand All @@ -73,7 +86,13 @@ func TestForwarderClient_InvokeOnReport(t *testing.T) {
transmissionID := testTransmissionID()
const maxResourceFee = uint64(100_000)
svc.EXPECT().SubmitTransaction(mock.Anything, mock.MatchedBy(func(req stellartypes.SubmitTransactionRequest) bool {
return req.FromAddress == testNodeAddress &&
if len(req.Args) == 0 || req.Args[0].Address == nil || req.Args[0].Address.AccountID == nil {
return false
}
transmitter, err := strkey.Encode(strkey.VersionByteAccountID, req.Args[0].Address.AccountID)
return err == nil &&
transmitter == testNodeAddress &&
req.FromAddress == transmitter &&
req.IdempotencyKey == transmissionID.idempotencyKey() &&
req.MaxResourceFee == maxResourceFee
})).
Expand Down
6 changes: 5 additions & 1 deletion chain_capabilities/stellar/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,13 @@ func (c *capabilityGRPCService) Initialise(ctx context.Context, dependencies cor
if err != nil {
return fmt.Errorf("failed to get stellar service: %w", err)
}
if _, err = stellarService.GetSigningAccount(ctx); err != nil {
signingAccount, err := stellarService.GetSigningAccount(ctx)
if err != nil {
return fmt.Errorf("stellar relayer has no signing account: %w", err)
}
if err = actions.ValidateSigningAccountAddress(signingAccount.AccountAddress); err != nil {
return fmt.Errorf("stellar relayer has invalid signing account: %w", err)
}

if err = c.setSelector(cfg); err != nil {
return err
Expand Down
Loading