Implement upgradeability (#151)
* Implement contract upgrade VAA action * naming and (╯°□°)╯︵ ┻━┻ * Carefully unflip table and replace broken cutlery ┬─┬ノ( ◕◡◕ ノ) * fix and automate upgradeability * document contract upgrade call * Update comments * Exhaustiveness check in VAA payload switch * Fix typo Co-authored-by: Leo <leo@certus.one>
This commit is contained in:
parent
ad9e8cc45b
commit
efa03ef73c
|
@ -26,8 +26,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
AdminCmd.AddCommand(AdminClientInjectGuardianSetUpdateCmd)
|
AdminCmd.AddCommand(AdminClientInjectGuardianSetUpdateCmd)
|
||||||
AdminCmd.AddCommand(AdminClientGuardianSetTemplateCmd)
|
AdminCmd.AddCommand(AdminClientGovernanceVAAVerifyCmd)
|
||||||
AdminCmd.AddCommand(AdminClientGuardianSetVerifyCmd)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var AdminCmd = &cobra.Command{
|
var AdminCmd = &cobra.Command{
|
||||||
|
@ -36,9 +35,9 @@ var AdminCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
|
|
||||||
var AdminClientInjectGuardianSetUpdateCmd = &cobra.Command{
|
var AdminClientInjectGuardianSetUpdateCmd = &cobra.Command{
|
||||||
Use: "guardian-set-update-inject",
|
Use: "governance-vaa-inject",
|
||||||
Short: "Inject and sign a guardian set update from a prototxt file (see docs!)",
|
Short: "Inject and sign a governance VAA from a prototxt file (see docs!)",
|
||||||
Run: runInjectGuardianSetUpdate,
|
Run: runInjectGovernanceVAA,
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +52,7 @@ func getAdminClient(ctx context.Context, addr string) (*grpc.ClientConn, error,
|
||||||
return conn, err, c
|
return conn, err, c
|
||||||
}
|
}
|
||||||
|
|
||||||
func runInjectGuardianSetUpdate(cmd *cobra.Command, args []string) {
|
func runInjectGovernanceVAA(cmd *cobra.Command, args []string) {
|
||||||
path := args[0]
|
path := args[0]
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
@ -66,15 +65,15 @@ func runInjectGuardianSetUpdate(cmd *cobra.Command, args []string) {
|
||||||
log.Fatalf("failed to read file: %v", err)
|
log.Fatalf("failed to read file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var msg nodev1.GuardianSetUpdate
|
var msg nodev1.InjectGovernanceVAARequest
|
||||||
err = prototext.Unmarshal(b, &msg)
|
err = prototext.Unmarshal(b, &msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to deserialize: %v", err)
|
log.Fatalf("failed to deserialize: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.SubmitGuardianSetVAA(ctx, &nodev1.SubmitGuardianSetVAARequest{GuardianSet: &msg})
|
resp, err := c.InjectGovernanceVAA(ctx, &msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to submit guardian set update: %v", err)
|
log.Fatalf("failed to submit governance VAA: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("VAA successfully injected with digest %s", hexutils.BytesToHex(resp.Digest))
|
log.Printf("VAA successfully injected with digest %s", hexutils.BytesToHex(resp.Digest))
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
@ -28,7 +29,7 @@ type nodePrivilegedService struct {
|
||||||
|
|
||||||
// adminGuardianSetUpdateToVAA converts a nodev1.GuardianSetUpdate message to its canonical VAA representation.
|
// adminGuardianSetUpdateToVAA converts a nodev1.GuardianSetUpdate message to its canonical VAA representation.
|
||||||
// Returns an error if the data is invalid.
|
// Returns an error if the data is invalid.
|
||||||
func adminGuardianSetUpdateToVAA(req *nodev1.GuardianSetUpdate) (*vaa.VAA, error) {
|
func adminGuardianSetUpdateToVAA(req *nodev1.GuardianSetUpdate, guardianSetIndex uint32, timestamp uint32) (*vaa.VAA, error) {
|
||||||
if len(req.Guardians) == 0 {
|
if len(req.Guardians) == 0 {
|
||||||
return nil, errors.New("empty guardian set specified")
|
return nil, errors.New("empty guardian set specified")
|
||||||
}
|
}
|
||||||
|
@ -48,21 +49,59 @@ func adminGuardianSetUpdateToVAA(req *nodev1.GuardianSetUpdate) (*vaa.VAA, error
|
||||||
|
|
||||||
v := &vaa.VAA{
|
v := &vaa.VAA{
|
||||||
Version: vaa.SupportedVAAVersion,
|
Version: vaa.SupportedVAAVersion,
|
||||||
GuardianSetIndex: req.CurrentSetIndex,
|
GuardianSetIndex: guardianSetIndex,
|
||||||
Timestamp: time.Unix(int64(req.Timestamp), 0),
|
Timestamp: time.Unix(int64(timestamp), 0),
|
||||||
Payload: &vaa.BodyGuardianSetUpdate{
|
Payload: &vaa.BodyGuardianSetUpdate{
|
||||||
Keys: addrs,
|
Keys: addrs,
|
||||||
NewIndex: req.CurrentSetIndex + 1,
|
NewIndex: guardianSetIndex + 1,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *nodePrivilegedService) SubmitGuardianSetVAA(ctx context.Context, req *nodev1.SubmitGuardianSetVAARequest) (*nodev1.SubmitGuardianSetVAAResponse, error) {
|
// adminContractUpgradeToVAA converts a nodev1.ContractUpgrade message to its canonical VAA representation.
|
||||||
s.logger.Info("guardian set injected via admin socket", zap.String("request", req.String()))
|
// Returns an error if the data is invalid.
|
||||||
|
func adminContractUpgradeToVAA(req *nodev1.ContractUpgrade, guardianSetIndex uint32, timestamp uint32) (*vaa.VAA, error) {
|
||||||
|
if len(req.NewContract) != 32 {
|
||||||
|
return nil, errors.New("invalid new_contract address")
|
||||||
|
}
|
||||||
|
|
||||||
v, err := adminGuardianSetUpdateToVAA(req.GuardianSet)
|
if req.ChainId > math.MaxUint8 {
|
||||||
|
return nil, errors.New("invalid chain_id")
|
||||||
|
}
|
||||||
|
|
||||||
|
newContractAddress := vaa.Address{}
|
||||||
|
copy(newContractAddress[:], req.NewContract)
|
||||||
|
|
||||||
|
v := &vaa.VAA{
|
||||||
|
Version: vaa.SupportedVAAVersion,
|
||||||
|
GuardianSetIndex: guardianSetIndex,
|
||||||
|
Timestamp: time.Unix(int64(timestamp), 0),
|
||||||
|
Payload: &vaa.BodyContractUpgrade{
|
||||||
|
ChainID: uint8(req.ChainId),
|
||||||
|
NewContract: newContractAddress,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *nodePrivilegedService) InjectGovernanceVAA(ctx context.Context, req *nodev1.InjectGovernanceVAARequest) (*nodev1.InjectGovernanceVAAResponse, error) {
|
||||||
|
s.logger.Info("governance VAA injected via admin socket", zap.String("request", req.String()))
|
||||||
|
|
||||||
|
var (
|
||||||
|
v *vaa.VAA
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
switch payload := req.Payload.(type) {
|
||||||
|
case *nodev1.InjectGovernanceVAARequest_GuardianSet:
|
||||||
|
v, err = adminGuardianSetUpdateToVAA(payload.GuardianSet, req.CurrentSetIndex, req.Timestamp)
|
||||||
|
case *nodev1.InjectGovernanceVAARequest_ContractUpgrade:
|
||||||
|
v, err = adminContractUpgradeToVAA(payload.ContractUpgrade, req.CurrentSetIndex, req.Timestamp)
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("unsupported VAA type: %T", payload))
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||||
}
|
}
|
||||||
|
@ -73,14 +112,14 @@ func (s *nodePrivilegedService) SubmitGuardianSetVAA(ctx context.Context, req *n
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.logger.Info("guardian set VAA constructed",
|
s.logger.Info("governance VAA constructed",
|
||||||
zap.Any("vaa", v),
|
zap.Any("vaa", v),
|
||||||
zap.String("digest", digest.String()),
|
zap.String("digest", digest.String()),
|
||||||
)
|
)
|
||||||
|
|
||||||
s.injectC <- v
|
s.injectC <- v
|
||||||
|
|
||||||
return &nodev1.SubmitGuardianSetVAAResponse{Digest: digest.Bytes()}, nil
|
return &nodev1.InjectGovernanceVAAResponse{Digest: digest.Bytes()}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func adminServiceRunnable(logger *zap.Logger, socketPath string, injectC chan<- *vaa.VAA) (supervisor.Runnable, error) {
|
func adminServiceRunnable(logger *zap.Logger, socketPath string, injectC chan<- *vaa.VAA) (supervisor.Runnable, error) {
|
||||||
|
|
|
@ -13,27 +13,42 @@ import (
|
||||||
nodev1 "github.com/certusone/wormhole/bridge/pkg/proto/node/v1"
|
nodev1 "github.com/certusone/wormhole/bridge/pkg/proto/node/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
var templateNumGuardians *int
|
var setUpdateNumGuardians *int
|
||||||
var templateGuardianIndex *int
|
var templateGuardianIndex *int
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
templateNumGuardians = AdminClientGuardianSetTemplateCmd.Flags().Int("num", 1, "Number of devnet guardians in example file")
|
templateGuardianIndex = TemplateCmd.PersistentFlags().Int("idx", 0, "Default current guardian set index")
|
||||||
templateGuardianIndex = AdminClientGuardianSetTemplateCmd.Flags().Int("idx", 0, "Default current guardian set index")
|
setUpdateNumGuardians = AdminClientGuardianSetTemplateCmd.Flags().Int("num", 1, "Number of devnet guardians in example file")
|
||||||
|
|
||||||
|
TemplateCmd.AddCommand(AdminClientGuardianSetTemplateCmd)
|
||||||
|
TemplateCmd.AddCommand(AdminClientContractUpgradeTemplateCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
var TemplateCmd = &cobra.Command{
|
||||||
|
Use: "template",
|
||||||
|
Short: "Guardian governance VAA template commands ",
|
||||||
}
|
}
|
||||||
|
|
||||||
var AdminClientGuardianSetTemplateCmd = &cobra.Command{
|
var AdminClientGuardianSetTemplateCmd = &cobra.Command{
|
||||||
Use: "guardian-set-update-template",
|
Use: "guardian-set-update",
|
||||||
Short: "Generate an empty guardian set template at specified path (offline)",
|
Short: "Generate an empty guardian set template at specified path (offline)",
|
||||||
Run: runGuardianSetTemplate,
|
Run: runGuardianSetTemplate,
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var AdminClientContractUpgradeTemplateCmd = &cobra.Command{
|
||||||
|
Use: "contract-upgrade",
|
||||||
|
Short: "Generate an empty contract upgrade template at specified path (offline)",
|
||||||
|
Run: runContractUpgradeTemplate,
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
}
|
||||||
|
|
||||||
func runGuardianSetTemplate(cmd *cobra.Command, args []string) {
|
func runGuardianSetTemplate(cmd *cobra.Command, args []string) {
|
||||||
path := args[0]
|
path := args[0]
|
||||||
|
|
||||||
// Use deterministic devnet addresses as examples in the template, such that this doubles as a test fixture.
|
// Use deterministic devnet addresses as examples in the template, such that this doubles as a test fixture.
|
||||||
guardians := make([]*nodev1.GuardianSetUpdate_Guardian, *templateNumGuardians)
|
guardians := make([]*nodev1.GuardianSetUpdate_Guardian, *setUpdateNumGuardians)
|
||||||
for i := 0; i < *templateNumGuardians; i++ {
|
for i := 0; i < *setUpdateNumGuardians; i++ {
|
||||||
k := devnet.DeterministicEcdsaKeyByIndex(crypto.S256(), uint64(i))
|
k := devnet.DeterministicEcdsaKeyByIndex(crypto.S256(), uint64(i))
|
||||||
guardians[i] = &nodev1.GuardianSetUpdate_Guardian{
|
guardians[i] = &nodev1.GuardianSetUpdate_Guardian{
|
||||||
Pubkey: crypto.PubkeyToAddress(k.PublicKey).Hex(),
|
Pubkey: crypto.PubkeyToAddress(k.PublicKey).Hex(),
|
||||||
|
@ -41,12 +56,41 @@ func runGuardianSetTemplate(cmd *cobra.Command, args []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m := &nodev1.GuardianSetUpdate{
|
m := &nodev1.InjectGovernanceVAARequest{
|
||||||
CurrentSetIndex: uint32(*templateGuardianIndex),
|
CurrentSetIndex: uint32(*templateGuardianIndex),
|
||||||
// Timestamp is hardcoded to make it reproducible on different devnet nodes.
|
// Timestamp is hardcoded to make it reproducible on different devnet nodes.
|
||||||
// In production, a real UNIX timestamp should be used (see node.proto).
|
// In production, a real UNIX timestamp should be used (see node.proto).
|
||||||
Timestamp: 1605744545,
|
Timestamp: 1605744545,
|
||||||
Guardians: guardians,
|
Payload: &nodev1.InjectGovernanceVAARequest_GuardianSet{
|
||||||
|
GuardianSet: &nodev1.GuardianSetUpdate{Guardians: guardians},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := prototext.MarshalOptions{Multiline: true}.Marshal(m)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ioutil.WriteFile(path, b, 0640)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func runContractUpgradeTemplate(cmd *cobra.Command, args []string) {
|
||||||
|
path := args[0]
|
||||||
|
|
||||||
|
m := &nodev1.InjectGovernanceVAARequest{
|
||||||
|
CurrentSetIndex: uint32(*templateGuardianIndex),
|
||||||
|
// Timestamp is hardcoded to make it reproducible on different devnet nodes.
|
||||||
|
// In production, a real UNIX timestamp should be used (see node.proto).
|
||||||
|
Timestamp: 1605744545,
|
||||||
|
Payload: &nodev1.InjectGovernanceVAARequest_ContractUpgrade{
|
||||||
|
ContractUpgrade: &nodev1.ContractUpgrade{
|
||||||
|
ChainId: 1,
|
||||||
|
NewContract: make([]byte, 32),
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := prototext.MarshalOptions{Multiline: true}.Marshal(m)
|
b, err := prototext.MarshalOptions{Multiline: true}.Marshal(m)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package guardiand
|
package guardiand
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/certusone/wormhole/bridge/pkg/vaa"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
@ -11,14 +12,14 @@ import (
|
||||||
nodev1 "github.com/certusone/wormhole/bridge/pkg/proto/node/v1"
|
nodev1 "github.com/certusone/wormhole/bridge/pkg/proto/node/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
var AdminClientGuardianSetVerifyCmd = &cobra.Command{
|
var AdminClientGovernanceVAAVerifyCmd = &cobra.Command{
|
||||||
Use: "guardian-set-update-verify",
|
Use: "governance-vaa-verify",
|
||||||
Short: "Verify guardian set update in prototxt format (offline)",
|
Short: "Verify governance vaa in prototxt format (offline)",
|
||||||
Run: runGuardianSetVerify,
|
Run: runGovernanceVAAVerify,
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
}
|
}
|
||||||
|
|
||||||
func runGuardianSetVerify(cmd *cobra.Command, args []string) {
|
func runGovernanceVAAVerify(cmd *cobra.Command, args []string) {
|
||||||
path := args[0]
|
path := args[0]
|
||||||
|
|
||||||
b, err := ioutil.ReadFile(path)
|
b, err := ioutil.ReadFile(path)
|
||||||
|
@ -26,13 +27,21 @@ func runGuardianSetVerify(cmd *cobra.Command, args []string) {
|
||||||
log.Fatalf("failed to read file: %v", err)
|
log.Fatalf("failed to read file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var msg nodev1.GuardianSetUpdate
|
var msg nodev1.InjectGovernanceVAARequest
|
||||||
err = prototext.Unmarshal(b, &msg)
|
err = prototext.Unmarshal(b, &msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to deserialize: %v", err)
|
log.Fatalf("failed to deserialize: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
v, err := adminGuardianSetUpdateToVAA(&msg)
|
var (
|
||||||
|
v *vaa.VAA
|
||||||
|
)
|
||||||
|
switch payload := msg.Payload.(type) {
|
||||||
|
case *nodev1.InjectGovernanceVAARequest_GuardianSet:
|
||||||
|
v, err = adminGuardianSetUpdateToVAA(payload.GuardianSet, msg.CurrentSetIndex, msg.Timestamp)
|
||||||
|
case *nodev1.InjectGovernanceVAARequest_ContractUpgrade:
|
||||||
|
v, err = adminContractUpgradeToVAA(payload.ContractUpgrade, msg.CurrentSetIndex, msg.Timestamp)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("invalid update: %v", err)
|
log.Fatalf("invalid update: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ func init() {
|
||||||
rootCmd.AddCommand(guardiand.BridgeCmd)
|
rootCmd.AddCommand(guardiand.BridgeCmd)
|
||||||
rootCmd.AddCommand(guardiand.KeygenCmd)
|
rootCmd.AddCommand(guardiand.KeygenCmd)
|
||||||
rootCmd.AddCommand(guardiand.AdminCmd)
|
rootCmd.AddCommand(guardiand.AdminCmd)
|
||||||
|
rootCmd.AddCommand(guardiand.TemplateCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// initConfig reads in config file and ENV variables if set.
|
// initConfig reads in config file and ENV variables if set.
|
||||||
|
|
|
@ -172,6 +172,17 @@ func (p *Processor) handleObservation(ctx context.Context, m *gossipv1.SignedObs
|
||||||
// A guardian set update is broadcast to every chain that we talk to.
|
// A guardian set update is broadcast to every chain that we talk to.
|
||||||
p.devnetVAASubmission(ctx, signed, hash)
|
p.devnetVAASubmission(ctx, signed, hash)
|
||||||
p.terraVAASubmission(ctx, signed, hash)
|
p.terraVAASubmission(ctx, signed, hash)
|
||||||
|
case *vaa.BodyContractUpgrade:
|
||||||
|
switch t.ChainID {
|
||||||
|
case vaa.ChainIDSolana:
|
||||||
|
// Already submitted to Solana.
|
||||||
|
default:
|
||||||
|
p.logger.Error("unsupported target chain for contract upgrade",
|
||||||
|
zap.String("digest", hash),
|
||||||
|
zap.Any("vaa", signed),
|
||||||
|
zap.String("bytes", hex.EncodeToString(vaaBytes)),
|
||||||
|
zap.Uint8("target_chain", t.ChainID))
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unknown VAA payload type: %+v", v))
|
panic(fmt.Sprintf("unknown VAA payload type: %+v", v))
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,13 @@ type (
|
||||||
// NewIndex is the index of the new guardian set
|
// NewIndex is the index of the new guardian set
|
||||||
NewIndex uint32
|
NewIndex uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BodyContractUpgrade struct {
|
||||||
|
// ChainID is the chain on which the contract should be upgraded
|
||||||
|
ChainID uint8
|
||||||
|
// NewContract is the address of the account containing the new contract.
|
||||||
|
NewContract Address
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (a Address) String() string {
|
func (a Address) String() string {
|
||||||
|
@ -106,6 +113,7 @@ func (c ChainID) String() string {
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ActionGuardianSetUpdate Action = 0x01
|
ActionGuardianSetUpdate Action = 0x01
|
||||||
|
ActionContractUpgrade Action = 0x02
|
||||||
ActionTransfer Action = 0x10
|
ActionTransfer Action = 0x10
|
||||||
|
|
||||||
// ChainIDSolana is the ChainID of Solana
|
// ChainIDSolana is the ChainID of Solana
|
||||||
|
@ -182,6 +190,8 @@ func Unmarshal(data []byte) (*VAA, error) {
|
||||||
v.Payload, err = parseBodyGuardianSetUpdate(payloadReader)
|
v.Payload, err = parseBodyGuardianSetUpdate(payloadReader)
|
||||||
case ActionTransfer:
|
case ActionTransfer:
|
||||||
v.Payload, err = parseBodyTransfer(payloadReader)
|
v.Payload, err = parseBodyTransfer(payloadReader)
|
||||||
|
case ActionContractUpgrade:
|
||||||
|
v.Payload, err = parseBodyContractUpgrade(payloadReader)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unknown action: %d", action)
|
return nil, fmt.Errorf("unknown action: %d", action)
|
||||||
}
|
}
|
||||||
|
@ -403,6 +413,33 @@ func (v *BodyGuardianSetUpdate) serialize() ([]byte, error) {
|
||||||
return buf.Bytes(), nil
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseBodyContractUpgrade(r io.Reader) (*BodyContractUpgrade, error) {
|
||||||
|
b := &BodyContractUpgrade{}
|
||||||
|
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &b.ChainID); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to read chain id: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if n, err := r.Read(b.NewContract[:]); err != nil || n != 32 {
|
||||||
|
return nil, fmt.Errorf("failed to read new contract address: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *BodyContractUpgrade) getActionID() Action {
|
||||||
|
return ActionContractUpgrade
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *BodyContractUpgrade) serialize() ([]byte, error) {
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
|
MustWrite(buf, binary.BigEndian, v.ChainID)
|
||||||
|
buf.Write(v.NewContract[:])
|
||||||
|
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
// MustWrite calls binary.Write and panics on errors
|
// MustWrite calls binary.Write and panics on errors
|
||||||
func MustWrite(w io.Writer, order binary.ByteOrder, data interface{}) {
|
func MustWrite(w io.Writer, order binary.ByteOrder, data interface{}) {
|
||||||
if err := binary.Write(w, order, data); err != nil {
|
if err := binary.Write(w, order, data); err != nil {
|
||||||
|
|
|
@ -61,6 +61,24 @@ func TestSerializeDeserialize(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "ContractUpgrade",
|
||||||
|
vaa: &VAA{
|
||||||
|
Version: 1,
|
||||||
|
GuardianSetIndex: 9,
|
||||||
|
Signatures: []*Signature{
|
||||||
|
{
|
||||||
|
Index: 1,
|
||||||
|
Signature: [65]byte{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Timestamp: time.Unix(2837, 0),
|
||||||
|
Payload: &BodyContractUpgrade{
|
||||||
|
ChainID: ChainIDEthereum,
|
||||||
|
NewContract: Address{1, 3, 4, 5, 2, 3},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
|
|
@ -146,6 +146,20 @@ uint8 len(keys)
|
||||||
The `new_index` must be monotonically increasing and is manually specified here to fix a potential guardian_set index
|
The `new_index` must be monotonically increasing and is manually specified here to fix a potential guardian_set index
|
||||||
desynchronization between the any of the chains in the system.
|
desynchronization between the any of the chains in the system.
|
||||||
|
|
||||||
|
##### Contract upgrade
|
||||||
|
|
||||||
|
ID: `0x02`
|
||||||
|
|
||||||
|
Payload:
|
||||||
|
|
||||||
|
```
|
||||||
|
uint8 chain_id
|
||||||
|
[32]uint8 new_contract
|
||||||
|
```
|
||||||
|
|
||||||
|
`chain_id` specifies the chain on which the contract should be updated. `new_contract` is the address of the updated
|
||||||
|
contract.
|
||||||
|
|
||||||
##### Transfer
|
##### Transfer
|
||||||
|
|
||||||
ID: `0x10`
|
ID: `0x10`
|
||||||
|
|
|
@ -154,6 +154,14 @@ followed by:
|
||||||
| ----- | ------------ | ------------------- | ------ | --------- | ----- | ------- |
|
| ----- | ------------ | ------------------- | ------ | --------- | ----- | ------- |
|
||||||
| 9 | guardian_set_new | GuardianSet | | ✅ | ✅ | ✅ |
|
| 9 | guardian_set_new | GuardianSet | | ✅ | ✅ | ✅ |
|
||||||
|
|
||||||
|
##### Contract upgrade
|
||||||
|
|
||||||
|
| Index | Name | Type | signer | writeable | empty | derived |
|
||||||
|
| ----- | ------------------ | ----------------- | ------ | --------- | ----- | ------- |
|
||||||
|
| 9 | new_contract | Account | | | ✅ | |
|
||||||
|
| 10 | program_data | Account | | ✅ | ✅ | ✅ |
|
||||||
|
| 11 | upgradeable_loader | UpgradeableLoader | | | | |
|
||||||
|
|
||||||
##### Transfer: Ethereum (native) -> Solana (wrapped)
|
##### Transfer: Ethereum (native) -> Solana (wrapped)
|
||||||
|
|
||||||
| Index | Name | Type | signer | writeable | empty | derived |
|
| Index | Name | Type | signer | writeable | empty | derived |
|
||||||
|
|
|
@ -9,20 +9,17 @@ import "google/api/annotations.proto";
|
||||||
// NodePrivileged exposes an administrative API. It runs on a UNIX socket and is authenticated
|
// NodePrivileged exposes an administrative API. It runs on a UNIX socket and is authenticated
|
||||||
// using Linux filesystem permissions.
|
// using Linux filesystem permissions.
|
||||||
service NodePrivileged {
|
service NodePrivileged {
|
||||||
// SubmitGuardianSetVAA injects a guardian set change VAA into the guardian node.
|
// InjectGovernanceVAA injects a governance VAA into the guardian node.
|
||||||
// The node will inject the VAA into the aggregator and sign/broadcast the VAA signature.
|
// The node will inject the VAA into the aggregator and sign/broadcast the VAA signature.
|
||||||
//
|
//
|
||||||
// A consensus majority of nodes on the network will have to inject the VAA within the
|
// A consensus majority of nodes on the network will have to inject the VAA within the
|
||||||
// VAA timeout window for it to reach consensus.
|
// VAA timeout window for it to reach consensus.
|
||||||
//
|
//
|
||||||
rpc SubmitGuardianSetVAA (SubmitGuardianSetVAARequest) returns (SubmitGuardianSetVAAResponse);
|
rpc InjectGovernanceVAA (InjectGovernanceVAARequest) returns (InjectGovernanceVAAResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
// GuardianSet represents a new guardian set to be submitted to and signed by the node.
|
message InjectGovernanceVAARequest {
|
||||||
// During the genesis procedure, this data structure will be assembled using off-chain collaborative tooling
|
// Index of the current guardian set.
|
||||||
// like GitHub using a human-readable encoding, so readability is a concern.
|
|
||||||
message GuardianSetUpdate {
|
|
||||||
// Index of the current guardian set to be replaced.
|
|
||||||
uint32 current_set_index = 1;
|
uint32 current_set_index = 1;
|
||||||
|
|
||||||
// UNIX timestamp (s) of the VAA to be created. The timestamp is informational and will be part
|
// UNIX timestamp (s) of the VAA to be created. The timestamp is informational and will be part
|
||||||
|
@ -30,15 +27,30 @@ message GuardianSetUpdate {
|
||||||
// is critical for replay protection - a given event may only ever be observed with the same timestamp,
|
// is critical for replay protection - a given event may only ever be observed with the same timestamp,
|
||||||
// otherwise, it may be possible to execute it multiple times.
|
// otherwise, it may be possible to execute it multiple times.
|
||||||
//
|
//
|
||||||
// For lockups, the timestamp identifies the block that the lockup belongs to. For guardian set updates,
|
// For lockups, the timestamp identifies the block that the lockup belongs to.
|
||||||
// we create the VAA manually. Best practice is to pick a timestamp which roughly matches the expected
|
|
||||||
// genesis ceremony data.
|
// For governance VAAs, guardians inject the VAA manually. Best practice is to pick a timestamp which roughly matches
|
||||||
//
|
// the timing of the off-chain ceremony used to achieve consensus. For guardian set updates, the actual on-chain
|
||||||
// The actual on-chain guardian set creation timestamp will be set when the VAA is accepted on each chain.
|
// guardian set creation timestamp will be set when the VAA is accepted on each chain.
|
||||||
//
|
//
|
||||||
// This is a uint32 to match the on-chain timestamp representation. This becomes a problem in 2106 (sorry).
|
// This is a uint32 to match the on-chain timestamp representation. This becomes a problem in 2106 (sorry).
|
||||||
uint32 timestamp = 2;
|
uint32 timestamp = 2;
|
||||||
|
|
||||||
|
oneof payload{
|
||||||
|
GuardianSetUpdate guardian_set = 3;
|
||||||
|
ContractUpgrade contract_upgrade = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message InjectGovernanceVAAResponse {
|
||||||
|
// Canonical digest of the submitted VAA.
|
||||||
|
bytes digest = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GuardianSet represents a new guardian set to be submitted to and signed by the node.
|
||||||
|
// During the genesis procedure, this data structure will be assembled using off-chain collaborative tooling
|
||||||
|
// like GitHub using a human-readable encoding, so readability is a concern.
|
||||||
|
message GuardianSetUpdate {
|
||||||
// List of guardian set members.
|
// List of guardian set members.
|
||||||
message Guardian {
|
message Guardian {
|
||||||
// Guardian key pubkey. Stored as hex string with 0x prefix for human readability -
|
// Guardian key pubkey. Stored as hex string with 0x prefix for human readability -
|
||||||
|
@ -50,17 +62,17 @@ message GuardianSetUpdate {
|
||||||
repeated Guardian guardians = 3;
|
repeated Guardian guardians = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SubmitGuardianSetVAARequest {
|
|
||||||
GuardianSetUpdate guardian_set = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SubmitGuardianSetVAAResponse {
|
|
||||||
// Canonical digest of the submitted VAA.
|
|
||||||
bytes digest = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GuardianKey specifies the on-disk format for a node's guardian key.
|
// GuardianKey specifies the on-disk format for a node's guardian key.
|
||||||
message GuardianKey {
|
message GuardianKey {
|
||||||
// data is the binary representation of the secp256k1 private key.
|
// data is the binary representation of the secp256k1 private key.
|
||||||
bytes data = 1;
|
bytes data = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContractUpgrade represents a Wormhole contract update to be submitted to and signed by the node.
|
||||||
|
message ContractUpgrade {
|
||||||
|
// ID of the chain where the Wormhole contract should be updated (uint8).
|
||||||
|
uint32 chain_id = 1;
|
||||||
|
|
||||||
|
// Address of the new program/contract.
|
||||||
|
bytes new_contract = 2;
|
||||||
|
}
|
||||||
|
|
|
@ -9,10 +9,10 @@ path=/tmp/new-guardianset.prototxt
|
||||||
sock=/tmp/admin.sock
|
sock=/tmp/admin.sock
|
||||||
|
|
||||||
# Create a no-op update that sets the same 1-node guardian set again.
|
# Create a no-op update that sets the same 1-node guardian set again.
|
||||||
kubectl exec guardian-${node} -c guardiand -- /guardiand admin guardian-set-update-template --num=1 --idx=${idx} $path
|
kubectl exec -n wormhole guardian-${node} -c guardiand -- /guardiand template guardian-set-update --num=1 --idx=${idx} $path
|
||||||
|
|
||||||
# Verify and print resulting result. The digest incorporates the current time and is NOT deterministic.
|
# Verify and print resulting result. The digest incorporates the current time and is NOT deterministic.
|
||||||
kubectl exec guardian-${node} -c guardiand -- /guardiand admin guardian-set-update-verify $path
|
kubectl exec -n wormhole guardian-${node} -c guardiand -- /guardiand admin governance-vaa-verify $path
|
||||||
|
|
||||||
# Submit to node
|
# Submit to node
|
||||||
kubectl exec guardian-${node} -c guardiand -- /guardiand admin guardian-set-update-inject --socket $sock $path
|
kubectl exec -n wormhole guardian-${node} -c guardiand -- /guardiand admin governance-vaa-inject --socket $sock $path
|
||||||
|
|
|
@ -330,6 +330,12 @@ version = "0.5.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
|
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytes"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e0dcbc35f504eb6fc275a6d20e4ebcda18cf50d40ba6fabff8c711fa16cb3b16"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bzip2"
|
name = "bzip2"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
|
@ -823,9 +829,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_logger"
|
name = "env_logger"
|
||||||
version = "0.7.1"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
|
checksum = "f26ecb66b4bdca6c1409b40fb255eefc2bd4f6d135dab3c3124f80ffa2a9661e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"humantime",
|
"humantime",
|
||||||
|
@ -1245,12 +1251,9 @@ checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "humantime"
|
name = "humantime"
|
||||||
version = "1.3.0"
|
version = "2.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
|
checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a"
|
||||||
dependencies = [
|
|
||||||
"quick-error",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper"
|
name = "hyper"
|
||||||
|
@ -1563,13 +1566,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memmap"
|
name = "memmap2"
|
||||||
version = "0.7.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
|
checksum = "d9b70ca2a6103ac8b665dc150b142ef0e4e89df640c9e6cf295d189c3caebe5a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"winapi 0.3.9",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1629,12 +1631,25 @@ dependencies = [
|
||||||
"kernel32-sys",
|
"kernel32-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"miow",
|
"miow 0.2.2",
|
||||||
"net2",
|
"net2",
|
||||||
"slab",
|
"slab",
|
||||||
"winapi 0.2.8",
|
"winapi 0.2.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio"
|
||||||
|
version = "0.7.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e50ae3f04d169fcc9bde0b547d1c205219b7157e07ded9c5aff03e0637cb3ed7"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"miow 0.3.6",
|
||||||
|
"ntapi",
|
||||||
|
"winapi 0.3.9",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio-uds"
|
name = "mio-uds"
|
||||||
version = "0.6.8"
|
version = "0.6.8"
|
||||||
|
@ -1643,7 +1658,7 @@ checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iovec",
|
"iovec",
|
||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio 0.6.23",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1658,6 +1673,16 @@ dependencies = [
|
||||||
"ws2_32-sys",
|
"ws2_32-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miow"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897"
|
||||||
|
dependencies = [
|
||||||
|
"socket2",
|
||||||
|
"winapi 0.3.9",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "multimap"
|
name = "multimap"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
|
@ -1684,9 +1709,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "net2"
|
name = "net2"
|
||||||
version = "0.2.36"
|
version = "0.2.37"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7cf75f38f16cb05ea017784dc6dbfd354f76c223dba37701734c4f5a9337d02"
|
checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -1695,15 +1720,23 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix"
|
name = "nix"
|
||||||
version = "0.17.0"
|
version = "0.19.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363"
|
checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cc",
|
"cc",
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 1.0.0",
|
||||||
"libc",
|
"libc",
|
||||||
"void",
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ntapi"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
|
||||||
|
dependencies = [
|
||||||
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2179,12 +2212,6 @@ dependencies = [
|
||||||
"prost",
|
"prost",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quick-error"
|
|
||||||
version = "1.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "0.6.13"
|
version = "0.6.13"
|
||||||
|
@ -2653,6 +2680,15 @@ dependencies = [
|
||||||
"opaque-debug 0.3.0",
|
"opaque-debug 0.3.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signature"
|
name = "signature"
|
||||||
version = "1.2.2"
|
version = "1.2.2"
|
||||||
|
@ -2694,9 +2730,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-account-decoder"
|
name = "solana-account-decoder"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "29fa579ccae25e66c5b9f3e058b16b19efc823e653ee491bbcda1f06a440de7a"
|
checksum = "469a64e65f2788c0fcd68124fce6a490c139a37ee159d855fe45bde9404be96e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"Inflector",
|
"Inflector",
|
||||||
"base64 0.12.3",
|
"base64 0.12.3",
|
||||||
|
@ -2718,9 +2754,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-clap-utils"
|
name = "solana-clap-utils"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "90e908b0267c02e3898fb5769109dddbc936f14aadcedd3d5925d1a4d9b120f9"
|
checksum = "5bc41382ae2e834acce6b26e361e0ba79acec3b6633e36189e1cbcd16e3d9edf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
|
@ -2734,9 +2770,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-cli-config"
|
name = "solana-cli-config"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0f0f69ef61a624038c6c2e0109f08c827633a04a4d21272e1e02e3bd70961008"
|
checksum = "ef627ff85612a66af08384dfbe006948c74143cee6a0b80311a94e5e0ffe8c2b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs-next",
|
"dirs-next",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
@ -2748,9 +2784,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-client"
|
name = "solana-client"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7253ee3b369812df3c30c9076ac2d5f042e09d7cb9c04e2928ebf5df26ad4ab2"
|
checksum = "3fbe10a0b09201e4d272848644720d75d237dfe92536701b973ecb6a042d8363"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.13.0",
|
"base64 0.13.0",
|
||||||
"bincode",
|
"bincode",
|
||||||
|
@ -2759,6 +2795,7 @@ dependencies = [
|
||||||
"indicatif",
|
"indicatif",
|
||||||
"jsonrpc-core",
|
"jsonrpc-core",
|
||||||
"log",
|
"log",
|
||||||
|
"net2",
|
||||||
"rayon",
|
"rayon",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"semver 0.11.0",
|
"semver 0.11.0",
|
||||||
|
@ -2779,9 +2816,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-config-program"
|
name = "solana-config-program"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3c5c599f4049337d8c89c08811b3044203d083038e4e4be724843088211f3158"
|
checksum = "d0dbb6f55cfd7eefb7d739c3a5b8ff2bba53825f002b7a3fc0531c2a335092a5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
@ -2793,9 +2830,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-crate-features"
|
name = "solana-crate-features"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc73ada8cddc62edf58dc09ef3cf4551259d0ca1c7ece5f102757279ec2afa95"
|
checksum = "a694ee719e16262801bdaeacda065e21352b7607cd7327b180172adca99864dc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bytes 0.4.12",
|
"bytes 0.4.12",
|
||||||
|
@ -2817,13 +2854,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-faucet"
|
name = "solana-faucet"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "16cae7630ea7accaae2e6f538f400bcac312271cf4ab882a92875570447650b0"
|
checksum = "ca85d93e05c4270f15c4ce929895bafa42a6d6f368d6d70ada93fbd51add69f8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes 0.4.12",
|
|
||||||
"clap",
|
"clap",
|
||||||
"log",
|
"log",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -2834,21 +2870,20 @@ dependencies = [
|
||||||
"solana-metrics",
|
"solana-metrics",
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
"solana-version",
|
"solana-version",
|
||||||
"tokio 0.1.22",
|
"tokio 0.3.6",
|
||||||
"tokio-codec",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-frozen-abi"
|
name = "solana-frozen-abi"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9e5ab6ad3dda6a3d95d19603eeedc65689d8125eafb3e23c6a1e01ab8a6ba60c"
|
checksum = "2cc29ffc04200709ae0ece6a6a4a78d97043537e0cf70fa36a0cec200140e893"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bs58",
|
"bs58",
|
||||||
"bv",
|
"bv",
|
||||||
"generic-array 0.14.4",
|
"generic-array 0.14.4",
|
||||||
"log",
|
"log",
|
||||||
"memmap",
|
"memmap2",
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
|
@ -2860,9 +2895,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-frozen-abi-macro"
|
name = "solana-frozen-abi-macro"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ffaa09aa938a67501479ed8a785071c6993f72c34e43f680db3ea7a2dadad9e7"
|
checksum = "9351c5355512afadaa64225d0653b050c768a7d5938429bff8a2e7c17143429f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"proc-macro2 1.0.24",
|
"proc-macro2 1.0.24",
|
||||||
|
@ -2873,9 +2908,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-logger"
|
name = "solana-logger"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0d949157d0b23eaf5758b427d90741d2a90751c4e3dfee028f5726ab8b36e769"
|
checksum = "188a6e6d7e001336d00ece746ecbd4b5e5ff1a12397c456934d831288f99b23d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
@ -2884,9 +2919,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-measure"
|
name = "solana-measure"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "76c197e92932f6498371df4a52e972403b0a3dfd3eac101b2844774b43292d89"
|
checksum = "cef4e2d6ffd08f35e6268b1bcffe63b37a6f9a53d91644757d607b8d3ba4251e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jemalloc-ctl",
|
"jemalloc-ctl",
|
||||||
"jemallocator",
|
"jemallocator",
|
||||||
|
@ -2897,9 +2932,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-metrics"
|
name = "solana-metrics"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ed2f570bd9d87a991c58800bd94149c34243f14c6b3dfc39fbca602e13db70a"
|
checksum = "4c02403e4f6fcb97e149854c42a0a7e81af041e5228544ad375cd75fb82a859d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"gethostname",
|
"gethostname",
|
||||||
|
@ -2911,12 +2946,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-net-utils"
|
name = "solana-net-utils"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fea0a40ca7c0f5be26d1a203ac1ef44920f7c845ffdcf922e2aa597662e13958"
|
checksum = "5468c5a5590aef624a668d264cb64f009d0d81ad8c7d609a57dbcb4328fcb2ef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"bytes 0.4.12",
|
|
||||||
"clap",
|
"clap",
|
||||||
"log",
|
"log",
|
||||||
"nix",
|
"nix",
|
||||||
|
@ -2927,15 +2961,15 @@ dependencies = [
|
||||||
"solana-clap-utils",
|
"solana-clap-utils",
|
||||||
"solana-logger",
|
"solana-logger",
|
||||||
"solana-version",
|
"solana-version",
|
||||||
"tokio 0.1.22",
|
"tokio 0.3.6",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-program"
|
name = "solana-program"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8e9c6cb16e8aa986bc0d2af8ec50628f7451bef9dac89924adf48302bd4fc755"
|
checksum = "6c16bdd751d5549716a610f87b8ab1ca13ceaf66dfc9f325440894a72eadb74e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"bs58",
|
"bs58",
|
||||||
|
@ -2963,9 +2997,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-rayon-threadlimit"
|
name = "solana-rayon-threadlimit"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "de7367bfa559a08c2023d62f780ae01fddf865b974d7fd449bbeb1399641764d"
|
checksum = "72de795cac4d5e9c9c083177bfcbe343c461c1ce5dcffbecddd2d0b7f09e04fa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
|
@ -2973,9 +3007,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-remote-wallet"
|
name = "solana-remote-wallet"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1fde6cc84dfcc15c34eedba0675ca51cbaa8b83ca70233c5751459af869568e1"
|
checksum = "46f7717eca656d386dd233c60d6c63c3d5e16fa64dd3bca1a7f1b27007cf354e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base32",
|
"base32",
|
||||||
"console 0.11.3",
|
"console 0.11.3",
|
||||||
|
@ -2993,9 +3027,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-runtime"
|
name = "solana-runtime"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4d1364382b1ea6dd516c53455c817eaa5cd47bf7565cd00953586002731dd8fd"
|
checksum = "b817d921c53245e3fcc78ac605fb61ae0ada81346fda7dec41a7681770610ca5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"blake3",
|
"blake3",
|
||||||
|
@ -3013,7 +3047,7 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"libloading",
|
"libloading",
|
||||||
"log",
|
"log",
|
||||||
"memmap",
|
"memmap2",
|
||||||
"num-derive 0.3.3",
|
"num-derive 0.3.3",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
|
@ -3044,9 +3078,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-sdk"
|
name = "solana-sdk"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "85c38a02d501422070cd6a4d561b4ab1408e311c5a0b5af3a7bb01246da14f66"
|
checksum = "280fa9cef4fdb9154fea538ed1efdc74215b3734a4ad611ddb1393269efac1bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assert_matches",
|
"assert_matches",
|
||||||
"bincode",
|
"bincode",
|
||||||
|
@ -3063,7 +3097,7 @@ dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libsecp256k1",
|
"libsecp256k1",
|
||||||
"log",
|
"log",
|
||||||
"memmap",
|
"memmap2",
|
||||||
"num-derive 0.3.3",
|
"num-derive 0.3.3",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"pbkdf2",
|
"pbkdf2",
|
||||||
|
@ -3088,9 +3122,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-sdk-macro"
|
name = "solana-sdk-macro"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "475a680cd175f2e256452e007c6f8622d3a1ab97ab36d26303b35576e24f340c"
|
checksum = "11489c157e78f60ad9d4a96dc4d1955ef6936ef606f6ce0273689fcdb90391c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bs58",
|
"bs58",
|
||||||
"proc-macro2 1.0.24",
|
"proc-macro2 1.0.24",
|
||||||
|
@ -3101,9 +3135,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-secp256k1-program"
|
name = "solana-secp256k1-program"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "64f76265997062d8cb18b8055ab200294087ee0bb2de3cf65864eb964f39b2c8"
|
checksum = "3eb1617ea1dec65e59ab94eb6bdcf15e831270ae41317f4e9bee926693f74f30"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"digest 0.9.0",
|
"digest 0.9.0",
|
||||||
|
@ -3116,9 +3150,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-stake-program"
|
name = "solana-stake-program"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9fcb16ef12c9ed669308074bcc0549d5b36f29597fb701530f108088d438b3cd"
|
checksum = "a691ac55bb8cb4ded6c192ab117b545e3090e92c13560b02318b02ed423eaef6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"log",
|
"log",
|
||||||
|
@ -3138,9 +3172,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-transaction-status"
|
name = "solana-transaction-status"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2f69cb54e6854d4799529c22c21c1d53abaf2ebfc7b2c2fe1ce84b2afb9c620"
|
checksum = "ede0f19e5bec9b0d9a85c4eba2f453547064b124b4849ddfe6e7212a94aa75b0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"Inflector",
|
"Inflector",
|
||||||
"base64 0.12.3",
|
"base64 0.12.3",
|
||||||
|
@ -3162,9 +3196,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-version"
|
name = "solana-version"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d6995a2a6734a108b4a80497a391e86c8d234d94b02ceec0cebc9ba132874502"
|
checksum = "94bc42af0fb331572e8161e099f4b1c50cec8f12c3d64d61ff04c0719199aebb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
|
@ -3178,9 +3212,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-vote-program"
|
name = "solana-vote-program"
|
||||||
version = "1.4.14"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6b42b3fd7b76dd8c98eb13f92677b1803d0bc1ac06af45e10f1aee46b8c19a8a"
|
checksum = "c9a3c8a54916bb189a80dee075bae93950198ac8b51cde6d2e7e8860b8a05250"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"log",
|
"log",
|
||||||
|
@ -3205,18 +3239,18 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spl-memo"
|
name = "spl-memo"
|
||||||
version = "2.0.0"
|
version = "2.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "99775feb54f735a6826ea0af500c1f78f7a5974d6b17f1ac586cd114e2da7d80"
|
checksum = "fb2b771f6146dec14ef5fbf498f9374652c54badc3befc8c40c1d426dd45d720"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"solana-program",
|
"solana-program",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spl-token"
|
name = "spl-token"
|
||||||
version = "3.0.0"
|
version = "3.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2f77fa0b41cbc82d1d7c8f2d914b49e9a1a7b6e32af952d03383fb989c42bc89"
|
checksum = "a9774eebb62ff1ff2f5eca112413e476143925a2f5a43cee98fc5d3a6c0eec5c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayref",
|
"arrayref",
|
||||||
"num-derive 0.3.3",
|
"num-derive 0.3.3",
|
||||||
|
@ -3447,7 +3481,7 @@ checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 0.4.12",
|
"bytes 0.4.12",
|
||||||
"futures 0.1.30",
|
"futures 0.1.30",
|
||||||
"mio",
|
"mio 0.6.23",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"tokio-codec",
|
"tokio-codec",
|
||||||
"tokio-current-thread",
|
"tokio-current-thread",
|
||||||
|
@ -3476,12 +3510,34 @@ dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
"memchr",
|
"memchr",
|
||||||
"mio",
|
"mio 0.6.23",
|
||||||
"mio-uds",
|
"mio-uds",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"pin-project-lite 0.1.11",
|
"pin-project-lite 0.1.11",
|
||||||
"slab",
|
"slab",
|
||||||
"tokio-macros",
|
"tokio-macros 0.2.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "720ba21c25078711bf456d607987d95bce90f7c3bea5abe1db587862e7a1e87c"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"bytes 0.6.0",
|
||||||
|
"futures-core",
|
||||||
|
"libc",
|
||||||
|
"memchr",
|
||||||
|
"mio 0.7.7",
|
||||||
|
"num_cpus",
|
||||||
|
"once_cell",
|
||||||
|
"parking_lot 0.11.1",
|
||||||
|
"pin-project-lite 0.2.0",
|
||||||
|
"signal-hook-registry",
|
||||||
|
"slab",
|
||||||
|
"tokio-macros 0.3.2",
|
||||||
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3548,6 +3604,17 @@ dependencies = [
|
||||||
"syn 1.0.53",
|
"syn 1.0.53",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-macros"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46dfffa59fc3c8aad216ed61bdc2c263d2b9d87a9c8ac9de0c11a813e51b6db7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.24",
|
||||||
|
"quote 1.0.7",
|
||||||
|
"syn 1.0.53",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-reactor"
|
name = "tokio-reactor"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
|
@ -3558,7 +3625,7 @@ dependencies = [
|
||||||
"futures 0.1.30",
|
"futures 0.1.30",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"mio",
|
"mio 0.6.23",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"parking_lot 0.9.0",
|
"parking_lot 0.9.0",
|
||||||
"slab",
|
"slab",
|
||||||
|
@ -3598,7 +3665,7 @@ dependencies = [
|
||||||
"bytes 0.4.12",
|
"bytes 0.4.12",
|
||||||
"futures 0.1.30",
|
"futures 0.1.30",
|
||||||
"iovec",
|
"iovec",
|
||||||
"mio",
|
"mio 0.6.23",
|
||||||
"tokio-io",
|
"tokio-io",
|
||||||
"tokio-reactor",
|
"tokio-reactor",
|
||||||
]
|
]
|
||||||
|
@ -3641,7 +3708,7 @@ dependencies = [
|
||||||
"bytes 0.4.12",
|
"bytes 0.4.12",
|
||||||
"futures 0.1.30",
|
"futures 0.1.30",
|
||||||
"log",
|
"log",
|
||||||
"mio",
|
"mio 0.6.23",
|
||||||
"tokio-codec",
|
"tokio-codec",
|
||||||
"tokio-io",
|
"tokio-io",
|
||||||
"tokio-reactor",
|
"tokio-reactor",
|
||||||
|
@ -3658,7 +3725,7 @@ dependencies = [
|
||||||
"iovec",
|
"iovec",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"mio",
|
"mio 0.6.23",
|
||||||
"mio-uds",
|
"mio-uds",
|
||||||
"tokio-codec",
|
"tokio-codec",
|
||||||
"tokio-io",
|
"tokio-io",
|
||||||
|
@ -4114,12 +4181,6 @@ version = "0.9.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "void"
|
|
||||||
version = "1.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "walkdir"
|
||||||
version = "2.3.1"
|
version = "2.3.1"
|
||||||
|
|
|
@ -9,10 +9,10 @@ tonic = "0.3.0"
|
||||||
tokio = { version = "0.2", features = ["rt-threaded", "time", "stream", "fs", "macros", "uds"] }
|
tokio = { version = "0.2", features = ["rt-threaded", "time", "stream", "fs", "macros", "uds"] }
|
||||||
prost = "0.6"
|
prost = "0.6"
|
||||||
prost-types = "0.6"
|
prost-types = "0.6"
|
||||||
solana-sdk = { version = "1.4.7" }
|
solana-sdk = { version = "1.4.20" }
|
||||||
solana-client = { version = "1.4.7" }
|
solana-client = { version = "1.4.20" }
|
||||||
solana-faucet = "1.4.7"
|
solana-faucet = "1.4.20"
|
||||||
spl-token = "=3.0.0"
|
spl-token = "=3.0.1"
|
||||||
wormhole-bridge = { path = "../bridge" }
|
wormhole-bridge = { path = "../bridge" }
|
||||||
primitive-types = { version = "0.7.2" }
|
primitive-types = { version = "0.7.2" }
|
||||||
hex = "0.4.2"
|
hex = "0.4.2"
|
||||||
|
@ -21,7 +21,7 @@ tungstenite = "0.11.1"
|
||||||
serde = "1.0.103"
|
serde = "1.0.103"
|
||||||
url = "2.1.1"
|
url = "2.1.1"
|
||||||
serde_bytes = "0.11.5"
|
serde_bytes = "0.11.5"
|
||||||
log = "0.4.8"
|
log = "0.4.11"
|
||||||
serde_derive = "1.0.103"
|
serde_derive = "1.0.103"
|
||||||
serde_json = "1.0.57"
|
serde_json = "1.0.57"
|
||||||
bs58 = "0.3.1"
|
bs58 = "0.3.1"
|
||||||
|
|
|
@ -17,8 +17,8 @@ program = ["spl-token/no-entrypoint"]
|
||||||
num-derive = "0.2"
|
num-derive = "0.2"
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
remove_dir_all = "=0.5.0"
|
remove_dir_all = "=0.5.0"
|
||||||
solana-program = "1.4.7"
|
solana-program = "1.4.20"
|
||||||
spl-token = { version = "=3.0.0" }
|
spl-token = { version = "=3.0.1" }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
byteorder = "1.3.4"
|
byteorder = "1.3.4"
|
||||||
zerocopy = "0.3.0"
|
zerocopy = "0.3.0"
|
||||||
|
|
|
@ -112,6 +112,9 @@ pub enum Error {
|
||||||
/// Invalid Sysvar
|
/// Invalid Sysvar
|
||||||
#[error("InvalidSysvar")]
|
#[error("InvalidSysvar")]
|
||||||
InvalidSysvar,
|
InvalidSysvar,
|
||||||
|
/// Invalid Chain
|
||||||
|
#[error("InvalidChain")]
|
||||||
|
InvalidChain,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Error> for ProgramError {
|
impl From<Error> for ProgramError {
|
||||||
|
|
|
@ -42,6 +42,7 @@ impl PrintProgramError for Error {
|
||||||
Error::InsufficientFees => msg!("Error: InsufficientFees"),
|
Error::InsufficientFees => msg!("Error: InsufficientFees"),
|
||||||
Error::InvalidOwner => msg!("Error: InvalidOwner"),
|
Error::InvalidOwner => msg!("Error: InvalidOwner"),
|
||||||
Error::InvalidSysvar => msg!("Error: InvalidSysvar"),
|
Error::InvalidSysvar => msg!("Error: InvalidSysvar"),
|
||||||
|
Error::InvalidChain => msg!("Error: InvalidChain"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -425,6 +425,12 @@ pub fn post_vaa(
|
||||||
Bridge::derive_guardian_set_id(program_id, &bridge_key, u.new_index)?;
|
Bridge::derive_guardian_set_id(program_id, &bridge_key, u.new_index)?;
|
||||||
accounts.push(AccountMeta::new(guardian_set_key, false));
|
accounts.push(AccountMeta::new(guardian_set_key, false));
|
||||||
}
|
}
|
||||||
|
VAABody::UpgradeContract(u) => {
|
||||||
|
accounts.push(AccountMeta::new(u.buffer, false));
|
||||||
|
let (programdata_address, _) = Pubkey::find_program_address(&[program_id.as_ref()], &solana_program::bpf_loader_upgradeable::id());
|
||||||
|
accounts.push(AccountMeta::new(programdata_address, false));
|
||||||
|
accounts.push(AccountMeta::new_readonly(solana_program::bpf_loader_upgradeable::id(), false));
|
||||||
|
}
|
||||||
VAABody::Transfer(t) => {
|
VAABody::Transfer(t) => {
|
||||||
if t.source_chain == CHAIN_ID_SOLANA {
|
if t.source_chain == CHAIN_ID_SOLANA {
|
||||||
// Solana (any) -> Ethereum (any)
|
// Solana (any) -> Ethereum (any)
|
||||||
|
|
|
@ -36,6 +36,7 @@ use solana_program::program_pack::Pack;
|
||||||
use std::borrow::BorrowMut;
|
use std::borrow::BorrowMut;
|
||||||
use std::ops::Add;
|
use std::ops::Add;
|
||||||
use solana_program::fee_calculator::FeeCalculator;
|
use solana_program::fee_calculator::FeeCalculator;
|
||||||
|
use crate::vaa::BodyContractUpgrade;
|
||||||
|
|
||||||
/// SigInfo contains metadata about signers in a VerifySignature ix
|
/// SigInfo contains metadata about signers in a VerifySignature ix
|
||||||
struct SigInfo {
|
struct SigInfo {
|
||||||
|
@ -772,6 +773,19 @@ impl Bridge {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
VAABody::UpgradeContract(v) => {
|
||||||
|
if v.chain_id == CHAIN_ID_SOLANA {
|
||||||
|
evict_signatures = true;
|
||||||
|
Self::process_vaa_upgrade(
|
||||||
|
program_id,
|
||||||
|
accounts,
|
||||||
|
bridge_info,
|
||||||
|
v,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return Err(Error::InvalidChain.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
// Check and create claim
|
// Check and create claim
|
||||||
|
@ -1001,6 +1015,25 @@ impl Bridge {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Processes a VAA contract upgrade
|
||||||
|
pub fn process_vaa_upgrade(
|
||||||
|
program_id: &Pubkey,
|
||||||
|
accounts: &[AccountInfo],
|
||||||
|
bridge_info: &AccountInfo,
|
||||||
|
b: &BodyContractUpgrade,
|
||||||
|
) -> ProgramResult {
|
||||||
|
// Invoke upgrade
|
||||||
|
let upgrade_ix = solana_program::bpf_loader_upgradeable::upgrade(
|
||||||
|
program_id,
|
||||||
|
&b.buffer,
|
||||||
|
bridge_info.key,
|
||||||
|
bridge_info.key,
|
||||||
|
);
|
||||||
|
Self::invoke_as_bridge(program_id, &upgrade_ix, accounts);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new wrapped asset
|
/// Creates a new wrapped asset
|
||||||
pub fn process_create_wrapped(
|
pub fn process_create_wrapped(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
|
|
|
@ -6,6 +6,7 @@ use sha3::Digest;
|
||||||
use solana_program::program_error::ProgramError;
|
use solana_program::program_error::ProgramError;
|
||||||
|
|
||||||
use crate::{error::Error, state::AssetMeta};
|
use crate::{error::Error, state::AssetMeta};
|
||||||
|
use solana_program::pubkey::Pubkey;
|
||||||
|
|
||||||
pub type ForeignAddress = [u8; 32];
|
pub type ForeignAddress = [u8; 32];
|
||||||
|
|
||||||
|
@ -129,12 +130,14 @@ impl VAA {
|
||||||
pub enum VAABody {
|
pub enum VAABody {
|
||||||
UpdateGuardianSet(BodyUpdateGuardianSet),
|
UpdateGuardianSet(BodyUpdateGuardianSet),
|
||||||
Transfer(BodyTransfer),
|
Transfer(BodyTransfer),
|
||||||
|
UpgradeContract(BodyContractUpgrade),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VAABody {
|
impl VAABody {
|
||||||
fn action_id(&self) -> u8 {
|
fn action_id(&self) -> u8 {
|
||||||
match self {
|
match self {
|
||||||
VAABody::UpdateGuardianSet(_) => 0x01,
|
VAABody::UpdateGuardianSet(_) => 0x01,
|
||||||
|
VAABody::UpgradeContract(_) => 0x02,
|
||||||
VAABody::Transfer(_) => 0x10,
|
VAABody::Transfer(_) => 0x10,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,6 +150,7 @@ impl VAABody {
|
||||||
0x01 => {
|
0x01 => {
|
||||||
VAABody::UpdateGuardianSet(BodyUpdateGuardianSet::deserialize(&mut payload_data)?)
|
VAABody::UpdateGuardianSet(BodyUpdateGuardianSet::deserialize(&mut payload_data)?)
|
||||||
}
|
}
|
||||||
|
0x02 => VAABody::UpgradeContract(BodyContractUpgrade::deserialize(&mut payload_data)?),
|
||||||
0x10 => VAABody::Transfer(BodyTransfer::deserialize(&mut payload_data)?),
|
0x10 => VAABody::Transfer(BodyTransfer::deserialize(&mut payload_data)?),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::InvalidVAAAction);
|
return Err(Error::InvalidVAAAction);
|
||||||
|
@ -160,6 +164,7 @@ impl VAABody {
|
||||||
match self {
|
match self {
|
||||||
VAABody::Transfer(b) => b.serialize(),
|
VAABody::Transfer(b) => b.serialize(),
|
||||||
VAABody::UpdateGuardianSet(b) => b.serialize(),
|
VAABody::UpdateGuardianSet(b) => b.serialize(),
|
||||||
|
VAABody::UpgradeContract(b) => b.serialize(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,6 +186,34 @@ pub struct BodyTransfer {
|
||||||
pub amount: U256,
|
pub amount: U256,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct BodyContractUpgrade {
|
||||||
|
pub chain_id: u8,
|
||||||
|
pub buffer: Pubkey,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BodyContractUpgrade {
|
||||||
|
fn deserialize(data: &mut Cursor<&Vec<u8>>) -> Result<BodyContractUpgrade, Error> {
|
||||||
|
let chain_id = data.read_u8()?;
|
||||||
|
let mut key: [u8; 32] = [0; 32];
|
||||||
|
data.read(&mut key[..])?;
|
||||||
|
|
||||||
|
Ok(BodyContractUpgrade {
|
||||||
|
chain_id,
|
||||||
|
buffer: Pubkey::new(&key[..]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize(&self) -> Result<Vec<u8>, Error> {
|
||||||
|
let mut v: Cursor<Vec<u8>> = Cursor::new(Vec::new());
|
||||||
|
v.write_u8(self.chain_id)?;
|
||||||
|
v.write(&self.buffer.to_bytes());
|
||||||
|
|
||||||
|
Ok(v.into_inner())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl BodyUpdateGuardianSet {
|
impl BodyUpdateGuardianSet {
|
||||||
fn deserialize(data: &mut Cursor<&Vec<u8>>) -> Result<BodyUpdateGuardianSet, Error> {
|
fn deserialize(data: &mut Cursor<&Vec<u8>>) -> Result<BodyUpdateGuardianSet, Error> {
|
||||||
let new_index = data.read_u32::<BigEndian>()?;
|
let new_index = data.read_u32::<BigEndian>()?;
|
||||||
|
@ -273,6 +306,8 @@ mod tests {
|
||||||
state::AssetMeta,
|
state::AssetMeta,
|
||||||
vaa::{BodyTransfer, BodyUpdateGuardianSet, Signature, VAABody, VAA},
|
vaa::{BodyTransfer, BodyUpdateGuardianSet, Signature, VAABody, VAA},
|
||||||
};
|
};
|
||||||
|
use crate::vaa::BodyContractUpgrade;
|
||||||
|
use solana_program::pubkey::Pubkey;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialize_deserialize_vaa_transfer() {
|
fn serialize_deserialize_vaa_transfer() {
|
||||||
|
@ -329,6 +364,29 @@ mod tests {
|
||||||
assert_eq!(vaa, parsed_vaa)
|
assert_eq!(vaa, parsed_vaa)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serialize_deserialize_vaa_contract_upgrade() {
|
||||||
|
let vaa = VAA {
|
||||||
|
version: 8,
|
||||||
|
guardian_set_index: 3,
|
||||||
|
signatures: vec![Signature {
|
||||||
|
index: 1,
|
||||||
|
r: [2; 32],
|
||||||
|
s: [2; 32],
|
||||||
|
v: 7,
|
||||||
|
}],
|
||||||
|
timestamp: 83,
|
||||||
|
payload: Some(VAABody::UpgradeContract(BodyContractUpgrade {
|
||||||
|
chain_id: 3,
|
||||||
|
buffer: Pubkey::new_unique(),
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
|
||||||
|
let data = vaa.serialize().unwrap();
|
||||||
|
let parsed_vaa = VAA::deserialize(data.as_slice()).unwrap();
|
||||||
|
assert_eq!(vaa, parsed_vaa)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_given_guardian_set_update() {
|
fn parse_given_guardian_set_update() {
|
||||||
let vaa = VAA {
|
let vaa = VAA {
|
||||||
|
@ -411,4 +469,36 @@ mod tests {
|
||||||
let rec_data = parsed_vaa.serialize().unwrap();
|
let rec_data = parsed_vaa.serialize().unwrap();
|
||||||
assert_eq!(data, rec_data);
|
assert_eq!(data, rec_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_given_contract_upgrade() {
|
||||||
|
let vaa = VAA {
|
||||||
|
version: 1,
|
||||||
|
guardian_set_index: 2,
|
||||||
|
signatures: vec![Signature {
|
||||||
|
index: 0,
|
||||||
|
r: [
|
||||||
|
72, 156, 56, 20, 222, 146, 161, 112, 22, 97, 69, 59, 188, 199, 130, 240, 89,
|
||||||
|
249, 241, 79, 96, 27, 235, 10, 99, 16, 56, 80, 232, 188, 235, 11
|
||||||
|
],
|
||||||
|
s: [
|
||||||
|
65, 19, 144, 42, 104, 122, 52, 0, 126, 7, 43, 127, 120, 85, 5, 21, 216, 207,
|
||||||
|
78, 73, 213, 207, 142, 103, 211, 192, 100, 90, 27, 98, 176, 98
|
||||||
|
],
|
||||||
|
v: 1,
|
||||||
|
}],
|
||||||
|
timestamp: 4000,
|
||||||
|
payload: Some(VAABody::UpgradeContract(BodyContractUpgrade {
|
||||||
|
chain_id: 2,
|
||||||
|
buffer: Pubkey::new(&[146, 115, 122, 21, 4, 243, 179, 223, 140, 147, 203, 133, 198, 74, 72, 96, 187,
|
||||||
|
39, 14, 38, 2, 107, 110, 55, 240, 149, 53, 106, 64, 111, 106, 244]),
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
let data = hex::decode("01000000020100489c3814de92a1701661453bbcc782f059f9f14f601beb0a63103850e8bceb0b4113902a687a34007e072b7f78550515d8cf4e49d5cf8e67d3c0645a1b62b0620100000fa0020292737a1504f3b3df8c93cb85c64a4860bb270e26026b6e37f095356a406f6af4").unwrap();
|
||||||
|
let parsed_vaa = VAA::deserialize(data.as_slice()).unwrap();
|
||||||
|
assert_eq!(vaa, parsed_vaa);
|
||||||
|
|
||||||
|
let rec_data = parsed_vaa.serialize().unwrap();
|
||||||
|
assert_eq!(data, rec_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,14 +8,14 @@ edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33.0"
|
clap = "2.33.0"
|
||||||
solana-clap-utils = { version = "1.4.7" }
|
solana-clap-utils = { version = "1.4.20" }
|
||||||
solana-cli-config = { version = "1.4.7" }
|
solana-cli-config = { version = "1.4.20" }
|
||||||
solana-logger = { version = "1.4.7" }
|
solana-logger = { version = "1.4.20" }
|
||||||
solana-sdk = { version = "1.4.7" }
|
solana-sdk = { version = "1.4.20" }
|
||||||
solana-client = { version = "1.4.7" }
|
solana-client = { version = "1.4.20" }
|
||||||
solana-faucet = "1.4.7"
|
solana-faucet = "1.4.20"
|
||||||
solana-account-decoder = { version = "1.4.7" }
|
solana-account-decoder = { version = "1.4.20" }
|
||||||
spl-token = "=3.0.0"
|
spl-token = "=3.0.1"
|
||||||
wormhole-bridge = { path = "../bridge" }
|
wormhole-bridge = { path = "../bridge" }
|
||||||
primitive-types = { version = "0.7.2" }
|
primitive-types = { version = "0.7.2" }
|
||||||
hex = "0.4.2"
|
hex = "0.4.2"
|
||||||
|
|
|
@ -11,7 +11,7 @@ RUN rustup component add rustfmt
|
||||||
WORKDIR /usr/src/solana
|
WORKDIR /usr/src/solana
|
||||||
|
|
||||||
RUN git clone https://github.com/solana-labs/solana --branch master && \
|
RUN git clone https://github.com/solana-labs/solana --branch master && \
|
||||||
cd solana && git checkout v1.4.12
|
cd solana && git checkout v1.4.20
|
||||||
|
|
||||||
ADD *.patch .
|
ADD *.patch .
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue