Skip to content

Commit

Permalink
clean commit history
Browse files Browse the repository at this point in the history
  • Loading branch information
tt-cll committed Feb 1, 2025
1 parent f791bf9 commit 527bd52
Show file tree
Hide file tree
Showing 8 changed files with 444 additions and 29 deletions.
12 changes: 9 additions & 3 deletions deployment/ccip/changeset/cs_chain_contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -1615,15 +1615,21 @@ func isOCR3ConfigSetOnOffRamp(

// DefaultFeeQuoterDestChainConfig returns the default FeeQuoterDestChainConfig
// with the config enabled/disabled based on the configEnabled flag.
func DefaultFeeQuoterDestChainConfig(configEnabled bool) fee_quoter.FeeQuoterDestChainConfig {
func DefaultFeeQuoterDestChainConfig(configEnabled bool, destChainSelector ...uint64) fee_quoter.FeeQuoterDestChainConfig {
// https://github.com/smartcontractkit/ccip/blob/c4856b64bd766f1ddbaf5d13b42d3c4b12efde3a/contracts/src/v0.8/ccip/libraries/Internal.sol#L337-L337
/*
```Solidity
// bytes4(keccak256("CCIP ChainFamilySelector EVM"))
bytes4 public constant CHAIN_FAMILY_SELECTOR_EVM = 0x2812d52c;
```
*/
evmFamilySelector, _ := hex.DecodeString("2812d52c")
familySelector, _ := hex.DecodeString("2812d52c") // evm
if len(destChainSelector) > 0 {
destFamily, _ := chain_selectors.GetSelectorFamily(destChainSelector[0])
if destFamily == chain_selectors.FamilySolana {
familySelector, _ = hex.DecodeString("1e10bdc4") // solana
}
}
return fee_quoter.FeeQuoterDestChainConfig{
IsEnabled: configEnabled,
MaxNumberOfTokensPerMsg: 10,
Expand All @@ -1641,6 +1647,6 @@ func DefaultFeeQuoterDestChainConfig(configEnabled bool) fee_quoter.FeeQuoterDes
DefaultTxGasLimit: 200_000,
GasMultiplierWeiPerEth: 11e17, // Gas multiplier in wei per eth is scaled by 1e18, so 11e17 is 1.1 = 110%
NetworkFeeUSDCents: 1,
ChainFamilySelector: [4]byte(evmFamilySelector),
ChainFamilySelector: [4]byte(familySelector),
}
}
1 change: 1 addition & 0 deletions deployment/ccip/changeset/cs_deploy_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,7 @@ func deployChainContractsSolana(
solana.TokenProgramID,
solana.SPLAssociatedTokenAccountProgramID,
})
// TODO: can we use solCommonUtil.AwaitSlotChange here?
if err != nil {
return fmt.Errorf("failed to create lookup table: %w", err)
}
Expand Down
137 changes: 134 additions & 3 deletions deployment/ccip/changeset/solana/cs_chain_contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func commonValidation(e deployment.Environment, selector uint64, tokenPubKey sol

func validateRouterConfig(chain deployment.SolChain, chainState cs.SolCCIPChainState) error {
if chainState.Router.IsZero() {
return fmt.Errorf("router not found in existing state, deploy the router first chain %d", chain.Selector)
return fmt.Errorf("router not found in existing state, deploy the router first for chain %d", chain.Selector)
}
// addressing errcheck in the next PR
var routerConfigAccount solRouter.Config
Expand Down Expand Up @@ -421,10 +421,10 @@ func AddTokenPool(e deployment.Environment, cfg TokenPoolConfig) (deployment.Cha
tokenprogramID,
poolSigner,
tokenPubKey,
chain.DeployerKey.PublicKey(),
authorityPubKey,
)
if err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("failed to generate instructions: %w", err)
return deployment.ChangesetOutput{}, err
}
instructions := []solana.Instruction{createI, poolInitI, authI}

Expand Down Expand Up @@ -926,3 +926,134 @@ func AcceptAdminRoleTokenAdminRegistry(e deployment.Environment, cfg AcceptAdmin
// Update look up tables with tokens and pools
// Set Pool (https://smartcontract-it.atlassian.net/browse/INTAUTO-437)
// NewAppendRemotePoolAddressesInstruction (https://smartcontract-it.atlassian.net/browse/INTAUTO-436)

type SetPoolConfig struct {
ChainSelector uint64
TokenPubKey string
TokenAdminRegistryAdminPrivateKey string
PoolLookupTable string
WritableIndexes []uint8
}

func (cfg SetPoolConfig) Validate(e deployment.Environment) error {
tokenPubKey := solana.MustPublicKeyFromBase58(cfg.TokenPubKey)
if err := commonValidation(e, cfg.ChainSelector, tokenPubKey); err != nil {
return err
}
state, _ := cs.LoadOnchainState(e)
chainState := state.SolChains[cfg.ChainSelector]
chain := e.SolChains[cfg.ChainSelector]
if chainState.TokenPool.IsZero() {
return fmt.Errorf("token pool not found in existing state, deploy the token pool first for chain %d", cfg.ChainSelector)
}
if err := validateRouterConfig(chain, chainState); err != nil {
return err
}
tokenAdminRegistryPDA, _, err := solState.FindTokenAdminRegistryPDA(tokenPubKey, chainState.Router)
if err != nil {
return fmt.Errorf("failed to find token admin registry pda (mint: %s, router: %s): %w", tokenPubKey.String(), chainState.Router.String(), err)
}
var tokenAdminRegistryAccount solRouter.TokenAdminRegistry
if err := chain.GetAccountDataBorshInto(context.Background(), tokenAdminRegistryPDA, &tokenAdminRegistryAccount); err != nil {
return fmt.Errorf("token admin registry not found for (mint: %s, router: %s), cannot set pool", tokenPubKey.String(), chainState.Router.String())
}
return nil
}

// this sets the writable indexes of the token pool lookup table
func SetPool(e deployment.Environment, cfg SetPoolConfig) (deployment.ChangesetOutput, error) {
if err := cfg.Validate(e); err != nil {
return deployment.ChangesetOutput{}, err
}

chain := e.SolChains[cfg.ChainSelector]
state, _ := cs.LoadOnchainState(e)
chainState := state.SolChains[cfg.ChainSelector]
tokenPubKey := solana.MustPublicKeyFromBase58(cfg.TokenPubKey)
routerConfigPDA, _, _ := solState.FindConfigPDA(chainState.Router)
tokenAdminRegistryPDA, _, _ := solState.FindTokenAdminRegistryPDA(tokenPubKey, chainState.Router)
tokenAdminRegistryAdminPrivKey := solana.MustPrivateKeyFromBase58(cfg.TokenAdminRegistryAdminPrivateKey)
lookupTablePubKey := solana.MustPublicKeyFromBase58(cfg.PoolLookupTable)

base := solRouter.NewSetPoolInstruction(
tokenPubKey,
cfg.WritableIndexes,
routerConfigPDA,
tokenAdminRegistryPDA,
lookupTablePubKey,
tokenAdminRegistryAdminPrivKey.PublicKey(),
)

base.AccountMetaSlice = append(base.AccountMetaSlice, solana.Meta(lookupTablePubKey))
instruction, err := base.ValidateAndBuild()
if err != nil {
return deployment.ChangesetOutput{}, err
}

instructions := []solana.Instruction{instruction}
err = chain.Confirm(instructions, solCommonUtil.AddSigners(tokenAdminRegistryAdminPrivKey))
if err != nil {
return deployment.ChangesetOutput{}, err
}
return deployment.ChangesetOutput{}, nil
}

type TokenPoolLookupTableConfig struct {
ChainSelector uint64
TokenPubKey string
TokenProgram string // this can go as a address book tag
}

func (cfg TokenPoolLookupTableConfig) Validate(e deployment.Environment) error {
tokenPubKey := solana.MustPublicKeyFromBase58(cfg.TokenPubKey)
if err := commonValidation(e, cfg.ChainSelector, tokenPubKey); err != nil {

Check failure on line 1009 in deployment/ccip/changeset/solana/cs_chain_contracts.go

View workflow job for this annotation

GitHub Actions / GolangCI Lint (deployment)

if-return: redundant if ...; err != nil check, just return error instead. (revive)
return err
}
return nil
}

func AddTokenPoolLookupTable(e deployment.Environment, cfg TokenPoolLookupTableConfig) (deployment.ChangesetOutput, error) {
if err := cfg.Validate(e); err != nil {
return deployment.ChangesetOutput{}, err
}
chain := e.SolChains[cfg.ChainSelector]
// pool lookup table
// the last arg is the private key of the authority
ctx := e.GetContext()
client := chain.Client
state, _ := cs.LoadOnchainState(e)
chainState := state.SolChains[cfg.ChainSelector]
authorityPrivKey := chain.DeployerKey
tokenPubKey := solana.MustPublicKeyFromBase58(cfg.TokenPubKey)

tokenAdminRegistryPDA, _, _ := solState.FindTokenAdminRegistryPDA(tokenPubKey, chainState.Router)
tokenPoolChainConfigPDA, _ := solTokenUtil.TokenPoolConfigAddress(tokenPubKey, chainState.Router)
tokenPoolSigner, _ := solTokenUtil.TokenPoolSignerAddress(tokenPubKey, chainState.Router)
tokenProgram, _ := GetTokenProgramID(cfg.TokenProgram)
poolTokenAccount, _, _ := solana.FindAssociatedTokenAddress(tokenPoolSigner, tokenPubKey)
feeTokenConfigPDA, _, _ := solState.FindFeeBillingTokenConfigPDA(tokenPubKey, chainState.Router)

// TODO: this needs to be saved in the addressbook, its not derivable
table, err := solCommonUtil.CreateLookupTable(ctx, client, *authorityPrivKey)
if err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("failed to create lookup table for token pool (mint: %s): %w", tokenPubKey.String(), err)
}
list := solana.PublicKeySlice{
table, // 0
tokenAdminRegistryPDA, // 1
chainState.TokenPool, // 2
tokenPoolChainConfigPDA, // 3 - writable
poolTokenAccount, // 4 - writable
tokenPoolSigner, // 5
tokenProgram, // 6
tokenPubKey, // 7 - writable
feeTokenConfigPDA, // 8
}
if err = solCommonUtil.ExtendLookupTable(ctx, client, table, *authorityPrivKey, list); err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("failed to extend lookup table for token pool (mint: %s): %w", tokenPubKey.String(), err)
}
if err := solCommonUtil.AwaitSlotChange(ctx, client); err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("failed to await slot change while extending lookup table: %w", err)
}
return deployment.ChangesetOutput{}, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ func TestAddTokenPool(t *testing.T) {
RemoteChainSelector: evmChain,
TokenPubKey: tokenAddress.String(),
RemoteConfig: token_pool.RemoteConfig{
// this can be potentially read from the state if we are given the token symbol
PoolAddresses: []token_pool.RemoteAddress{{Address: []byte{1, 2, 3}}},
TokenAddress: token_pool.RemoteAddress{Address: []byte{4, 5, 6}},
Decimals: 9,
Expand Down
6 changes: 4 additions & 2 deletions deployment/ccip/changeset/solana/cs_solana_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ var _ deployment.ChangeSet[DeploySolanaTokenConfig] = DeploySolanaToken
var _ deployment.ChangeSet[MintSolanaTokenConfig] = MintSolanaToken
var _ deployment.ChangeSet[CreateSolanaTokenATAConfig] = CreateSolanaTokenATA

// TODO: add option to set token mint authority by taking in its public key
// might need to take is private key if it needs to sign that
type DeploySolanaTokenConfig struct {
ChainSelector uint64
TokenProgramName string
Expand All @@ -27,7 +29,7 @@ func NewTokenInstruction(chain deployment.SolChain, cfg DeploySolanaTokenConfig)
if err != nil {
return nil, nil, err
}
tokenAdminPubKey := chain.DeployerKey.PublicKey()
tokenAdminPubKey := chain.DeployerKey.PublicKey() // token mint authority
mint, _ := solana.NewRandomPrivateKey()
mintPublicKey := mint.PublicKey() // this is the token address
instructions, err := solTokenUtil.CreateToken(
Expand All @@ -54,7 +56,7 @@ func DeploySolanaToken(e deployment.Environment, cfg DeploySolanaTokenConfig) (d
if err != nil {
return deployment.ChangesetOutput{}, err
}

// do i need to add the mint as a signer here ?
err = chain.Confirm(instructions, solCommomUtil.AddSigners(mint))
if err != nil {
e.Logger.Errorw("Failed to confirm instructions for link token deployment", "chain", chain.String(), "err", err)
Expand Down
65 changes: 65 additions & 0 deletions deployment/ccip/changeset/solana/cs_solana_token_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,68 @@ func TestSolanaTokenOps(t *testing.T) {
func TestDeployLinkToken(t *testing.T) {
testhelpers.DeployLinkTokenTest(t, 1)
}

func TestSolanaTokenBalance(t *testing.T) {
t.Parallel()
lggr := logger.TestLogger(t)
e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{
SolChains: 1,
})
solChain1 := e.AllChainSelectorsSolana()[0]
e, err := commonchangeset.ApplyChangesets(t, e, nil, []commonchangeset.ChangesetApplication{
{
Changeset: commonchangeset.WrapChangeSet(changeset_solana.DeploySolanaToken),
Config: changeset_solana.DeploySolanaTokenConfig{
ChainSelector: solChain1,
TokenProgramName: deployment.SPL2022Tokens,
TokenDecimals: 9,
},
},
})
require.NoError(t, err)

state, err := ccipChangeset.LoadOnchainStateSolana(e)
require.NoError(t, err)
tokenAddress := state.SolChains[solChain1].SPL2022Tokens[0]
deployerKey := e.SolChains[solChain1].DeployerKey.PublicKey()
// testUser, _ := solana.NewRandomPrivateKey()
// testUserPubKey := testUser.PublicKey()

e, err = changeset.ApplyChangesets(t, e, nil, []changeset.ChangesetApplication{
{
Changeset: changeset.WrapChangeSet(changeset_solana.CreateSolanaTokenATA),
Config: changeset_solana.CreateSolanaTokenATAConfig{
ChainSelector: solChain1,
TokenPubkey: tokenAddress,
TokenProgram: deployment.SPL2022Tokens,
ATAList: []string{deployerKey.String()},
// ATAList: []string{testUserPubKey.String()},
},
},
{
Changeset: commonchangeset.WrapChangeSet(changeset_solana.MintSolanaToken),
Config: changeset_solana.MintSolanaTokenConfig{
ChainSelector: solChain1,
TokenPubkey: tokenAddress,
TokenProgram: deployment.SPL2022Tokens,
AmountToAddress: map[string]uint64{
deployerKey.String(): uint64(1000),
},
},
},
})
require.NoError(t, err)

// ata, _, _ := solTokenUtil.FindAssociatedTokenAddress(solana.Token2022ProgramID, tokenAddress, testUserPubKey)
ata, _, _ := solTokenUtil.FindAssociatedTokenAddress(
solana.Token2022ProgramID,
tokenAddress,
e.SolChains[solChain1].DeployerKey.PublicKey(),
)

outDec, outVal, err := solTokenUtil.TokenBalance(context.Background(), e.SolChains[solChain1].Client, ata, solRpc.CommitmentConfirmed)
require.NoError(t, err)
t.Logf("outDec: %d, outVal: %d", outDec, outVal)
// require.Equal(t, int(1000), outVal)
// require.Equal(t, 9, int(outDec))
}
Loading

0 comments on commit 527bd52

Please sign in to comment.