Skip to content

Commit

Permalink
Stub out algorand support in wormhole (wormhole-foundation#611)
Browse files Browse the repository at this point in the history
* Stub out algorand support in wormhole

  1) Introduce the algorand chain constant in all the appropriate places
  2) Deploy pyth/hernandc algorand smart contracts into devnet
  3) Fund all the correct contracts for devnet testing

Change-Id: I6e4402b5b21223b32ea89653f8c7606f5c7f2843

* pr/jsiegel/algorand-v1: ALGORAND is not a EVM chain @ gusc1a-ossdev-jsl1

* pr/jsiegel/algorand-v1: fix lint @ gusc1a-ossdev-jsl1

* pr/jsiegel/algorand-v1: put the requirements into the image @ gusc1a-ossdev-jsl1

* jsiegel/algorand: make the watcher hang forever @ gusc1a-ossdev-jsl1

* jsiegel/algorand: comment these out @ gusc1a-ossdev-jsl1

* jsiegel/algorand: put this back in @ gusc1a-ossdev-jsl1

* jsiegel/algorand: fix guardian example @ gusc1a-ossdev-jsl1

* Generate teal source code

commit-id:a537a109

* jsiegel/algorand: it builds @ gusc1a-ossdev-jsl1

* pr/jsiegel/algorand-v1: add Dockerfile.teal @ gusc1a-ossdev-jsl1

* jsiegel/algorand: improve the dependencies @ gusc1a-ossdev-jsl1

* pr/jsiegel/algorand-v1: Fix up build @ gusc1a-ossdev-jsl1

* dead file

* pr/jsiegel/algorand-v1: remove more stuff @ gusc1a-ossdev-jsl1

* pr/jsiegel/algorand-v1: fix build @ gusc1a-ossdev-jsl1

* pr/jsiegel/algorand-v1: freeze the requirements @ gusc1a-ossdev-jsl1

* pr/jsiegel/algorand-v1: Fix teal to use pipenv @ gusc1a-ossdev-jsl1

* pr/jsiegel/algorand-v1: fix miss-merge @ gusc1a-ossdev-jsl1

Co-authored-by: Leo <[email protected]>
  • Loading branch information
jumpsiegel and Leo authored Dec 22, 2021
1 parent d6945bf commit f90ed66
Show file tree
Hide file tree
Showing 19 changed files with 711 additions and 4 deletions.
4 changes: 4 additions & 0 deletions DEVELOP.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,7 @@ Node logs:
Account list:

kubectl exec -c goal-kmd algorand-0 -- ./goal account list

Get yourself a working shell:

kubectl exec -c goal-kmd algorand-0 -it shell-demo -- /bin/bash
21 changes: 21 additions & 0 deletions Dockerfile.teal
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# syntax=docker.io/docker/dockerfile:1.3@sha256:42399d4635eddd7a9b8a24be879d2f9a930d0ed040a61324cfdf59ef1357b3b2
FROM docker.io/fedora:34 AS teal-build
RUN dnf -y install python3-pip

COPY staging/algorand/teal /teal

# Install pyTEAL dependencies
COPY third_party/algorand/Pipfile.lock Pipfile.lock
COPY third_party/algorand/Pipfile Pipfile

RUN pip install pipenv
RUN pipenv install

# Regenerate TEAL assembly
RUN pipenv run python3 /teal/wormhole/pyteal/vaa-processor.py vaa-processor-approval.teal vaa-processor-clear.teal
RUN pipenv run python3 /teal/wormhole/pyteal/vaa-verify.py 0 vaa-verify.teal

FROM scratch AS teal-export
COPY --from=teal-build /vaa-processor-approval.teal third_party/algorand/teal/
COPY --from=teal-build /vaa-processor-clear.teal third_party/algorand/teal/
COPY --from=teal-build /vaa-verify.teal third_party/algorand/teal/
9 changes: 9 additions & 0 deletions Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ local_resource(
trigger_mode = trigger_mode,
)

local_resource(
name = "teal-gen",
deps = ["staging/algorand/teal"],
cmd = "tilt docker build -- --target teal-export -f Dockerfile.teal -o type=local,dest=. .",
env = {"DOCKER_BUILDKIT": "1"},
trigger_mode = trigger_mode,
)

# wasm

