Skip to content

Commit

Permalink
make it so
Browse files Browse the repository at this point in the history
  • Loading branch information
Roman Shtylman committed Mar 26, 2020
0 parents commit cb67dad
Show file tree
Hide file tree
Showing 12 changed files with 684 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.vscode
build
6 changes: 6 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
image: golang:1.13

unit_test:
stage: test
script:
- make test
55 changes: 55 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Blue Oak Model License

Version 1.0.0

## Purpose

This license gives everyone as much permission to work with
this software as possible, while protecting contributors
from liability.

## Acceptance

In order to receive this license, you must agree to its
rules. The rules of this license are both obligations
under that agreement and conditions to your license.
You must not do anything with this software that triggers
a rule that you cannot or will not follow.

## Copyright

Each contributor licenses you to do everything with this
software that would otherwise infringe that contributor's
copyright in it.

## Notices

You must ensure that everyone who gets a copy of
any part of this software from you, with or without
changes, also gets the text of this license or a link to
<https://blueoakcouncil.org/license/1.0.0>.

## Excuse

If anyone notifies you in writing that you have not
complied with [Notices](#notices), you can keep your
license by taking all practical steps to comply within 30
days after the notice. If you do not do so, your license
ends immediately.

## Patent

Each contributor licenses you to do everything with this
software that would otherwise infringe any patent claims
they can license or become able to license.

## Reliability

No contributor can revoke this license.

## No Liability

***As far as the law allows, this software comes as is,
without any warranty or condition, and no contributor
will be liable to anyone for any damages related to this
software or this license, under any kind of legal claim.***
28 changes: 28 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
GOLINT:=$(shell go list -f {{.Target}} golang.org/x/lint/golint)

all: build

build: build/signer

build/signer: cmd/signer/main.go $(wildcard internal/**/*.go)
CGO_ENABLED=0 go build -o ./build/signer ${gobuild_flags} ./cmd/signer

lint: tools
@$(GOLINT) -set_exit_status ./...

test:
@go test -short ./...

race:
@go test -race -short ./...

msan:
@go test -msan -short ./...

tools:
@go install golang.org/x/lint/golint

clean:
rm -rf build

.PHONY: all lint test race msan tools clean build
82 changes: 82 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Tendermint Validator

A lightweight single key tendermint validator for sentry nodes.

## Design

A lightweight alternative to using a full node instance for validating blocks. The validator is able to connect to any number of sentry nodes and will sign blocks provided by the nodes. The validator maintains a watermark file to protect against double signing.

## Pre-requisites

Before starting, please make sure to fully understand node and validator requirements and operation for your particular network and chain.

## Setup

_The security of any key material is outside the scope of this guide. At a minimum we recommend performing key material steps on airgapped computers and using your audited security procedures._

### Setup Validator Instance

Configure the instance with a [toml](https://github.com/toml-lang/toml) file. Below is a sample configuration.

```toml
# Path to priv validator key json file
key_file = "/path/to/priv_validator_key.json"

# The state directory stores watermarks for double signing protection.
# Each validator instance maintains a watermark.
state_dir = "/path/to/state/dir"

# The network chain id for your p2p nodes
chain_id = "chain-id-here"

# Configure any number of p2p network nodes.
# We recommend at least 2 nodes for redundancy.
[[node]]
address = "tcp://<node-a ip>:1234"

[[node]]
address = "tcp://<node-b ip>:1234"
```

## Configure p2p network nodes

Validators are not directly connected to the p2p network nor do they store chain and application state. They rely on nodes to receive blocks from the p2p network, make signing requests, and relay the signed blocks back to the p2p network.

To make a node available as a relay for a validator, find the `priv_validator_laddr` (or equivalent) configuration item in your node's configuration file. Change this value, to accept connections on an IP address and port of your choosing.

```diff
# TCP or UNIX socket address for Tendermint to listen on for
# connections from an external PrivValidator process
-priv_validator_laddr = ""
+priv_validator_laddr = "tcp://0.0.0.0:1234"
```

_Full configuration and operation of your tendermint node is outside the scope of this guide. You should consult your network's documentation for node configuration._

_We recommend hosting nodes on separate and isolated infrastructure from your validator instances._

## Launch validator

Once your validator instance and node is configured, you can launch the signer.

```bash
signer --config /path/to/config.toml
```

_We recommend using systemd or similar service management program as appropriate for your runtime platform._

## Security

Security and management of any key material is outside the scope of this service. Always consider your own security and risk profile when dealing with sensitive keys, services, or infrastructure.

## No Liability

As far as the law allows, this software comes as is,
without any warranty or condition, and no contributor
will be liable to anyone for any damages related to this
software or this license, under any kind of legal claim.

## References

- https://docs.tendermint.com/master/tendermint-core/validators.html
- https://hub.cosmos.network/master/validators/overview.html
94 changes: 94 additions & 0 deletions cmd/signer/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package main

import (
"flag"
"fmt"
"log"
"net"
"os"
"path"
"sync"
"time"

"tendermint-signer/internal/signer"

cmn "github.com/tendermint/tendermint/libs/common"
tmlog "github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/privval"
)

func fileExists(filename string) bool {
info, err := os.Stat(filename)
if os.IsNotExist(err) {
return false
}
return !info.IsDir()
}

func main() {
logger := tmlog.NewTMLogger(
tmlog.NewSyncWriter(os.Stdout),
).With("module", "validator")

var configFile = flag.String("config", "", "path to configuration file")
flag.Parse()

if *configFile == "" {
panic("--config flag is required")
}

config, err := signer.LoadConfigFromFile(*configFile)
if err != nil {
log.Fatal(err)
}

logger.Info(
"Tendermint Validator",
"priv-key", config.PrivValKeyFile,
"priv-state-dir", config.PrivValStateDir,
)

signer.InitSerialization()

// services to stop on shutdown
var services []cmn.Service

chainID := config.ChainID
if chainID == "" {
log.Fatal("chain_id option is required")
}

stateFile := path.Join(config.PrivValStateDir, fmt.Sprintf("%s_priv_validator_state.json", chainID))

if !fileExists(stateFile) {
log.Fatalf("State file missing: %s\n", stateFile)
}

val := privval.LoadFilePV(config.PrivValKeyFile, stateFile)
pv := &signer.PvGuard{PrivValidator: val}

for _, node := range config.Nodes {
dialer := net.Dialer{Timeout: 30 * time.Second}
signer := signer.NewNodeClient(node.Address, logger, config.ChainID, pv, dialer)

err := signer.Start()
if err != nil {
panic(err)
}

services = append(services, signer)
}

wg := sync.WaitGroup{}
wg.Add(1)
cmn.TrapSignal(logger, func() {
for _, service := range services {
err := service.Stop()
if err != nil {
panic(err)
}
}
wg.Done()
})
wg.Wait()
}
27 changes: 27 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module tendermint-signer

require (
github.com/BurntSushi/toml v0.3.1
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fortytw2/leaktest v1.3.0 // indirect
github.com/go-kit/kit v0.9.0 // indirect
github.com/go-logfmt/logfmt v0.4.0 // indirect
github.com/go-stack/stack v1.8.0 // indirect
github.com/gogo/protobuf v1.2.1 // indirect
github.com/golang/protobuf v1.3.2 // indirect
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf // indirect
github.com/magiconair/properties v1.8.0 // indirect
github.com/pkg/errors v0.8.1 // indirect
github.com/stretchr/testify v1.3.0 // indirect
github.com/tendermint/go-amino v0.14.1
github.com/tendermint/tendermint v0.31.5
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 // indirect
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 // indirect
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 // indirect
google.golang.org/genproto v0.0.0-20190219182410-082222b4a5c5 // indirect
google.golang.org/grpc v1.19.0 // indirect
)

go 1.13
Loading

0 comments on commit cb67dad

Please sign in to comment.