December 23, 2022

Near Node (Another Guide)

Выполняем команды по очереди, внимательно все копируя!

Требования к серверу

4 CPU

8 GB RAM

500 GB SSD

Лично я арендовала сервер на Hetzner CX51 и добавила 200 гб памяти (буду следить за использованием ресурсов) по стоимости вышло 40 евро.

Если хотите брать так, как я, то Вам необходимо объединить память в один диск - смотрите эту статью.

Первое задание

sudo apt update && sudo apt upgrade -y

curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -  

sudo apt install build-essential nodejs

PATH="$PATH"

node -v
#хороший ответ - v18.x.x

npm -v
#хороший ответ - 8.x.x

sudo npm install -g near-cli

npm install -g npm@8.16.0

export NEAR_ENV=shardnet

echo 'export NEAR_ENV=shardnet' >> ~/.bashrc

echo 'export NEAR_ENV=shardnet' >> ~/.bash_profile

source $HOME/.bash_profile

Второе задание

lscpu | grep -P '(?=.*avx )(?=.*sse4.2 )(?=.*cx16 )(?=.*popcnt )' > /dev/null \
  && echo "Supported" \
  || echo "Not supported"
#правильный вывод команды - Supported

sudo apt install -y git binutils-dev libcurl4-openssl-dev zlib1g-dev libdw-dev libiberty-dev cmake gcc g++ python3 docker.io protobuf-compiler libssl-dev pkg-config clang llvm cargo
Устанавливаем python pip (репозиторий библиотек для python):
sudo apt install python3-pip
USER_BASE_BIN=$(python3 -m site --user-base)/bin

export PATH="$USER_BASE_BIN:$PATH"
Устанавливаем тулзы для билда
sudo apt install clang build-essential make
Устанавливаем раст и карго
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
#нажимаем y и потом 1
source $HOME/.cargo/env

Копируем nearcore проект с GitHub

git clone https://github.com/near/nearcore

cd nearcore

git fetch

Коммитим

git checkout <commit>
#заменить <commit> на значение из файла, по ссылке ниже

Брать номер коммита от сюда

Компилируем бинарники nearcore

cargo build -p neard --release --features shardnet

Создание рабочей директории

./target/release/neard --home ~/.near init --chain-id shardnet --download-genesis

Этим шагом была создана директория .near и в ней такие файлы: config.json, node_key.json, genesis.json

  • config.json - Параметры конфигурации, которые отвечают за то, как будет работать узел. config.json содержит необходимую информацию для работы узла в сети ( как общаться с одноранговыми узлами и как достичь консенсуса). Некоторые параметры настраиваются.
  • genesis.json - Файл со всеми данными, с которых началась сеть. Он содержит начальные учетные записи, контракты, ключи доступа и другие записи, которые представляют начальное состояние блокчейна.
  • node_key.json - Файл, который содержит открытый и закрытый ключ для узла. Также включает параметр account_id, необходимый для запуска узла валидатора.
  • data/ - Папка, в которую узел NEAR будет записывать свое состояние.

Находятся эти файлы по такому пути: cd /root/.near/

Перемещаем config.json

Удаляем старый конфиг файл и выкачиваем с гитхаба актуальный:

rm ~/.near/config.json
wget -O ~/.near/config.json https://s3-us-west-1.amazonaws.com/build.nearprotocol.com/nearcore-deploy/shardnet/config.json

Устанавливаем AWS Cli

sudo apt-get install awscli -y

Запускаем ноду

cd ~/nearcore

./target/release/neard --home ~/.near run

#Из важного - должны подцепиться пиры (>0) и загрузиться хедеры (ждем 100%)
#Только потом идем дальше по гайду!
#выходим - Ctrl+C

Создаем сервисный файл, что бы наша нода работала не только при ручном запуске, а и в фоновом режиме:

sudo tee /etc/systemd/system/neard.service > /dev/null <<EOF

Вставляем одной командой:

[Unit]
Description=NEARd Daemon Service

