Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
cryi committed Feb 3, 2024
0 parents commit b5b17a8
Show file tree
Hide file tree
Showing 20 changed files with 2,027 additions and 0 deletions.
96 changes: 96 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: release

on:
release:
types: [created]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '>=1.21.6'
- name: Test
run: go test -v ./...
- name: Build win-arm64
run: env CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build -ldflags="-s -w" -trimpath -o bin/tezpeak-win-arm64.exe
- name: Build win-amd64
run: env CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -trimpath -o bin/tezpeak-win-amd64.exe
- name: Build linux-arm64
run: env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="-s -w" -trimpath -o bin/tezpeak-linux-arm64
- name: Build linux-riscv64
run: env CGO_ENABLED=0 GOOS=linux GOARCH=riscv64 go build -ldflags="-s -w" -trimpath -o bin/tezpeak-linux-riscv64
- name: Build linux-amd64
run: env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -trimpath -o bin/tezpeak-linux-amd64
- name: Build macos-arm64
run: env CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -ldflags="-s -w" -trimpath -o bin/tezpeak-macos-arm64
- name: Build macos-amd64
run: env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags="-s -w" -trimpath -o bin/tezpeak-macos-amd64

- name: Upload files to a GitHub release
uses: svenstaro/upload-release-action@2.4.0
with:
file_glob: true
tag: ${{ github.ref }}
file: bin/tezpeak*

# build-containers:
# runs-on: ubuntu-latest
# needs: [build]
# steps:
# - uses: actions/checkout@v3
# - name: Login to ghcr.io
# uses: docker/login-action@v2
# with:
# registry: ghcr.io
# username: ${{ github.actor }}
# password: ${{ secrets.GITHUB_TOKEN }}

# - name: Set up QEMU
# uses: docker/setup-qemu-action@v2

# - name: Set up Docker Buildx
# uses: docker/setup-buildx-action@v2

# - name: Build and publish container
# uses: docker/build-push-action@v4
# with:
# file: ./container/Containerfile
# platforms: linux/amd64,linux/arm64
# build-args: GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
# tags: ghcr.io/tez-capital/tezpeak:latest,ghcr.io/tez-capital/tezpeak:${{github.ref_name}}
# push: true
# provenance: false

# - name: Build and publish riscv64 container
# uses: docker/build-push-action@v4
# with:
# file: ./container/riscv64/Containerfile
# platforms: linux/riscv64
# build-args: GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
# tags: ghcr.io/tez-capital/riscv64/tezpeak:latest,ghcr.io/tez-capital/riscv64/tezpeak:${{github.ref_name}}
# push: true
# provenance: false

notify:
runs-on: ubuntu-latest
needs: [build] #, build-containers]
steps:
- name: Ami tezpeak Repository Dispatch
uses: peter-evans/repository-dispatch@v2
with:
token: ${{ secrets.AMI_TEZPEAK_ACCESS_TOKEN }}
repository: tez-capital/ami-tezpeak
event-type: tezpeak-release
client-payload: '{ "id": "${{ steps.repository_info.outputs.ID }}", "repository": "${{github.repository}}", "version": "${{github.ref_name}}" }'

# - name: Notify new version available
# uses: Ilshidur/action-discord@master
# env:
# DISCORD_WEBHOOK: ${{ secrets.PB_DISCORD_WEBHOOK }}
# with:
# args: "New tezpeak ${{ github.ref_name }} released. (<https://github.com/tez-capital/tezpeak/releases/tag/${{ github.ref_name }}>)"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
config.hjson
557 changes: 557 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

191 changes: 191 additions & 0 deletions configuration/runtime.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
package configuration

import (
"errors"
"fmt"
"log/slog"
"os"
"path/filepath"

"github.com/hjson/hjson-go/v4"
"github.com/tez-capital/tezpeak/constants"
)

type versionedConfig interface {
ToRuntime() *Runtime
}

type deserializedConfigVersion struct {
Version int `json:"version,omitempty"`
}

type RuntimeReferenceNode struct {
Address string
IsRightsProvider bool
IsBlockProvider bool
}

