-
Notifications
You must be signed in to change notification settings - Fork 108
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add relayer_key_balance metrics and unit tests
- Loading branch information
1 parent
6a64051
commit 66b7027
Showing
10 changed files
with
326 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package crypto | ||
|
||
import ( | ||
fmt "fmt" | ||
|
||
"github.com/gagliardetto/solana-go" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
// SolanaPrivateKeyFromString converts a base58 encoded private key to a solana.PrivateKey | ||
func SolanaPrivateKeyFromString(privKeyBase58 string) (*solana.PrivateKey, error) { | ||
privateKey, err := solana.PrivateKeyFromBase58(privKeyBase58) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "invalid base58 private key") | ||
} | ||
|
||
// Solana private keys are 64 bytes long | ||
if len(privateKey) != 64 { | ||
return nil, fmt.Errorf("invalid private key length: %d", len(privateKey)) | ||
} | ||
|
||
return &privateKey, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package crypto_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/gagliardetto/solana-go" | ||
"github.com/stretchr/testify/require" | ||
"github.com/zeta-chain/zetacore/pkg/crypto" | ||
) | ||
|
||
func Test_IsValidSolanaPrivateKey(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
input string | ||
output *solana.PrivateKey | ||
errMsg string | ||
}{ | ||
{ | ||
name: "valid private key", | ||
input: "3EMjCcCJg53fMEGVj13UPQpo6py9AKKyLE2qroR4yL1SvAN2tUznBvDKRYjntw7m6Jof1R2CSqjTddL27rEb6sFQ", | ||
output: func() *solana.PrivateKey { | ||
privKey, _ := solana.PrivateKeyFromBase58( | ||
"3EMjCcCJg53fMEGVj13UPQpo6py9AKKyLE2qroR4yL1SvAN2tUznBvDKRYjntw7m6Jof1R2CSqjTddL27rEb6sFQ", | ||
) | ||
return &privKey | ||
}(), | ||
}, | ||
{ | ||
name: "invalid private key - too short", | ||
input: "oR4yL1SvAN2tUznBvDKRYjntw7m6Jof1R2CSqjTddL27rEb6sFQ", | ||
output: nil, | ||
errMsg: "invalid private key length: 38", | ||
}, | ||
{ | ||
name: "invalid private key - too long", | ||
input: "3EMjCcCJg53fMEGVj13UPQpo6py9AKKyLE2qroR4yL1SvAN2tUznBvDKRYjntw7m6Jof1R2CSqjTddL27rEb6sFQdJ", | ||
output: nil, | ||
errMsg: "invalid private key length: 66", | ||
}, | ||
{ | ||
name: "invalid private key - bad base58 encoding", | ||
input: "!!!InvalidBase58!!!", | ||
output: nil, | ||
errMsg: "invalid base58 private key", | ||
}, | ||
{ | ||
name: "invalid private key - empty string", | ||
input: "", | ||
output: nil, | ||
errMsg: "invalid base58 private key", | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
result, err := crypto.SolanaPrivateKeyFromString(tt.input) | ||
if tt.errMsg != "" { | ||
require.ErrorContains(t, err, tt.errMsg) | ||
require.Nil(t, result) | ||
return | ||
} | ||
|
||
require.NoError(t, err) | ||
require.Equal(t, tt.output.String(), result.String()) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
package signer_test | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"testing" | ||
|
||
"github.com/gagliardetto/solana-go/rpc" | ||
"github.com/prometheus/client_golang/prometheus/testutil" | ||
"github.com/stretchr/testify/mock" | ||
"github.com/stretchr/testify/require" | ||
"github.com/zeta-chain/zetacore/pkg/chains" | ||
"github.com/zeta-chain/zetacore/testutil/sample" | ||
observertypes "github.com/zeta-chain/zetacore/x/observer/types" | ||
"github.com/zeta-chain/zetacore/zetaclient/chains/base" | ||
"github.com/zeta-chain/zetacore/zetaclient/chains/interfaces" | ||
"github.com/zeta-chain/zetacore/zetaclient/chains/solana/signer" | ||
"github.com/zeta-chain/zetacore/zetaclient/keys" | ||
"github.com/zeta-chain/zetacore/zetaclient/metrics" | ||
"github.com/zeta-chain/zetacore/zetaclient/testutils" | ||
"github.com/zeta-chain/zetacore/zetaclient/testutils/mocks" | ||
) | ||
|
||
func Test_NewSigner(t *testing.T) { | ||
// test parameters | ||
chain := chains.SolanaDevnet | ||
chainParams := sample.ChainParams(chain.ChainId) | ||
chainParams.GatewayAddress = testutils.GatewayAddresses[chain.ChainId] | ||
|
||
tests := []struct { | ||
name string | ||
chain chains.Chain | ||
chainParams observertypes.ChainParams | ||
solClient interfaces.SolanaRPCClient | ||
tss interfaces.TSSSigner | ||
relayerKey *keys.RelayerKey | ||
ts *metrics.TelemetryServer | ||
logger base.Logger | ||
errMessage string | ||
}{ | ||
{ | ||
name: "should create solana signer successfully with relayer key", | ||
chain: chain, | ||
chainParams: *chainParams, | ||
solClient: nil, | ||
tss: nil, | ||
relayerKey: &keys.RelayerKey{ | ||
PrivateKey: "3EMjCcCJg53fMEGVj13UPQpo6py9AKKyLE2qroR4yL1SvAN2tUznBvDKRYjntw7m6Jof1R2CSqjTddL27rEb6sFQ", | ||
}, | ||
ts: nil, | ||
logger: base.DefaultLogger(), | ||
}, | ||
{ | ||
name: "should create solana signer successfully without relayer key", | ||
chainParams: *chainParams, | ||
solClient: nil, | ||
tss: nil, | ||
relayerKey: nil, | ||
ts: nil, | ||
logger: base.DefaultLogger(), | ||
}, | ||
{ | ||
name: "should fail to create solana signer with invalid gateway address", | ||
chainParams: func() observertypes.ChainParams { | ||
cp := *chainParams | ||
cp.GatewayAddress = "invalid" | ||
return cp | ||
}(), | ||
solClient: nil, | ||
tss: nil, | ||
relayerKey: nil, | ||
ts: nil, | ||
logger: base.DefaultLogger(), | ||
errMessage: "cannot parse gateway address", | ||
}, | ||
{ | ||
name: "should fail to create solana signer with invalid relayer key", | ||
chainParams: *chainParams, | ||
solClient: nil, | ||
tss: nil, | ||
relayerKey: &keys.RelayerKey{ | ||
PrivateKey: "3EMjCcCJg53fMEGVj13", // too short | ||
}, | ||
ts: nil, | ||
logger: base.DefaultLogger(), | ||
errMessage: "unable to construct solana private key", | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
s, err := signer.NewSigner(tt.chain, tt.chainParams, tt.solClient, tt.tss, tt.relayerKey, tt.ts, tt.logger) | ||
if tt.errMessage != "" { | ||
require.ErrorContains(t, err, tt.errMessage) | ||
require.Nil(t, s) | ||
return | ||
} | ||
|
||
require.NoError(t, err) | ||
require.NotNil(t, s) | ||
}) | ||
} | ||
} | ||
|
||
func Test_SetRelayerBalanceMetrics(t *testing.T) { | ||
// test parameters | ||
chain := chains.SolanaDevnet | ||
chainParams := sample.ChainParams(chain.ChainId) | ||
chainParams.GatewayAddress = testutils.GatewayAddresses[chain.ChainId] | ||
relayerKey := &keys.RelayerKey{ | ||
PrivateKey: "3EMjCcCJg53fMEGVj13UPQpo6py9AKKyLE2qroR4yL1SvAN2tUznBvDKRYjntw7m6Jof1R2CSqjTddL27rEb6sFQ", | ||
} | ||
ctx := context.Background() | ||
|
||
// mock solana client with RPC error | ||
mckClient := mocks.NewSolanaRPCClient(t) | ||
mckClient.On("GetBalance", mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.New("rpc error")) | ||
|
||
// create signer and set relayer balance metrics | ||
s, err := signer.NewSigner(chain, *chainParams, mckClient, nil, relayerKey, nil, base.DefaultLogger()) | ||
require.NoError(t, err) | ||
s.SetRelayerBalanceMetrics(ctx) | ||
|
||
// assert that relayer key balance metrics is not set (due to RPC error) | ||
balance := testutil.ToFloat64(metrics.RelayerKeyBalance.WithLabelValues(chain.Name)) | ||
require.Equal(t, 0.0, balance) | ||
|
||
// mock solana client with balance | ||
mckClient = mocks.NewSolanaRPCClient(t) | ||
mckClient.On("GetBalance", mock.Anything, mock.Anything, mock.Anything).Return(&rpc.GetBalanceResult{ | ||
Value: 123400000, | ||
}, nil) | ||
|
||
// create signer and set relayer balance metrics again | ||
s, err = signer.NewSigner(chain, *chainParams, mckClient, nil, relayerKey, nil, base.DefaultLogger()) | ||
require.NoError(t, err) | ||
s.SetRelayerBalanceMetrics(ctx) | ||
|
||
// assert that relayer key balance metrics is set correctly | ||
balance = testutil.ToFloat64(metrics.RelayerKeyBalance.WithLabelValues(chain.Name)) | ||
require.Equal(t, 0.1234, balance) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.