[Service]
Type=simple
User=$USER
#Group=near
WorkingDirectory=/root/.near
ExecStart=/root/nearcore/target/release/neard run
Restart=on-failure
RestartSec=30
KillSignal=SIGINT
TimeoutStopSec=45
KillMode=mixed

[Install]
WantedBy=multi-user.target
EOF

Закрываем терминал и открываем заново, что бы все фоновые процессы стопнулись.

Запускаем сервисный файл:

sudo systemctl daemon-reload

sudo systemctl enable neard

sudo systemctl restart neard

sudo systemctl status neard

Теперь устанавливаем "ccze", тулза, необходимая для красивого отображения логов:

sudo apt install ccze

Просмотр логов:

journalctl -n 100 -f -u neard | ccze -A

На этом этапе нода установлена и работает! Теперь нам необходимо создать кошелек, валидатора и застейкать монет:


Останавливаем сервис:

sudo systemctl stop neard

sudo systemctl disable neard

Создаем кошелек тут
Идем в терминал:

near login

Нам среди прочего текста выдаст ссылку - копируем ее и вставляем во вкладку браузера, где вы залогинились в свой кошелек, даем доступ, перекинет на пустую страницу - отлично, идем в терминал - вписываем имя кошелька (выглядит так: ХХ.shardnet.near). Далее я буду называть "ХХ" - именем!

Создаем файл validator_key.json
  • Генерируем ключ:
near generate-key <pool_id>.factory.shardnet.near
#заменить <pool_id> на имя ХХ
  • Копируем созданный файл в файл validator_key.json
cp ~/.near-credentials/shardnet/<pool_id>.factory.shardnet.near.json ~/.near/validator_key.json
#заменить <pool_id> на имя ХХ

Теперь необходимо отредактировать только-что созданный файл(аккуратно работаем с вим, задаем в чатике вопросы, если что-то не помним):

vi ~/.near/validator_key.json
  • Меняем “account_id” на ХХ.factory.shardnet.near, где ХХ - имя
  • Меняем private_key на secret_key

Вот так будет выглядеть Ваш файл:

{
  "account_id": "xx.factory.shardnet.near",
  "public_key": "ed25519:HeaBJ3xLgvZacQWmEctTeUqyfSU4SDEnEwckWxd92W2G",
  "secret_key": "ed25519:****"
}

Проверить правильность изменения файла, не заходя в вим:

cat ~/.near/validator_key.json

Задание 3
Создаем стейкинг пул

near call factory.shardnet.near create_staking_pool '{"staking_pool_id": "<pool name>", "owner_id": "<accountId>", "stake_public_key": "<public key>", "reward_fee_fraction": {"numerator": 5, "denominator": 100}, "code_hash":"DD428g9eqLL8fWUxv8QSpVFzyHi1Qd16P8ephYCTmMSZ"}' --accountId="<accountId>" --amount=30 --gas=300000000000000
#<pool name> - XX
#<accountId> - XX.shardnet.near
#<public key> - берем из файла validator_key.json

Выполнив эту команду - Вы уже застейкаете минимальное количество токенов (30) в свой пул, если хотите застейкать еще:

near call <pool_id> deposit_and_stake --amount <amount> --accountId <accountId> --gas=300000000000000
#<pool_id> - XX.factory.shardnet.near
#<amount> - количество токенов, которое хотите застейкать
#<accountId> - XX.shardnet.near

Задание 4

В этом задании нам необходимо познакомится с мониторингом ноды и установить RPC на порт 3030.

Проверка логов:

journalctl -n 100 -f -u neard | ccze -A

RPC

Обычно RPC используется для проверки статистики валидатора, версии узла и просмотра доли делегатора, хотя его можно использовать для взаимодействия с блокчейном, учетными записями и контрактами в целом.

Подробнее о многих командах и о том, как их использовать, можно узнать здесь:

https://docs.near.org/api/rpc/introduction

Для работы RPC необходимо открыть порт 3030 (сразу откроем еще несколько, которые могут Вам понадобиться для дальнейших заданий)
Сервис должен быть остановлен (или его потом нужно будет перезапустить для правильной работы):

sudo ufw allow 22