type Runtime struct {
Bakers []string
WorkingDirectory string
Node string
ReferenceNodes map[string]RuntimeReferenceNode
BlockWindow int64

// TODO:
// ReadOnly bool
}

func gerDefaultRuntime() *Runtime {
return &Runtime{
WorkingDirectory: "",
ReferenceNodes: make(map[string]RuntimeReferenceNode),
BlockWindow: 50,
}
}

type nodeAppJsonConfiguration struct {
AdditionalKeysAliases []string `json:"additional_keys_aliases,omitempty"`
}

type nodeAppJson struct {
Configuration nodeAppJsonConfiguration `json:"configuration,omitempty"`
}

type nodePublicKeyHashAlias struct {
Name string `json:"name,omitempty"`
Hash string `json:"value,omitempty"`
}

type nodePublicKeys []nodePublicKeyHashAlias

func (r *Runtime) loadBakersFromNodeConfiguration() {
aliases := []string{"baker"} // baker is used by default

nodeDirectory := filepath.Join(r.WorkingDirectory, "node")
nodeAppJsonPath := filepath.Join(nodeDirectory, "app.json")
if _, err := os.Stat(nodeAppJsonPath); os.IsNotExist(err) {
nodeAppJsonPath = filepath.Join(nodeDirectory, "app.hjson")
}

nodeAppJsonBytes, err := os.ReadFile(nodeAppJsonPath)
if err != nil {
slog.Error("failed to read node app.json file", "error", err.Error())
return
}

var nodeApp nodeAppJson
err = hjson.Unmarshal(nodeAppJsonBytes, &nodeApp)
if err != nil {
slog.Error("failed to parse node app.json file", "error", err.Error())
return
}

aliases = append(aliases, nodeApp.Configuration.AdditionalKeysAliases...)

// r.Bakers
publicKeyHashesPath := filepath.Join(nodeDirectory, "data", ".tezos-client", "public_key_hashs")
publicKeyHashesBytes, err := os.ReadFile(publicKeyHashesPath)
if err != nil {
slog.Error("failed to read node public_key_hashs file", "error", err.Error())
return
}

var publicKeys nodePublicKeys
err = hjson.Unmarshal(publicKeyHashesBytes, &publicKeys)
if err != nil {
slog.Error("failed to parse node public_key_hashs file", "error", err.Error())
return
}

for _, publicKey := range publicKeys {
for _, alias := range aliases {
if publicKey.Name == alias {
r.Bakers = append(r.Bakers, publicKey.Hash)
}
}
}
}

func (r *Runtime) Hydrate() *Runtime {
if r.WorkingDirectory == "" {
envWorkingDirectory := os.Getenv(constants.ENV_TEZBAKE_HOME)
if envWorkingDirectory != "" {
r.WorkingDirectory = envWorkingDirectory
} else {
r.WorkingDirectory, _ = os.Getwd()
}
}

if r.Node == "" {
r.Node = constants.DEFAULT_BAKER_NODE_URL
}

if r.BlockWindow == 0 {
r.BlockWindow = 50
}

fmt.Println("r.ReferenceNodes", r.ReferenceNodes)
if len(r.ReferenceNodes) == 0 {
r.ReferenceNodes = map[string]RuntimeReferenceNode{
"Tezos Foundation": {
Address: constants.DEFAULT_REFERENCE_NODE_URL,
IsRightsProvider: constants.DEFAULT_REFERENCE_NODE_IS_RIGHTS_PROVIDER,
IsBlockProvider: constants.DEFAULT_REFERENCE_NODE_IS_BLOCK_PROVIDER,
},
"tzkt": {
Address: constants.DEFAULT_REFERENCE_NODE_2_URL,
IsRightsProvider: constants.DEFAULT_REFERENCE_NODE_2_IS_RIGHTS_PROVIDER,
IsBlockProvider: constants.DEFAULT_REFERENCE_NODE_2_IS_BLOCK_PROVIDER,
},
}
}

if len(r.Bakers) == 0 {
r.loadBakersFromNodeConfiguration()
}
return r
}

func (r *Runtime) Validate() (*Runtime, error) {
if r.WorkingDirectory == "" {
return nil, constants.ErrInvalidWorkingDirectory
}

if len(r.ReferenceNodes) == 0 {
return nil, constants.ErrInvalidBlockWindow
}

return r, nil
}

