-
Notifications
You must be signed in to change notification settings - Fork 105
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
feat: whitelist spl [in progress] #2984
base: develop
Are you sure you want to change the base?
Changes from all commits
0fc857c
059d4d5
4897a2c
b95097a
ff4a594
1c9f482
41ae9b1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
[148,138,110,3,169,253,42,101,79,110,149,110,112,214,41,163,75,28,36,29,241,151,41,200,135,185,252,180,158,191,166,156,119,192,217,18,69,149,119,145,212,43,144,149,176,111,89,140,102,63,193,127,241,148,51,161,170,62,19,196,239,253,6,192] | ||
[170,171,179,164,93,78,137,61,23,64,233,109,110,253,36,57,111,127,55,106,199,85,39,175,73,206,30,244,229,216,101,145,157,23,123,51,143,17,39,82,72,82,114,55,41,2,101,170,230,6,41,179,227,225,43,107,236,186,181,51,118,110,43,227] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package e2etests | ||
|
||
import ( | ||
"github.com/gagliardetto/solana-go" | ||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/zeta-chain/node/e2e/runner" | ||
"github.com/zeta-chain/node/e2e/txserver" | ||
"github.com/zeta-chain/node/e2e/utils" | ||
"github.com/zeta-chain/node/pkg/chains" | ||
crosschaintypes "github.com/zeta-chain/node/x/crosschain/types" | ||
) | ||
|
||
func TestSolanaWhitelistSPL(r *runner.E2ERunner, args []string) { | ||
// Deploy a new SPL | ||
r.Logger.Info("Deploying new SPL") | ||
|
||
// load deployer private key | ||
privkey, err := solana.PrivateKeyFromBase58(r.Account.SolanaPrivateKey.String()) | ||
require.NoError(r, err) | ||
|
||
spl := r.DeploySPL(&privkey) | ||
|
||
// check that whitelist entry doesn't exist for this spl | ||
seed := [][]byte{[]byte("whitelist"), spl.PublicKey().Bytes()} | ||
whitelistEntryPDA, _, err := solana.FindProgramAddress(seed, r.GatewayProgram) | ||
require.NoError(r, err) | ||
|
||
whitelistEntryInfo, err := r.SolanaClient.GetAccountInfo(r.Ctx, whitelistEntryPDA) | ||
require.Error(r, err) | ||
require.Nil(r, whitelistEntryInfo) | ||
|
||
// whitelist sol zrc20 | ||
r.Logger.Info("whitelisting spl on new network") | ||
res, err := r.ZetaTxServer.BroadcastTx(utils.AdminPolicyName, crosschaintypes.NewMsgWhitelistERC20( | ||
r.ZetaTxServer.MustGetAccountAddressFromName(utils.AdminPolicyName), | ||
spl.PublicKey().String(), | ||
chains.SolanaLocalnet.ChainId, | ||
"TESTSPL", | ||
"TESTSPL", | ||
6, | ||
100000, | ||
)) | ||
require.NoError(r, err) | ||
|
||
// retrieve zrc20 and cctx from event | ||
whitelistCCTXIndex, err := txserver.FetchAttributeFromTxResponse(res, "whitelist_cctx_index") | ||
require.NoError(r, err) | ||
|
||
zrc20Addr, err := txserver.FetchAttributeFromTxResponse(res, "zrc20_address") | ||
require.NoError(r, err) | ||
|
||
err = r.ZetaTxServer.InitializeLiquidityCap(zrc20Addr) | ||
require.NoError(r, err) | ||
|
||
// ensure CCTX created | ||
resCCTX, err := r.CctxClient.Cctx(r.Ctx, &crosschaintypes.QueryGetCctxRequest{Index: whitelistCCTXIndex}) | ||
require.NoError(r, err) | ||
|
||
cctx := resCCTX.CrossChainTx | ||
r.Logger.CCTX(*cctx, "whitelist_cctx") | ||
|
||
// wait for the whitelist cctx to be mined | ||
r.WaitForMinedCCTXFromIndex(whitelistCCTXIndex) | ||
|
||
// check that whitelist entry exists for this spl | ||
whitelistEntryInfo, err = r.SolanaClient.GetAccountInfo(r.Ctx, whitelistEntryPDA) | ||
require.NoError(r, err) | ||
require.NotNil(r, whitelistEntryInfo) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,8 @@ import ( | |
|
||
ethcommon "github.com/ethereum/go-ethereum/common" | ||
"github.com/gagliardetto/solana-go" | ||
"github.com/gagliardetto/solana-go/programs/system" | ||
"github.com/gagliardetto/solana-go/programs/token" | ||
"github.com/gagliardetto/solana-go/rpc" | ||
"github.com/near/borsh-go" | ||
"github.com/stretchr/testify/require" | ||
|
@@ -62,6 +64,7 @@ func (r *E2ERunner) CreateDepositInstruction( | |
func (r *E2ERunner) CreateSignedTransaction( | ||
instructions []solana.Instruction, | ||
privateKey solana.PrivateKey, | ||
additionalPrivateKeys []solana.PrivateKey, | ||
) *solana.Transaction { | ||
// get a recent blockhash | ||
recent, err := r.SolanaClient.GetLatestBlockhash(r.Ctx, rpc.CommitmentFinalized) | ||
|
@@ -81,6 +84,11 @@ func (r *E2ERunner) CreateSignedTransaction( | |
if privateKey.PublicKey().Equals(key) { | ||
return &privateKey | ||
} | ||
for _, apk := range additionalPrivateKeys { | ||
if apk.PublicKey().Equals(key) { | ||
return &apk | ||
} | ||
} | ||
return nil | ||
}, | ||
) | ||
|
@@ -89,6 +97,39 @@ func (r *E2ERunner) CreateSignedTransaction( | |
return tx | ||
} | ||
|
||
func (r *E2ERunner) DeploySPL(privateKey *solana.PrivateKey) *solana.Wallet { | ||
lamport, err := r.SolanaClient.GetMinimumBalanceForRentExemption(r.Ctx, token.MINT_SIZE, rpc.CommitmentFinalized) | ||
require.NoError(r, err) | ||
|
||
tokenAccount := solana.NewWallet() | ||
createAccountInstruction := system.NewCreateAccountInstruction( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. using create account and initialize mint instructions in same transaction to create new mint account |
||
lamport, | ||
token.MINT_SIZE, | ||
solana.TokenProgramID, | ||
privateKey.PublicKey(), | ||
tokenAccount.PublicKey(), | ||
).Build() | ||
|
||
initializeMintInstruction := token.NewInitializeMint2Instruction( | ||
6, | ||
privateKey.PublicKey(), | ||
privateKey.PublicKey(), | ||
tokenAccount.PublicKey(), | ||
).Build() | ||
|
||
signedTx := r.CreateSignedTransaction( | ||
[]solana.Instruction{createAccountInstruction, initializeMintInstruction}, | ||
*privateKey, | ||
[]solana.PrivateKey{tokenAccount.PrivateKey}, | ||
) | ||
|
||
// broadcast the transaction and wait for finalization | ||
_, out := r.BroadcastTxSync(signedTx) | ||
r.Logger.Info("create spl logs: %v", out.Meta.LogMessages) | ||
|
||
return tokenAccount | ||
} | ||
|
||
// BroadcastTxSync broadcasts a transaction and waits for it to be finalized | ||
func (r *E2ERunner) BroadcastTxSync(tx *solana.Transaction) (solana.Signature, *rpc.GetTransactionResult) { | ||
// broadcast the transaction | ||
|
@@ -134,7 +175,7 @@ func (r *E2ERunner) SOLDepositAndCall( | |
instruction := r.CreateDepositInstruction(signerPrivKey.PublicKey(), receiver, data, amount.Uint64()) | ||
|
||
// create and sign the transaction | ||
signedTx := r.CreateSignedTransaction([]solana.Instruction{instruction}, *signerPrivKey) | ||
signedTx := r.CreateSignedTransaction([]solana.Instruction{instruction}, *signerPrivKey, []solana.PrivateKey{}) | ||
|
||
// broadcast the transaction and wait for finalization | ||
sig, out := r.BroadcastTxSync(signedTx) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ import ( | |
|
||
const ( | ||
// SolanaGatewayProgramID is the program ID of the Solana gateway program | ||
SolanaGatewayProgramID = "94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d" | ||
SolanaGatewayProgramID = "BaDmykPHVwPQNY9SXQnJU8JPXdN89z3ib7qEfhNfkWRg" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ws4charlie i used |
||
|
||
// PDASeed is the seed for the Solana gateway program derived address | ||
PDASeed = "meta" | ||
|
@@ -43,6 +43,11 @@ func DiscriminatorWithdrawSPL() [8]byte { | |
return [8]byte{156, 234, 11, 89, 235, 246, 32} | ||
} | ||
|
||
// DiscriminatorWhitelist returns the discriminator for Solana gateway 'whitelist_spl_mint' instruction | ||
func DiscriminatorWhitelistSplMint() [8]byte { | ||
return [8]byte{30, 110, 162, 42, 208, 147, 254, 219} | ||
} | ||
|
||
// ParseGatewayAddressAndPda parses the gateway id and program derived address from the given string | ||
func ParseGatewayIDAndPda(address string) (solana.PublicKey, solana.PublicKey, error) { | ||
var gatewayID, pda solana.PublicKey | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ws4charlie solana relayer and deployer used in e2e tests are different, and with recent introduction of using deployer as authority for whitelist (and other messages), is it ok to use same account here, or maybe we can add new key for zetaclient?