sudo ufw allow 3030

sudo ufw allow 9090

sudo ufw allow 3000

sudo ufw allow 24567

sudo ufw enable

Проверяем открыты ли порты:

Идем на любой сайт из гугла по запросу "проверить открыты ли порты на сервере", например этот, вводим свой айпи и нужный порт.

Устанавливаем вспомогательную тулзу JQ

sudo apt install curl jq

Проверить версию вашего узла:

curl -s http://127.0.0.1:3030/status | jq .version
Проверяйте делегатов и делайте ставки
near view <your pool>.factory.shardnet.near get_accounts '{"from_index": 0, "limit": 10}' --accountId <accountId>.shardnet.near

Проверить причину отказа валидатора

curl -s -d '{"jsonrpc": "2.0", "method": "validators", "id": "dontcare", "params": [null]}' -H 'Content-Type: application/json' 127.0.0.1:3030 | jq -c '.result.prev_epoch_kickout[] | select(.account_id | contains ("<POOL_ID>"))' | jq .reason
#<POOL_ID> - заменить на XX.factory.shardnet.near

Проверить блоки, произведенные / ожидаемые

curl -r -s -d '{"jsonrpc": "2.0", "method": "validators", "id": "dontcare", "params": [null]}' -H 'Content-Type: application/json' 127.0.0.1:3030 | jq -c '.result.current_validators[] | select(.account_id | contains ("<POOL_ID>"))'

Задание 5

В этом задании необходимо написать свой собственный гайд, в котором детально описать как выполнять задания 1-4. Разместить свою статью на популярном ресурсе, например Медиум. Это задание нужно отправить на проверку, заполнив форму. В нее нужно прикрепить ссылку на Вашу статью.

Задание 6

В этом задании нужно создать скрипт, который будет подавать Ваш пул в активный сет валидаторов, а так же настроить джобу.

Для начала создаем папку/директорию, в которой будет храниться файл со скриптом и директорию для логов:

mkdir /root/scripts

mkdir /root/logs

Далее создаем файл скрипта ping.sh:

vi /root/scripts/ping.sh

Открывается редактор файла, в него вставляем:

#!/bin/sh
# Ping call to renew Proposal added to crontab

export NEAR_ENV=shardnet
export LOGS=/root/logs
export POOLID=<YOUR_POOL_ID>
export ACCOUNTID=<YOUR_ACCOUNT_ID>

echo "---" >> $LOGS/all.log
date >> $LOGS/all.log
near call $POOLID.factory.shardnet.near ping '{}' --accountId $ACCOUNTID.shardnet.near --gas=300000000000000 >> $LOGS/all.log
near proposals | grep $POOLID >> $LOGS/all.log
near validators current | grep $POOLID >> $LOGS/all.log
near validators next | grep $POOLID >> $LOGS/all.log
#<YOUR_POOL_ID> - заменить на имя ХХ
#<YOUR_ACCOUNT_ID> - заменить на имя ХХ

Добавляем нашему файлу право на исполнение:

chmod +x root/scripts/ping.sh

Создаем джобу. Джоба - это некое задание, которое будет выполняться раз в определенное время. В нашем случае будет исполняться скрипт ping.sh раз в два часа:

crontab -e

Откроется вим, в него вставляем следующую строку:

0 */2 * * * sh /root/scripts/ping.sh

Просмотр логов джобы(будут видны хоть какие-то логи после того, как хотя бы 1 раз выполнится джоба):

cat root/logs/all.log

Нужно отправить отчет о выполнении задания в эту форму. В нее нужно прикрепить ссылку с эксплорера на Ваш пул и скрин из этого же эксплорера, где видно, что метод пинг вызывается каждые 2 часа(пример скрина ниже)

Задание 7

В этом задании нужно провести работу с данными, которые генерирует блокчейн. Тут нет строгих критериев, лично я попробую выполнить это задание, используя прометеус и графану. Постараюсь написать гайд по этому заданию отдельно. А пока даю Вам ссылку на оф доки с описанием задания, если у Вас есть идеи и навыки - дерзайте! Удачи!)