local_resource(
Expand Down Expand Up @@ -301,6 +309,7 @@ docker_build(

k8s_resource(
"algorand",
resource_deps = ["teal-gen"],
port_forwards = [
port_forward(4001, name = "Algorand RPC [:4001]", host = webHost),
port_forward(4002, name = "Algorand KMD [:4002]", host = webHost),
Expand Down
2 changes: 1 addition & 1 deletion devnet/algorand.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ spec:
command:
- /bin/sh
- -c
- ./goal kmd start -d /network/Node && ./goal account list && sleep infinity
- ./goal kmd start -d /network/Node && ./goal account list && /setup/setup.sh && sleep infinity
ports:
- containerPort: 4002
name: kmd
Expand Down
6 changes: 6 additions & 0 deletions devnet/node.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ spec:
- http://terra-lcd:1317
- --terraContract
- terra18vd8fpwxzck93qlwghaj6arh4p7c5n896xzem5
- --algorandRPC
- http://localhost:4001
- --algorandToken
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- --algorandContract
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- --solanaContract
- Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o
- --solanaWS
Expand Down
32 changes: 32 additions & 0 deletions node/cmd/guardiand/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ import (

"github.com/certusone/wormhole/node/pkg/terra"

"github.com/certusone/wormhole/node/pkg/algorand"

ipfslog "github.com/ipfs/go-log/v2"
)

Expand Down Expand Up @@ -78,6 +80,10 @@ var (
terraLCD *string
terraContract *string

algorandRPC *string
algorandToken *string
algorandContract *string

solanaWsRPC *string
solanaRPC *string

Expand Down Expand Up @@ -145,6 +151,10 @@ func init() {
terraLCD = NodeCmd.Flags().String("terraLCD", "", "Path to LCD service root for http calls")
terraContract = NodeCmd.Flags().String("terraContract", "", "Wormhole contract address on Terra blockchain")

algorandRPC = NodeCmd.Flags().String("algorandRPC", "", "Algorand RPC URL")
algorandToken = NodeCmd.Flags().String("algorandToken", "", "Algorand access token")
algorandContract = NodeCmd.Flags().String("algorandContract", "", "Algorand contract")

solanaWsRPC = NodeCmd.Flags().String("solanaWS", "", "Solana Websocket URL (required")
solanaRPC = NodeCmd.Flags().String("solanaRPC", "", "Solana RPC URL (required")

Expand Down Expand Up @@ -248,6 +258,9 @@ func runNode(cmd *cobra.Command, args []string) {
readiness.RegisterComponent(common.ReadinessEthSyncing)
readiness.RegisterComponent(common.ReadinessSolanaSyncing)
readiness.RegisterComponent(common.ReadinessTerraSyncing)
if *unsafeDevMode {
readiness.RegisterComponent(common.ReadinessAlgorandSyncing)
}
readiness.RegisterComponent(common.ReadinessBSCSyncing)
readiness.RegisterComponent(common.ReadinessPolygonSyncing)
readiness.RegisterComponent(common.ReadinessAvalancheSyncing)
Expand Down Expand Up @@ -384,6 +397,18 @@ func runNode(cmd *cobra.Command, args []string) {
logger.Fatal("Please specify --terraContract")
}

if *unsafeDevMode {
if *algorandRPC == "" {
logger.Fatal("Please specify --algorandRPC")
}
if *algorandToken == "" {
logger.Fatal("Please specify --algorandToken")
}
if *algorandContract == "" {
logger.Fatal("Please specify --algorandContract")
}
}

if *bigTablePersistenceEnabled {
if *bigTableGCPProject == "" {
logger.Fatal("Please specify --bigTableGCPProject")
Expand Down Expand Up @@ -585,6 +610,13 @@ func runNode(cmd *cobra.Command, args []string) {
return err
}

if *unsafeDevMode {
if err := supervisor.Run(ctx, "algorandwatch",
algorand.NewWatcher(*algorandRPC, *algorandToken, *algorandContract, lockC, setC).Run); err != nil {
return err
}
}

if err := supervisor.Run(ctx, "solwatch-confirmed",
solana.NewSolanaWatcher(*solanaWsRPC, *solanaRPC, solAddress, lockC, rpc.CommitmentConfirmed).Run); err != nil {
return err
Expand Down
30 changes: 30 additions & 0 deletions node/pkg/algorand/watcher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package algorand

import (
"context"
"github.com/certusone/wormhole/node/pkg/common"
"github.com/certusone/wormhole/node/pkg/readiness"
)

type (
// Watcher is responsible for looking over Algorand blockchain and reporting new transactions to the contract
Watcher struct {
urlRPC string
urlToken string
contract string

msgChan chan *common.MessagePublication
setChan chan *common.GuardianSet
}
)

// NewWatcher creates a new Algorand contract watcher
func NewWatcher(urlRPC string, urlToken string, contract string, lockEvents chan *common.MessagePublication, setEvents chan *common.GuardianSet) *Watcher {
return &Watcher{urlRPC: urlRPC, urlToken: urlToken, contract: contract, msgChan: lockEvents, setChan: setEvents}
}

func (e *Watcher) Run(ctx context.Context) error {
readiness.SetReady(common.ReadinessAlgorandSyncing)

select {}
}
1 change: 1 addition & 0 deletions node/pkg/common/readiness.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const (
ReadinessEthSyncing readiness.Component = "ethSyncing"
ReadinessSolanaSyncing readiness.Component = "solanaSyncing"
ReadinessTerraSyncing readiness.Component = "terraSyncing"
ReadinessAlgorandSyncing readiness.Component = "algorandSyncing"
ReadinessBSCSyncing readiness.Component = "bscSyncing"
ReadinessPolygonSyncing readiness.Component = "polygonSyncing"
ReadinessEthRopstenSyncing readiness.Component = "ethRopstenSyncing"
Expand Down
6 changes: 6 additions & 0 deletions node/pkg/vaa/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ func (c ChainID) String() string {
return "avalanche"
case ChainIDOasis:
return "oasis"
case ChainIDAlgorand:
return "algorand"
case ChainIDEthereumRopsten:
return "ethereum-ropsten"
default:
Expand All @@ -123,6 +125,8 @@ func ChainIDFromString(s string) (ChainID, error) {
return ChainIDAvalanche, nil
case "oasis":
return ChainIDOasis, nil
case "algorand":
return ChainIDAlgorand, nil
case "ethereum-ropsten":
return ChainIDEthereumRopsten, nil
default:
Expand All @@ -146,6 +150,8 @@ const (
ChainIDAvalanche ChainID = 6
// ChainIDOasis is the ChainID of Oasis
ChainIDOasis ChainID = 7
// ChainIDAlgorand is the ChainID of Algorand
ChainIDAlgorand ChainID = 8

// ChainIDEthereumRopsten is the ChainID of Ethereum Ropsten
ChainIDEthereumRopsten ChainID = 10001
Expand Down
1 change: 1 addition & 0 deletions proto/publicrpc/v1/publicrpc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ enum ChainID {
CHAIN_ID_POLYGON = 5;
CHAIN_ID_AVALANCHE = 6;
CHAIN_ID_OASIS = 7;
CHAIN_ID_ALGORAND = 8;
// Special case - Eth has two testnets. CHAIN_ID_ETHEREUM is Goerli,
// but we also want to connect to Ropsten, so we add a separate chain.
CHAIN_ID_ETHEREUM_ROPSTEN = 10001;
Expand Down
3 changes: 2 additions & 1 deletion sdk/js/src/utils/consts.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
export type ChainId = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10001;
export type ChainId = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10001;
export const CHAIN_ID_SOLANA: ChainId = 1;
export const CHAIN_ID_ETH: ChainId = 2;
export const CHAIN_ID_TERRA: ChainId = 3;
export const CHAIN_ID_BSC: ChainId = 4;
export const CHAIN_ID_POLYGON: ChainId = 5;
export const CHAIN_ID_AVAX: ChainId = 6;
export const CHAIN_ID_OASIS: ChainId = 7;
export const CHAIN_ID_ALGORAND: ChainId = 8;
export const CHAIN_ID_ETHEREUM_ROPSTEN: ChainId = 10001;

export const WSOL_ADDRESS = "So11111111111111111111111111111111111111112";
Expand Down
Empty file modified staging/algorand/scripts/createapp.sh
100644 → 100755
Empty file.
4 changes: 2 additions & 2 deletions staging/algorand/teal/wormhole/pyteal/vaa-verify.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,10 @@ def vaa_verify_program(vaa_processor_app_id):
print("VAA Verify Stateless Program, (c) 2021-22 Randlabs Inc. ")
print("Compiling...")

if len(sys.argv) >= 2:
if len(sys.argv) >= 1:
appid = sys.argv[1]

if len(sys.argv) >= 3:
if len(sys.argv) >= 2:
outfile = sys.argv[2]

with open(outfile, "w") as f:
Expand Down
2 changes: 2 additions & 0 deletions third_party/algorand/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Generated
teal
11 changes: 11 additions & 0 deletions third_party/algorand/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ FROM docker.io/algorand/stable:3.2.1@sha256:0a87978492680fd98e2cc410f59f2bfd7fef

RUN mkdir -p /setup
ADD template.json /setup/
ADD setup.sh /setup/
ADD setup.py /setup/
ADD teal/vaa-verify.teal /setup/
ADD teal/vaa-processor-clear.teal /setup/
ADD teal/vaa-processor-approval.teal /setup/

RUN ./goal network create -n sandnet -r /network -t /setup/template.json && echo rawr

Expand All @@ -14,3 +19,9 @@ ADD config.json /network/Node/config.json
ADD kmd_config.json /network/Node/kmd-v0.5/kmd_config.json

ENV ALGORAND_DATA=/network/Node

ADD Pipfile.lock /setup/
ADD Pipfile /setup/
RUN apt-get update
RUN apt-get install -y python3-pip
RUN pip install pipenv
12 changes: 12 additions & 0 deletions third_party/algorand/Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
py-algorand-sdk = "*"
pyteal = "*"
mypy = "*"
pytest = "*"

[dev-packages]
Loading

0 comments on commit f90ed66

Please sign in to comment.