mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-15 06:11:20 +00:00
mv tools files to tools repo
This commit is contained in:
10
tools/mintnet-kubernetes/examples/basecoin/Makefile
Normal file
10
tools/mintnet-kubernetes/examples/basecoin/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
create:
|
||||
@echo "==> Creating deployment"
|
||||
@kubectl create -f app.yaml
|
||||
|
||||
destroy:
|
||||
@echo "==> Destroying deployment"
|
||||
@kubectl delete -f app.yaml
|
||||
@kubectl delete pvc -l app=tm
|
||||
|
||||
.PHONY: create destroy
|
42
tools/mintnet-kubernetes/examples/basecoin/README.md
Normal file
42
tools/mintnet-kubernetes/examples/basecoin/README.md
Normal file
@ -0,0 +1,42 @@
|
||||
# Basecoin example
|
||||
|
||||
This is an example of using [basecoin](https://github.com/tendermint/basecoin).
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
make create
|
||||
```
|
||||
|
||||
### Check account balance and send a transaction
|
||||
|
||||
1. wait until all the pods are `Running`.
|
||||
|
||||
```
|
||||
kubectl get pods -w -o wide -L tm
|
||||
```
|
||||
|
||||
2. wait until app starts.
|
||||
|
||||
```
|
||||
kubectl logs -c app -f tm-0
|
||||
```
|
||||
|
||||
3. get account's address of the second pod
|
||||
|
||||
```
|
||||
ADDR=`kubectl exec -c app tm-1 -- cat /app/key.json | jq ".address" | tr -d "\""`
|
||||
```
|
||||
|
||||
4. send 5 coins to it from the first pod
|
||||
|
||||
```
|
||||
kubectl exec -c app tm-0 -- basecoin tx send --to "0x$ADDR" --amount 5mycoin --from /app/key.json --chain_id chain-tTH4mi
|
||||
```
|
||||
|
||||
|
||||
## Clean up
|
||||
|
||||
```
|
||||
make destroy
|
||||
```
|
334
tools/mintnet-kubernetes/examples/basecoin/app.yaml
Normal file
334
tools/mintnet-kubernetes/examples/basecoin/app.yaml
Normal file
@ -0,0 +1,334 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
|
||||
name: basecoin
|
||||
labels:
|
||||
app: basecoin
|
||||
spec:
|
||||
ports:
|
||||
- port: 26656
|
||||
name: p2p
|
||||
- port: 26657
|
||||
name: rpc
|
||||
clusterIP: None
|
||||
selector:
|
||||
app: tm
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: tm-config
|
||||
data:
|
||||
seeds: "tm-0,tm-1,tm-2,tm-3"
|
||||
validators: "tm-0,tm-1,tm-2,tm-3"
|
||||
validator.power: "10"
|
||||
genesis.json: |-
|
||||
{
|
||||
"genesis_time": "2016-02-05T06:02:31.526Z",
|
||||
"chain_id": "chain-tTH4mi",
|
||||
"validators": [],
|
||||
"app_hash": ""
|
||||
}
|
||||
pub_key_nginx.conf: |-
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server ipv6only=on;
|
||||
location /pub_key.json { root /usr/share/nginx/; }
|
||||
location /app_pub_key.json { root /usr/share/nginx/; }
|
||||
}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: app-config
|
||||
data:
|
||||
genesis.json: |-
|
||||
{
|
||||
"chain_id": "chain-tTH4mi",
|
||||
"app_options": {
|
||||
"accounts": [
|
||||
{
|
||||
"pub_key": "tm-0",
|
||||
"coins": [
|
||||
{
|
||||
"denom": "mycoin",
|
||||
"amount": 1000000000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"pub_key": "tm-1",
|
||||
"coins": [
|
||||
{
|
||||
"denom": "mycoin",
|
||||
"amount": 1000000000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"pub_key": "tm-2",
|
||||
"coins": [
|
||||
{
|
||||
"denom": "mycoin",
|
||||
"amount": 1000000000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"pub_key": "tm-3",
|
||||
"coins": [
|
||||
{
|
||||
"denom": "mycoin",
|
||||
"amount": 1000000000
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
---
|
||||
apiVersion: policy/v1beta1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: tm-budget
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: tm
|
||||
minAvailable: 2
|
||||
---
|
||||
apiVersion: apps/v1beta1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: tm
|
||||
spec:
|
||||
serviceName: basecoin
|
||||
replicas: 4
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: tm
|
||||
annotations:
|
||||
pod.beta.kubernetes.io/init-containers: '[{
|
||||
"name": "tm-gen-validator",
|
||||
"image": "tendermint/tendermint:0.10.0",
|
||||
"imagePullPolicy": "IfNotPresent",
|
||||
"command": ["bash", "-c", "
|
||||
set -ex\n
|
||||
if [ ! -f /tendermint/priv_validator.json ]; then\n
|
||||
tendermint gen_validator > /tendermint/priv_validator.json\n
|
||||
# pub_key.json will be served by pub-key container\n
|
||||
cat /tendermint/priv_validator.json | jq \".pub_key\" > /tendermint/pub_key.json\n
|
||||
fi\n
|
||||
"],
|
||||
"volumeMounts": [
|
||||
{"name": "tmdir", "mountPath": "/tendermint"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "app-gen-key",
|
||||
"image": "tendermint/basecoin:0.5.1",
|
||||
"imagePullPolicy": "IfNotPresent",
|
||||
"command": ["bash", "-c", "
|
||||
set -ex\n
|
||||
if [ ! -f /app/key.json ]; then\n
|
||||
basecoin key new > /app/key.json\n
|
||||
# pub_key.json will be served by app-pub-key container\n
|
||||
cat /app/key.json | jq \".pub_key\" > /app/pub_key.json\n
|
||||
fi\n
|
||||
"],
|
||||
"volumeMounts": [
|
||||
{"name": "appdir", "mountPath": "/app"}
|
||||
]
|
||||
}]'
|
||||
spec:
|
||||
containers:
|
||||
- name: tm
|
||||
imagePullPolicy: IfNotPresent
|
||||
image: tendermint/tendermint:0.10.0
|
||||
ports:
|
||||
- containerPort: 26656
|
||||
name: p2p
|
||||
- containerPort: 26657
|
||||
name: rpc
|
||||
env:
|
||||
- name: SEEDS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: tm-config
|
||||
key: seeds
|
||||
- name: VALIDATOR_POWER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: tm-config
|
||||
key: validator.power
|
||||
- name: VALIDATORS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: tm-config
|
||||
key: validators
|
||||
- name: TMHOME
|
||||
value: /tendermint
|
||||
command:
|
||||
- bash
|
||||
- "-c"
|
||||
- |
|
||||
set -ex
|
||||
|
||||
# copy template
|
||||
cp /etc/tendermint/genesis.json /tendermint/genesis.json
|
||||
|
||||
# fill genesis file with validators
|
||||
IFS=',' read -ra VALS_ARR <<< "$VALIDATORS"
|
||||
fqdn_suffix=$(hostname -f | sed 's#[^.]*\.\(\)#\1#')
|
||||
for v in "${VALS_ARR[@]}"; do
|
||||
# wait until validator generates priv/pub key pair
|
||||
set +e
|
||||
|
||||
curl -s --fail "http://$v.$fqdn_suffix/pub_key.json" > /dev/null
|
||||
ERR=$?
|
||||
while [ "$ERR" != 0 ]; do
|
||||
sleep 5
|
||||
curl -s --fail "http://$v.$fqdn_suffix/pub_key.json" > /dev/null
|
||||
ERR=$?
|
||||
done
|
||||
set -e
|
||||
|
||||
# add validator to genesis file along with its pub_key
|
||||
curl -s "http://$v.$fqdn_suffix/pub_key.json" | jq ". as \$k | {pub_key: \$k, amount: $VALIDATOR_POWER, name: \"$v\"}" > pub_validator.json
|
||||
cat /tendermint/genesis.json | jq ".validators |= .+ [$(cat pub_validator.json)]" > tmpgenesis && mv tmpgenesis /tendermint/genesis.json
|
||||
rm pub_validator.json
|
||||
done
|
||||
|
||||
# construct seeds
|
||||
IFS=',' read -ra SEEDS_ARR <<< "$SEEDS"
|
||||
seeds=()
|
||||
for s in "${SEEDS_ARR[@]}"; do
|
||||
seeds+=("$s.$fqdn_suffix:26656")
|
||||
done
|
||||
seeds=$(IFS=','; echo "${seeds[*]}")
|
||||
|
||||
tendermint node --p2p.seeds="$seeds" --moniker="`hostname`" --proxy_app="unix:///socks/app.sock"
|
||||
volumeMounts:
|
||||
- name: tmdir
|
||||
mountPath: /tendermint
|
||||
- mountPath: /etc/tendermint/genesis.json
|
||||
name: tmconfigdir
|
||||
subPath: genesis.json
|
||||
- name: socksdir
|
||||
mountPath: /socks
|
||||
|
||||
- name: app
|
||||
imagePullPolicy: IfNotPresent
|
||||
image: tendermint/basecoin:0.5.1
|
||||
env:
|
||||
- name: BCHOME
|
||||
value: /app
|
||||
workingDir: /app
|
||||
command:
|
||||
- bash
|
||||
- "-c"
|
||||
- |
|
||||
set -ex
|
||||
|
||||
# replace "tm-N" with public keys in genesis file
|
||||
cp /etc/app/genesis.json genesis.json
|
||||
fqdn_suffix=$(hostname -f | sed 's#[^.]*\.\(\)#\1#')
|
||||
# for every "base/account"
|
||||
i=0
|
||||
length=$(cat genesis.json | jq ".app_options.accounts | length")
|
||||
while [[ $i -lt $length ]]; do
|
||||
# extract pod name ("tm-0")
|
||||
pod=$(cat genesis.json | jq -r ".app_options.accounts[$i].pub_key")
|
||||
|
||||
# wait until pod starts to serve its pub_key
|
||||
set +e
|
||||
|
||||
curl -s --fail "http://$pod.$fqdn_suffix/app_pub_key.json" > /dev/null
|
||||
ERR=$?
|
||||
while [ "$ERR" != 0 ]; do
|
||||
sleep 5
|
||||
curl -s --fail "http://$pod.$fqdn_suffix/app_pub_key.json" > /dev/null
|
||||
ERR=$?
|
||||
done
|
||||
set -e
|
||||
|
||||
# get its pub_key
|
||||
curl -s "http://$pod.$fqdn_suffix/app_pub_key.json" | jq "." > k.json
|
||||
|
||||
# replace pod name with it ("tm-0" => "{"type": ..., "data": ...}")
|
||||
cat genesis.json | jq ".app_options.accounts[$i].pub_key = $(cat k.json | jq '.')" > tmpgenesis && mv tmpgenesis genesis.json
|
||||
rm -f k.json
|
||||
|
||||
i=$((i+1))
|
||||
done
|
||||
|
||||
rm -f /socks/app.sock # remove old socket
|
||||
|
||||
basecoin start --address="unix:///socks/app.sock" --without-tendermint
|
||||
volumeMounts:
|
||||
- name: appdir
|
||||
mountPath: /app
|
||||
- mountPath: /etc/app/genesis.json
|
||||
name: appconfigdir
|
||||
subPath: genesis.json
|
||||
- name: socksdir
|
||||
mountPath: /socks
|
||||
|
||||
- name: pub-key
|
||||
imagePullPolicy: IfNotPresent
|
||||
image: nginx:latest
|
||||
ports:
|
||||
- containerPort: 80
|
||||
command:
|
||||
- bash
|
||||
- "-c"
|
||||
- |
|
||||
set -ex
|
||||
# fixes 403 Permission Denied (open() "/tendermint/pub_key.json" failed (13: Permission denied))
|
||||
# => we cannot serve from /tendermint, so we copy the file
|
||||
mkdir -p /usr/share/nginx
|
||||
cp /tendermint/pub_key.json /usr/share/nginx/pub_key.json
|
||||
cp /app/pub_key.json /usr/share/nginx/app_pub_key.json
|
||||
nginx -g "daemon off;"
|
||||
volumeMounts:
|
||||
- name: tmdir
|
||||
mountPath: /tendermint
|
||||
- name: appdir
|
||||
mountPath: /app
|
||||
- mountPath: /etc/nginx/conf.d/pub_key.conf
|
||||
name: tmconfigdir
|
||||
subPath: pub_key_nginx.conf
|
||||
|
||||
volumes:
|
||||
- name: tmconfigdir
|
||||
configMap:
|
||||
name: tm-config
|
||||
- name: appconfigdir
|
||||
configMap:
|
||||
name: app-config
|
||||
- name: socksdir
|
||||
emptyDir: {}
|
||||
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: tmdir
|
||||
annotations:
|
||||
volume.alpha.kubernetes.io/storage-class: anything
|
||||
spec:
|
||||
accessModes: [ "ReadWriteOnce" ]
|
||||
resources:
|
||||
requests:
|
||||
storage: 2Gi
|
||||
- metadata:
|
||||
name: appdir
|
||||
annotations:
|
||||
volume.alpha.kubernetes.io/storage-class: anything
|
||||
spec:
|
||||
accessModes: [ "ReadWriteOnce" ]
|
||||
resources:
|
||||
requests:
|
||||
storage: 12Mi
|
100
tools/mintnet-kubernetes/examples/basecoin/lightclient.md
Normal file
100
tools/mintnet-kubernetes/examples/basecoin/lightclient.md
Normal file
@ -0,0 +1,100 @@
|
||||
**OUTDATED**
|
||||
|
||||
# Using with lightclient
|
||||
|
||||
We have an awesome cluster running, let's try to test this out without
|
||||
relying on executing commands on the cluster. Rather, we can connect to the
|
||||
rpc interface with the `light-client` package and execute commands locally,
|
||||
or even proxy our webapp to the kubernetes backend.
|
||||
|
||||
## Setup
|
||||
|
||||
In order to get this working, we need to know a few pieces of info,
|
||||
the chain id of tendermint, the chain id of basecoin, and an account
|
||||
with a bit of cash....
|
||||
|
||||
### Tendermint Chain ID
|
||||
|
||||
`kubectl exec -c tm tm-0 -- curl -s http://tm-1.basecoin:26657/status | json_pp | grep network`
|
||||
|
||||
set TM_CHAIN with the value there
|
||||
|
||||
### Basecoin Chain ID
|
||||
|
||||
`kubectl exec -c app tm-1 -- grep -A1 chainID /app/genesis.json`
|
||||
|
||||
set BC_CHAIN with the value there
|
||||
|
||||
### Expose tendermint rpc
|
||||
|
||||
We need to be able to reach the tendermint rpc interface from our shell.
|
||||
|
||||
`kubectl port-forward tm-0 26657:26657`
|
||||
|
||||
### Start basecoin-proxy
|
||||
|
||||
Using this info, let's connect our proxy and get going
|
||||
|
||||
`proxy-basecoin -tmchain=$TM_CHAIN -chain=$BC_CHAIN -rpc=localhost:26657`
|
||||
|
||||
## Basecoin accounts
|
||||
|
||||
Well, we can connect, but we don't have a registered account yet...
|
||||
Let's look around, then use the cli to send some money from one of
|
||||
the validators to our client's address so we can play.
|
||||
|
||||
**TODO** we can add some of our known accounts (from `/keys`) into
|
||||
the genesis file, so we can skip all the kubectl money fiddling here.
|
||||
We will want to start with money on some known non-validators.
|
||||
|
||||
### Getting validator info (kubectl)
|
||||
|
||||
The basecoin app deployment starts with 1000 "blank" coin in an account of
|
||||
each validator. Let's get the address of the first validator
|
||||
|
||||
`kubectl exec -c app tm-1 -- grep address /app/key.json`
|
||||
|
||||
Store this info as VAL1_ADDR
|
||||
|
||||
### Querying state (proxy)
|
||||
|
||||
The proxy can read any public info via the tendermint rpc, so let's check
|
||||
out this account.
|
||||
|
||||
`curl localhost:8108/query/account/$VAL1_ADDR`
|
||||
|
||||
Now, let's make out own account....
|
||||
|
||||
`curl -XPOST http://localhost:8108/keys/ -d '{"name": "k8demo", "passphrase": "1234567890"}'`
|
||||
|
||||
(or pick your own user and password). Remember the address you get here. You can
|
||||
always find it out later by calling:
|
||||
|
||||
`curl http://localhost:8108/keys/k8demo`
|
||||
|
||||
and store it in DEMO_ADDR, which is empty at first
|
||||
|
||||
`curl localhost:8108/query/account/$DEMO_ADDR`
|
||||
|
||||
|
||||
### "Stealing" validator cash (kubectl)
|
||||
|
||||
Run one command, that will be signed, now we have money
|
||||
|
||||
`kubectl exec -c app tm-0 -- basecoin tx send --to <k8demo-address> --amount 500`
|
||||
|
||||
### Using our money
|
||||
|
||||
Returning to our remote shell, we have a remote account with some money.
|
||||
Let's see that.
|
||||
|
||||
`curl localhost:8108/query/account/$DEMO_ADDR`
|
||||
|
||||
Cool. Now we need to send it to a second account.
|
||||
|
||||
`curl -XPOST http://localhost:8108/keys/ -d '{"name": "buddy", "passphrase": "1234567890"}'`
|
||||
|
||||
and store the resulting address in BUDDY_ADDR
|
||||
|
||||
**TODO** finish this
|
||||
|
Reference in New Issue
Block a user