Skip to content

Commit

Permalink
Solana link deploy (B) (#15845)
Browse files Browse the repository at this point in the history
* Adding solchains in NewEnv

* Revert "Adding solchains in NewEnv"

This reverts commit aaab52e.

* adding sol chains to newenv

* newEnv needs to send nil

* adding test env setup

* adding link token deployment and test

* adding nil for crib sol chains

* using switch case

* Adding decimal const

* adding chain selectors commit

* go mod tidy

* linting

* chain sel update

* update core/scripts go files

* again

* add changeset

* go imports

* go mod

* go mod

* go mod tidy

* linting

---------

Co-authored-by: Terry Tata <[email protected]>
  • Loading branch information
yashnevatia and tt-cll authored Jan 9, 2025
1 parent c7759e1 commit b83cc93
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 12 deletions.
76 changes: 68 additions & 8 deletions deployment/common/changeset/deploy_link_token.go
Original file line number Diff line number Diff line change
@@ -1,38 +1,66 @@
package changeset

import (
"errors"
"context"
"fmt"

"github.com/smartcontractkit/chainlink-common/pkg/logger"

"github.com/gagliardetto/solana-go"
solRpc "github.com/gagliardetto/solana-go/rpc"
chainsel "github.com/smartcontractkit/chain-selectors"

solCommomUtil "github.com/smartcontractkit/chainlink-ccip/chains/solana/utils/common"
solTokenUtil "github.com/smartcontractkit/chainlink-ccip/chains/solana/utils/tokens"
"github.com/smartcontractkit/chainlink/deployment"
"github.com/smartcontractkit/chainlink/deployment/common/types"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/link_token"
)

var _ deployment.ChangeSet[[]uint64] = DeployLinkToken

const (
TokenDecimalsSolana = 9
)

// DeployLinkToken deploys a link token contract to the chain identified by the ChainSelector.
func DeployLinkToken(e deployment.Environment, chains []uint64) (deployment.ChangesetOutput, error) {
for _, chain := range chains {
_, ok := e.Chains[chain]
if !ok {
return deployment.ChangesetOutput{}, errors.New("chain not found in environment")
_, evmOk := e.Chains[chain]
_, solOk := e.SolChains[chain]
if !evmOk && !solOk {
return deployment.ChangesetOutput{}, fmt.Errorf("chain %d not found in environment", chain)
}
}
newAddresses := deployment.NewMemoryAddressBook()
for _, chain := range chains {
_, err := deployLinkTokenContract(
e.Logger, e.Chains[chain], newAddresses,
)
family, err := chainsel.GetSelectorFamily(chain)
if err != nil {
return deployment.ChangesetOutput{AddressBook: newAddresses}, err
}
switch family {
case chainsel.FamilyEVM:
// Deploy EVM LINK token
_, err := deployLinkTokenContractEVM(
e.Logger, e.Chains[chain], newAddresses,
)
if err != nil {
return deployment.ChangesetOutput{AddressBook: newAddresses}, err
}
case chainsel.FamilySolana:
// Deploy Solana LINK token
err := deployLinkTokenContractSolana(
e.Logger, e.SolChains[chain], newAddresses,
)
if err != nil {
return deployment.ChangesetOutput{AddressBook: newAddresses}, err
}
}
}
return deployment.ChangesetOutput{AddressBook: newAddresses}, nil
}

func deployLinkTokenContract(
func deployLinkTokenContractEVM(
lggr logger.Logger,
chain deployment.Chain,
ab deployment.AddressBook,
Expand All @@ -57,3 +85,35 @@ func deployLinkTokenContract(
}
return linkToken, nil
}

func deployLinkTokenContractSolana(
lggr logger.Logger,
chain deployment.SolChain,
ab deployment.AddressBook,
) error {
adminPublicKey := chain.DeployerKey.PublicKey()
mint, _ := solana.NewRandomPrivateKey()
// this is the token address
mintPublicKey := mint.PublicKey()
instructions, err := solTokenUtil.CreateToken(
context.Background(), solana.Token2022ProgramID, mintPublicKey, adminPublicKey, TokenDecimalsSolana, chain.Client, solRpc.CommitmentConfirmed,
)
if err != nil {
lggr.Errorw("Failed to generate instructions for link token deployment", "chain", chain.String(), "err", err)
return err
}
err = chain.Confirm(instructions, solCommomUtil.AddSigners(mint))
if err != nil {
lggr.Errorw("Failed to confirm instructions for link token deployment", "chain", chain.String(), "err", err)
return err
}
tv := deployment.NewTypeAndVersion(types.LinkToken, deployment.Version1_0_0)
lggr.Infow("Deployed contract", "Contract", tv.String(), "addr", mintPublicKey.String(), "chain", chain.String())
err = ab.Save(chain.Selector, mintPublicKey.String(), tv)
if err != nil {
lggr.Errorw("Failed to save link token", "chain", chain.String(), "err", err)
return err
}

return nil
}
12 changes: 10 additions & 2 deletions deployment/common/changeset/deploy_link_token_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ func TestDeployLinkToken(t *testing.T) {
t.Parallel()
lggr := logger.TestLogger(t)
e := memory.NewMemoryEnvironment(t, lggr, zapcore.InfoLevel, memory.MemoryEnvironmentConfig{
Chains: 1,
Chains: 1,
SolChains: 1,
})
chain1 := e.AllChainSelectors()[0]
solChain1 := e.AllChainSelectorsSolana()[0]
e, err := changeset.ApplyChangesets(t, e, nil, []changeset.ChangesetApplication{
{
Changeset: changeset.WrapChangeSet(changeset.DeployLinkToken),
Config: []uint64{chain1},
Config: []uint64{chain1, solChain1},
},
})
require.NoError(t, err)
Expand All @@ -32,4 +34,10 @@ func TestDeployLinkToken(t *testing.T) {
// View itself already unit tested
_, err = state.GenerateLinkView()
require.NoError(t, err)

// solana test
addrs, err = e.ExistingAddresses.AddressesForChain(solChain1)
require.NoError(t, err)
require.NotEmpty(t, addrs)

}
1 change: 1 addition & 0 deletions deployment/common/changeset/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ func ApplyChangesets(t *testing.T, e deployment.Environment, timelockContractsPe
Logger: e.Logger,
ExistingAddresses: addresses,
Chains: e.Chains,
SolChains: e.SolChains,
NodeIDs: e.NodeIDs,
Offchain: e.Offchain,
OCRSecrets: e.OCRSecrets,
Expand Down
4 changes: 2 additions & 2 deletions deployment/environment/memory/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,16 @@ func getTestSolanaChainSelectors() []uint64 {
}

func GenerateChainsSol(t *testing.T, numChains int) map[uint64]SolanaChain {
chains := make(map[uint64]SolanaChain)
testSolanaChainSelectors := getTestSolanaChainSelectors()
if len(testSolanaChainSelectors) < numChains {
t.Fatalf("not enough test solana chain selectors available")
}

chains := make(map[uint64]SolanaChain)
for i := 0; i < numChains; i++ {
chainID := testSolanaChainSelectors[i]
url, _ := solTestUtil.SetupLocalSolNodeWithFlags(t)
admin, gerr := solana.NewRandomPrivateKey()
solTestUtil.FundTestAccounts(t, []solana.PublicKey{admin.PublicKey()}, url)
require.NoError(t, gerr)
chains[chainID] = SolanaChain{
Client: solRpc.New(url),
Expand Down

0 comments on commit b83cc93

Please sign in to comment.