func Load() (*Runtime, error) {
var err error
configBytes, err := os.ReadFile("config.hjson")
if err != nil {
slog.Debug("failed to read config file", "error", err.Error())

// return config loaded from environment variables
return gerDefaultRuntime().Hydrate().Validate()
}

var configVersion deserializedConfigVersion
err = hjson.Unmarshal(configBytes, &configVersion)
if err != nil {
return nil, errors.Join(constants.ErrInvalidConfigVersion, err)
}

var configuration versionedConfig
switch configVersion.Version {
case 0:
configuration, err = load_v0(configBytes)
default:
return nil, constants.ErrInvalidConfigVersion
}

if err != nil {
return nil, errors.Join(constants.ErrInvalidConfig, err)
}

return configuration.ToRuntime().Hydrate().Validate()
}
95 changes: 95 additions & 0 deletions configuration/v0.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package configuration

import (
"github.com/hjson/hjson-go/v4"
"github.com/tez-capital/tezpeak/constants"
)

type referenceNode struct {
Address string `json:"address"`
IsRightsProvider *bool `json:"is_rights_provider,omitempty"`
IsBlockProvider *bool `json:"is_block_provider,omitempty"`
}

type v0 struct {
Version int `json:"version,omitempty"`
Bakers []string `json:"bakers,omitempty"`
WorkingDirectory string `json:"working_directory,omitempty"`
Node string `json:"node,omitempty"`
ReferenceNodes *map[string]referenceNode `json:"reference_nodes,omitempty"`
BlockWindow int64 `json:"block_window,omitempty"`
}

func getDefault_v0() *v0 {
isRightsProvider := constants.DEFAULT_REFERENCE_NODE_IS_RIGHTS_PROVIDER
isBlockProvider := constants.DEFAULT_REFERENCE_NODE_IS_BLOCK_PROVIDER

isRightsProvider2 := constants.DEFAULT_REFERENCE_NODE_2_IS_RIGHTS_PROVIDER
isBlockProvider2 := constants.DEFAULT_REFERENCE_NODE_2_IS_BLOCK_PROVIDER

return &v0{
Version: 0,
Bakers: []string{},
WorkingDirectory: "",
ReferenceNodes: &map[string]referenceNode{
"Tezos Foundation": {
Address: constants.DEFAULT_REFERENCE_NODE_URL,
IsRightsProvider: &isRightsProvider,
IsBlockProvider: &isBlockProvider,
},
"tzkt": {
Address: constants.DEFAULT_REFERENCE_NODE_2_URL,
IsRightsProvider: &isRightsProvider2,
IsBlockProvider: &isBlockProvider2,
},
},
BlockWindow: 50,
}
}

func load_v0(configBytes []byte) (*v0, error) {
configuration := getDefault_v0()

err := hjson.Unmarshal(configBytes, &configuration)
if err != nil {
return nil, err
}

isProvider := true
if configuration.ReferenceNodes != nil {
for _, node := range *configuration.ReferenceNodes {
if node.IsRightsProvider == nil {
node.IsRightsProvider = &isProvider
}
}
}
return configuration, nil
}

func (v *v0) ToRuntime() *Runtime {
result := &Runtime{
Bakers: v.Bakers,
WorkingDirectory: v.WorkingDirectory,
Node: v.Node,
ReferenceNodes: make(map[string]RuntimeReferenceNode),
BlockWindow: v.BlockWindow,
}

if v.ReferenceNodes != nil {
for name, node := range *v.ReferenceNodes {
runtimeReferenceNode := RuntimeReferenceNode{
Address: node.Address,
IsRightsProvider: true,
IsBlockProvider: true,
}
if node.IsRightsProvider != nil {
runtimeReferenceNode.IsRightsProvider = *node.IsRightsProvider
}
if node.IsBlockProvider != nil {
runtimeReferenceNode.IsBlockProvider = *node.IsBlockProvider
}
result.ReferenceNodes[name] = runtimeReferenceNode
}
}
return result
}
Loading

0 comments on commit b5b17a8

Please sign in to comment.