Задание 8

В этом задании необходимо развернуть смарт-контракт, который позволит разделить награды на два аккаунта.

Устанавливаем wasm32-unknown-unknow:

rustup target add wasm32-unknown-unknown

Выкачиваем проект с гит хаба:

git clone https://github.com/zavodil/near-staking-pool-owner

Компилируем смарт-контракт:

cd near-staking-pool-owner/contract

cargo build --target wasm32-unknown-unknown --release

Деплоим в свой аккаунт:
При необходимости измените путь к файлу .wasm

NEAR_ENV=shardnet near deploy <OWNER_ID>.shardnet.near --wasmFile target/wasm32-unknown-unknown/release/contract.wasm
#<OWNER_ID> - заменить на имя ХХ

Инициализируем учетные записи смарт-контрактов для разделения доходов:

CONTRACT_ID=<OWNER_ID>.shardnet.near
#<OWNER_ID> - заменить на имя ХХ

NEAR_ENV=shardnet near call $CONTRACT_ID new '{"staking_pool_account_id": "<STAKINGPOOL_ID>.factory.shardnet.near", "owner_id":"<OWNER_ID>.shardnet.near", "reward_receivers": [["<SPLITED_ACCOUNT_ID_1>.shardnet.near", {"numerator": 3, "denominator":10}], ["<SPLITED_ACCOUNT_ID_2>.shardnet.near", {"numerator": 70, "denominator":100}]]}' --accountId $CONTRACT_ID
#<STAKINGPOOL_ID> - заменить на имя ХХ
#<OWNER_ID> - заменить на имя ХХ
#<SPLITED_ACCOUNT_ID_1> - заменить на имя первогокошелька
#<SPLITED_ACCOUNT_ID_2> - заменить на имя нового 2го кошелька
#поменяйте значения numerator/denomitor, если хотите изменить процент распределения наград между кошельками

Подождите, пока Вы начнете получать награды от своего стейкинг пула. Выведите часть наград:

CONTRACT_ID=<OWNER_ID>.shardnet.near
#<OWNER_ID> - заменить на имя ХХ

NEAR_ENV=shardnet 

near call $CONTRACT_ID withdraw '{}' --accountId $CONTRACT_ID --gas 200000000000000

Для подтверждения выполнения задания нужно заполнить форму. В нее нужно прикрепить ссылку на транзакцию вывода наград и скриншот из терминала выполнения данной транзакции(как ниже на скрине):

Задание 9

Для этого задания необходимо пробраться в активный сет валидаторов, производить блоки и иметь аптайм не менее 70%.

  1. Убедитесь, что порт 3030 открыт на Вашем сервере

Для того, что бы отчитаться за задние нужно заполнить форму, в которую прикрепить ссылку http://<IP Address>:3030/status (заменить на свой айпи) и скрин с этого сайта, где видно, что Ваш аптайм выше 70%

Задание 10

Тут нам делать ничего не нужно, это просто делегация токенов от команды тем нодам, у которых аптайм выше 60% за последние эпохи

Задание 13

Тут нужно сделать бэкап ноды, ставим 2ю ноду либо в другую папку, либо на новый сервис, потом идем в старую ноду:

ЕСЛИ она на другом сервере: заходим через файловую сессию, качаем себе файлы validator_key.json и node_key.json (папка .near) и копируем их в папку root на новом сервере
ЕСЛИ она та том же сервере: находим файлы validator_key.json и node_key.json (папка .near) и просто запоминаем к ним путь

Теперь в терминал новой ноды(выполняем команды внимательно, так как нужно будет отправить скрин в отчет выполнения всех этих команд подряд):

cd .near

cat node_key.json | grep public_key

sudo systemctl stop neard

rm node_key.json

cp <PATH>/node_key.json /root/.near

cp <PATH>/validator_key.json /root/.near

#заменить <PATH> на путь к файлу
#пример(если вы положили в папку рут файл): cp /root/node_key.json /root/.near

cat node_key.json | grep public_key

sudo systemctl start neard

