3. SAFE HARBOR
• Следующий доклад предназначен для
описания нашего общего направления в
разработке.
2
4. SAFE HARBOR
• Следующий доклад предназначен для
описания нашего общего направления в
разработке.
• Он предназначен только для информационных
целей.
2
5. SAFE HARBOR
• Следующий доклад предназначен для
описания нашего общего направления в
разработке.
• Он предназначен только для информационных
целей.
• На этот доклад не следует полагаться при
принятии решений о построении схожего
решения.
2
8. О себе
• Меня зовут Александр.
• Scala Software Engineer в Aeneas. Заодно и студент в КНУ
им. Шевченка !.
3
9. О себе
• Меня зовут Александр.
• Scala Software Engineer в Aeneas. Заодно и студент в КНУ
им. Шевченка !.
• Пишу на Scala (по работе и в свободное время), Java,
Kotlin, Haskell/Idris, JS и С++. Изучаю Rust.
3
10. О себе
• Меня зовут Александр.
• Scala Software Engineer в Aeneas. Заодно и студент в КНУ
им. Шевченка !.
• Пишу на Scala (по работе и в свободное время), Java,
Kotlin, Haskell/Idris, JS и С++. Изучаю Rust.
• Contributor в open-source проекты, такие как Scorex,
Korolev (Scala), TeaVM (Java).
3
11. О себе
• Меня зовут Александр.
• Scala Software Engineer в Aeneas. Заодно и студент в КНУ
им. Шевченка !.
• Пишу на Scala (по работе и в свободное время), Java,
Kotlin, Haskell/Idris, JS и С++. Изучаю Rust.
• Contributor в open-source проекты, такие как Scorex,
Korolev (Scala), TeaVM (Java).
• Пристально слежу за разработкой виртуальных машин и
операционных систем и собираюсь делать вклад в это в
будущем.
3
16. Aeneas
• Aeneas - это публичная
модульная blockchain-
платформа.
• Её первостепенными
функциями являются:
инициирование проектов
добровольной финансовой
поддержки, размещение
заявок на политическое
лоббирование и
возможность их
исполнения лоббистскими
группами.
5
18. • Строгая статическая типизация.
• Сильная ФП-составляющая языка.
• Лаконичность языка.
• Совместимость с Java на уровне исходников.
• Масштабируемость языка (Scalable).
• Под капотом - JVM.
6
20. • Акторы - сущности, напоминающие потоки.
• Но главное отличие - у каждого актора своя
память.
• Общение путем передачи сообщений.
• Удобная сериализация.
• Дополнительно получаем кучу удобных методов
работы с различными сетевыми протоколами.
7
24. Почему Scorex 2?
• Модульность.
• Akka & Akka-TCP под капотом.
• Небольшой объём кодовой базы.
8
25. Почему Scorex 2?
• Модульность.
• Akka & Akka-TCP под капотом.
• Небольшой объём кодовой базы.
• Легко разобраться, с чего начать.
8
26. Почему Scorex 2?
• Модульность.
• Akka & Akka-TCP под капотом.
• Небольшой объём кодовой базы.
• Легко разобраться, с чего начать.
• Широкий выбор сопутствующих вспомогательных
инструментов (БД, библиотека криптоалгоритмов).
8
27. Почему Scorex 2?
• Модульность.
• Akka & Akka-TCP под капотом.
• Небольшой объём кодовой базы.
• Легко разобраться, с чего начать.
• Широкий выбор сопутствующих вспомогательных
инструментов (БД, библиотека криптоалгоритмов).
• Знакомые разработчики "
8
36. Баг подкрался незаметно
• … и не один.
• Посему данный доклад предназначен облегчить
жизнь всем, кто хочет попробовать сделать
blockchain на Scala + Scorex, и не наступить на
те грабли, что наступали (и продолжаем
наступать) мы.
12
41. 1. lazy
class SimpleBlockChain(loadSettings: LoadSettings)
extends Application with ScorexLogging {
//…
// Note : NEVER NEVER forget to mark override & implicit as LAZY!
override implicit lazy val settings = SimpleSettings.read().scorexSettings
override val nodeViewHolderRef: ActorRef = actorSystem.actorOf(
Props(new AeneasNodeViewHolder(settings, simpleSettings.miningSettings)))
}
15
42. 1. lazy
class SimpleBlockChain(loadSettings: LoadSettings)
extends Application with ScorexLogging {
//…
// Note : NEVER NEVER forget to mark override & implicit as LAZY!
override implicit lazy val settings = SimpleSettings.read().scorexSettings
override val nodeViewHolderRef: ActorRef = actorSystem.actorOf(
Props(new AeneasNodeViewHolder(settings, simpleSettings.miningSettings)))
}
• Не забывайте о lazy для перегружаемых и
имплицитных свойств!
15
44. 2. Запуск нескольких узлов
• Для отладки (да и для работы, собственно) вам
наверняка понадобится запускать несколько
экземпляров узлов.
16
45. 2. Запуск нескольких узлов
• Для отладки (да и для работы, собственно) вам
наверняка понадобится запускать несколько
экземпляров узлов.
• И тут помехой вам стаёт … sbt :
[error] server failed to start on 127.0.0.1:4714. java.net.BindException:
Address already in use.
16
46. 2. Запуск нескольких узлов
• Для отладки (да и для работы, собственно) вам
наверняка понадобится запускать несколько
экземпляров узлов.
• И тут помехой вам стаёт … sbt :
[error] server failed to start on 127.0.0.1:4714. java.net.BindException:
Address already in use.
• Он не способен запускать несколько
экземпляров «себя», и это давняя история.
16
48. 2. Запуск нескольких узлов
• Немного погуглив, мы забили на попытки
запустить sbt, а вспомнили об отличном
компоновочном универсальном туле под
названием make.
17
49. 2. Запуск нескольких узлов
• Немного погуглив, мы забили на попытки
запустить sbt, а вспомнили об отличном
компоновочном универсальном туле под
названием make.
• Сборка решения в jar-файл, запуск и очистка
происходит в специальном Makefile.
17
50. 2. Запуск нескольких узлов
• Немного погуглив, мы забили на попытки
запустить sbt, а вспомнили об отличном
компоновочном универсальном туле под
названием make.
• Сборка решения в jar-файл, запуск и очистка
происходит в специальном Makefile.
• Также, если критичны логи в режиме реального
времени, можно запускать решения из Вашей
IDE (IntelliJ IDEA в нашем случае).
17
52. 3. Синхронизация цепочек
• После консенсуса или в случае минутного
простоя надо синхронизировать всю активную
сеть.
18
53. 3. Синхронизация цепочек
• После консенсуса или в случае минутного
простоя надо синхронизировать всю активную
сеть.
• Для этого мы используем некое подобие
активного кэша в виде списка id-шников
последних 50 блоков. Известна эта структура в
Scorex 2 как SyncInfo.
18
59. 3. Синхронизация цепочек
• Мы рекомендуем сравнивать SyncInfo
пришедший c другого пира и SyncInfo
текущего узла, который можно получить,
вызвав метод syncInfo().
21
60. 3. Синхронизация цепочек
• Мы рекомендуем сравнивать SyncInfo
пришедший c другого пира и SyncInfo
текущего узла, который можно получить,
вызвав метод syncInfo().
• Это не так очевидно, к сожалению, так как в
других проектах используется перебор истории
(оверхед по памяти) и другие более экзотичные
способы.
21
62. 4. Работа с сетью
• Реализация работы с TCP присутствует! ☺
22
63. 4. Работа с сетью
• Реализация работы с TCP присутствует! ☺
• Сперва мы по недосмотру ринулись
реализовывать свой велосипед.
22
64. 4. Работа с сетью
• Реализация работы с TCP присутствует! ☺
• Сперва мы по недосмотру ринулись
реализовывать свой велосипед.
• Но очередная ревизия кода помогла нам не
идти этим путем.
22
65. 4. Работа с сетью
• Реализация работы с TCP присутствует! ☺
• Сперва мы по недосмотру ринулись
реализовывать свой велосипед.
• Но очередная ревизия кода помогла нам не
идти этим путем.
• Из минусов - много тудушек в коде, и полное
отсутствие документации.
22
67. 4. Работа с сетью :
крупно (1)
• NetworkController – ключевой класс при работе
с сетью, ему подконтрольны все события,
происходящие с сетью.
23
68. 4. Работа с сетью :
крупно (1)
• NetworkController – ключевой класс при работе
с сетью, ему подконтрольны все события,
происходящие с сетью.
• PeerManager – контроль за подключениями.
23
69. 4. Работа с сетью :
крупно (1)
• NetworkController – ключевой класс при работе
с сетью, ему подконтрольны все события,
происходящие с сетью.
• PeerManager – контроль за подключениями.
• PeerConnectionHandler – держатель логики
процесса подключения пиров.
23
70. 4. Работа с сетью :
крупно (1)
• NetworkController – ключевой класс при работе
с сетью, ему подконтрольны все события,
происходящие с сетью.
• PeerManager – контроль за подключениями.
• PeerConnectionHandler – держатель логики
процесса подключения пиров.
• SendingStrategy – стратегия посылки сообщений.
23
78. 5. Первый запуск нового узла
в функционирующей сети
Для того, чтобы полноценным узлом
можно было пользоваться, необходимо
скачать полную(!) копию валидного(!!!)
блокчейна.
25
80. Проблема №1 :
поиск пиров
• Мы временно счастливо забили на это дело $
26
81. Проблема №1 :
поиск пиров
• Мы временно счастливо забили на это дело $
• Дело в том, что для начальных этапов мы
введем так называемые well-known пиры,
которые будут такими же участниками сети, но
будут иметь право раздавать валидный
блокчейн.
26
82. Проблема №1 :
поиск пиров
• Мы временно счастливо забили на это дело $
• Дело в том, что для начальных этапов мы
введем так называемые well-known пиры,
которые будут такими же участниками сети, но
будут иметь право раздавать валидный
блокчейн.
• С процессом распространения платформы мы
будем валидировать проявившие себя узлы.
26
84. Проблема №2 :
процесс скачивания
• Было преодолено много боли, но мы в итоге с
помощью знаний из пункта №4 таки разработали
скачивание при начале работы полного узла.
27
85. Проблема №2 :
процесс скачивания
• Было преодолено много боли, но мы в итоге с
помощью знаний из пункта №4 таки разработали
скачивание при начале работы полного узла.
• В первую очередь, надо было обойти навязанный
нам способ инициализации локального узла :
private var nodeView : NodeView = restoreState()
.getOrElse(genesisState)
27
88. Что у нас в планах
• Наладить интеграционное тестирование.
29
89. Что у нас в планах
• Наладить интеграционное тестирование.
• Имплементация консенсуса.
29
90. Что у нас в планах
• Наладить интеграционное тестирование.
• Имплементация консенсуса.
• Имплементация транзакций и включение их в
блоки.
29
91. Что у нас в планах
• Наладить интеграционное тестирование.
• Имплементация консенсуса.
• Имплементация транзакций и включение их в
блоки.
• Возможно, какой-то research относительно
уплотнения хранилища (AVL-trees, но это не
точно).
29