journalctl -n 100 -f -u neard | ccze -A
Отчет: вот такой скрин, желательно одной фоткой)) форма другая тут

Задание 14

Написать скрипт для авто бэкапа ноды

Идем в терминал:

создаем директорию:

mkdir /root/reserve

Создаем скрипт, который будет делать бекап(перед этим получить необходимый урл, как - описано ниже):

vi backup.sh
#откроется вим

Копируем полностью и вставляем:

#!/bin/bash
DATE=$(date +%Y-%m-%d-%H-%M)
DATADIR=/root/.near/data
BACKUPDIR=/root/reserve/near_${DATE}
rm -rf /root/reserve/*
mkdir $BACKUPDIR
sudo systemctl stop neard
wait 5
echo "NEAR node was stopped"
if [ -d "$BACKUPDIR" ]; then
echo "Backup started"
cp -rf $DATADIR ${BACKUPDIR}/
tar -cvf /root/reserve/near_${DATE}.tar $BACKUPDIR
rm -rf /root/reserve/near_${DATE}
curl -fsS -m 10 --retry 5 -o /dev/null <URL>
echo "Backup completed"
else
echo $BACKUPDIR is not created. Check your permissions.
exit 0
fi
sudo systemctl start neard
echo "NEAR node was started"
#заменить <URL> на свой
#сохраняем и выходим из вима

Как получить урл?
В этом задании мы должны настроить джобу, которая будет выполнять скрипт бекапа раз в определенное время, в скрипте есть строка, которая отправляет информацию в сервис https://healthchecks.io/ , он в свою очередь умеет оповещать Вас по почте в том случае, если он не получил нужную информацию. Получается такая схема:

  • каждый день выполняется джоба в заданное время
  • джоба будет выполнять написанный скрипт
  • одной из команд в скрипте - отправка информации HealthCheks
  • если HealthCheks не получил информацию вовремя - значит скрипт не выполнился - он пришлет оповещение, что что-то не так

Идем на сайт https://healthchecks.io/

Регистрируемся, вписываем почту, на почту прийдет письмо, переходим по ссылке из него, видим такое:

Ссылка посередине скрина - необходимая Вам, копируем ее и вставляем в скрипт вместо <URL>

Теперь нужно настроить крон табу (для отчета это не требуется, но если вы хотите, что бы скрипт бекапа работал на вашем сервере - делайте)

crontab -e
#откроется вим, добавляем туда строку ниже

0  12 *  *  * sh /root/backup.sh >> /root/backup.log 2>&1
Отчет: для отчета нужно закоммитить этот скрипт на ваш гитхаб(7й урок и методичка Вам в помощь, однако не нужно компилировать его) и добавить ссылку на репозиторий в отчет. форма другая тут

Задание 15

Настроить NEAR Validator kuutamo

Задание 16

В этом задании нам предлагают настроить оповещения на почту, со следующим текстом: "Баланс Вашего валидатора "имя валидатора" на данный момент "кол-во" ниаров"

Пометка: будет работать этот скрипт в том случае, если у вас на сервере настроены нод экспрортеры и прометеус.

Для начала идем в дискорд проекта Notifi, ветка #integration-requests, заполняем форму на получение креденций, они прийдут Вам на почту, когда менеджер обработает запрос.

Создаем директорию для будущего скрипта, я ее создала в папке /root/scripts:

mkdir notifi

cd notifi

Инициализируем node.js проекта:

npm init -y

Устанавливаем зависимости:

npm install typescript --save-dev

npm install @types/node --save-dev

Создаем конфиг файл(копируем одной командой):

npx tsc --init --rootDir src --outDir build \
--esModuleInterop --resolveJsonModule --lib es6 \
--module commonjs --allowJs true --noImplicitAny true

Создаем папку и файл тайпскрипта:

mkdir src

touch src/index.ts

Правим конфиг:

vi tsconfig.json
#добавлем: , "DOM" в поле "lib", как на скрине

Теперь берем скрипт (у меня в телеграмме) и кладем его в директорию /root/scripts/notifi/src
Заходим в него через вим и меняем на свои значения:

cd /root/scripts/notifi/src

vi index.ts
#меняем <NAME> на свое значение XX.factory.shardnet.near
#меняем <URL> на свое значение
#меняем <SID> на свое значение
#меняем <SECRET> на свое значение
#меняем <TOPIC> на свое значение

Правим конфиг:

cd /root/scripts/notifi

vi package.json
#в итоге должен выглядеть так, как на скрине ниже

Устанавливаем доп тулзы:

sudo npm i @notifi-network/notifi-node

Запускаем билд и скрипт:

npm run start

Идем на почту и смотрим результат!

Отчет: заполняем эту форму, в нее отправляем скрин присланного письма от Notifi

Задание 18

Тут нужно доработать нашу графану вот такими показателями:

Block Height - near_block_height_head
Total Transactions - near_transaction_processed_successfully_total
Block Processed - rate(near_block_processed_total[$__rate_interval])
Blocks Per Minute - near_blocks_per_minute
Validators - near_is_validator - near_validator_active_total
Chunk - histogram_quantile(0.95, sum(rate(near_chunk_tgas_used_hist_bucket[$__rate_interval])) by (le))
Block Processing - rate(near_block_processing_time_count[$__rate_interval])
Transactions Pool Entries - near_transaction_pool_entries
Blocks Per Minute - near_blocks_per_minute
Processed Total Transactions - rate(near_transaction_processed_total[$__rate_interval])
Processed Successfully Transactions - rate(near_transaction_processed_successfully_total[$__rate_interval])
Reachable Peers - near_peer_reachable
Chunk Tgas Used - near_chunk_tgas_used
Block Processing Time Count - rate(near_block_processing_time_count[$__rate_interval])
Node is validator
Missed blocks
Percent of produced blocks
Missed chunks
Percent of produced chunks
Connected peers
Total validator stake

А так же показатели вашего "железа"

Отчет: форма вот тут

Команды

Посмотреть proposals:

near proposals
#A proposal by a validator indicates they would like to enter the validator set, in order for a proposal to be accepted it must meet the minimum seat price.

Посмотреть текущих валидаторов:

near validators current
#This shows a list of active validators in the current epoch, the number of blocks produced, number of blocks expected, and online rate. Used to monitor if a validator is having issues.

Посмотреть валидаторов следующей эпохи:

near validators next
#This shows validators whose proposal was accepted one epoch ago, and that will enter the validator set in the next epoch.
Депозит и стейк токенов:
near call <pool_id> deposit_and_stake --amount <amount> --accountId <accountId> --gas=300000000000000
Анстейк токенов:

Количество указывается в yoctoNEAR.

near call <pool_id> unstake '{"amount": "<amount yoctoNEAR>"}' --accountId <accountId> --gas=300000000000000

Что бы анстейкнуть все, что доступно:

near call <pool_id> unstake_all --accountId <accountId> --gas=300000000000000
Вывод на кошелек доступных(анстейкнутых токенов):

Анстейкинг занимает 2-3 эпохи

near call <pool_id> withdraw '{"amount": "<amount yoctoNEAR>"}' --accountId <accountId> --gas=300000000000000

Что бы вывести все доступные токены:

near call <pool_id> withdraw_all --accountId <accountId> --gas=300000000000000
Посмотреть баланс пула:
near view <pool_id> get_account_total_balance '{"account_id": "<accountId>"}'
Посмотреть анстейкнутый баланс пула:
near view <pool_id> get_account_unstaked_balance '{"account_id": "<accountId>"}'
Посмотреть баланс, доступный, для вывода:
near view <pool_id> is_account_unstaked_balance_available '{"account_id": "<accountId>"}'
Пауза в стейкинге:
near call <pool_id> pause_staking '{}' --accountId <accountId>
Продолжить стейкинг:
near call <pool_id> resume_staking '{}' --accountId <accountId>

Изменить процент за стейкинг:

near call <pool_id> update_reward_fee_fraction '{"reward_fee_fraction": {"numerator": 1, "denominator": 100}}' --accountId <account_id> --gas=300000000000000