Skip to content

Commit

Permalink
Merge pull request #1576 from ergoplatform/v4.0.22
Browse files Browse the repository at this point in the history
Candidate for version 4.0.22
  • Loading branch information
kushti authored Jan 28, 2022
2 parents 0e8ac97 + a149454 commit f38f3a6
Show file tree
Hide file tree
Showing 56 changed files with 751 additions and 436 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ To run specific Ergo version `<VERSION>` as a service with custom config `/path/
-e MAX_HEAP=3G \
ergoplatform/ergo:<VERSION> --<networkId> -c /etc/myergo.conf

Available versions can be found on [Ergo Docker image page](https://hub.docker.com/r/ergoplatform/ergo/tags), for example, `v4.0.21.1`.
Available versions can be found on [Ergo Docker image page](https://hub.docker.com/r/ergoplatform/ergo/tags), for example, `v4.0.22`.

This will connect to the Ergo mainnet or testnet following your configuration passed in `myergo.conf` and network flag `--<networkId>`. Every default config value would be overwritten with corresponding value in `myergo.conf`. `MAX_HEAP` variable can be used to control how much memory can the node consume.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ object UtxoStateBenchmark extends HistoryTestHelpers with NVBenchmark {
val transactionsQty = blocks.flatMap(_.transactions).size

def bench(mods: Seq[ErgoPersistentModifier]): Long = {
val state = ErgoState.generateGenesisUtxoState(createTempDir, StateConstants(None, realNetworkSetting), parameters)._1
val state = ErgoState.generateGenesisUtxoState(createTempDir, StateConstants(realNetworkSetting), parameters)._1
Utils.time {
mods.foldLeft(state) { case (st, mod) =>
st.applyModifier(mod).get
st.applyModifier(mod)(_ => ()).get
}
}.toLong
}
Expand Down
15 changes: 14 additions & 1 deletion src/main/resources/api/openapi.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
openapi: "3.0.2"

info:
version: "4.0.21.1"
version: "4.0.22"
title: Ergo Node API
description: API docs for Ergo Node. Models are shared between all Ergo products
contact:
Expand Down Expand Up @@ -426,6 +426,7 @@ components:
items:
anyOf:
- $ref: '#/components/schemas/PaymentRequest'
- $ref: '#/components/schemas/BurnTokensRequest'
- $ref: '#/components/schemas/AssetIssueRequest'
fee:
description: Transaction fee
Expand Down Expand Up @@ -1114,6 +1115,18 @@ components:
registers:
$ref: '#/components/schemas/Registers'

BurnTokensRequest:
description: Request for burning tokens in wallet
type: object
required:
- assetsToBurn
properties:
assetsToBurn:
description: Assets list to burn in the transaction
type: array
items:
$ref: '#/components/schemas/Asset'

AssetIssueRequest:
description: Request for generation of asset issue transaction
type: object
Expand Down
24 changes: 2 additions & 22 deletions src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ ergo {
keepVersions = 200

# Acceptable difference between NOW and timestamp of the latest chain update or best block. This helps to discover syncing issues.
acceptableChainUpdateDelay = 15m
acceptableChainUpdateDelay = 30m

# Maximum number of unconfirmed transactions node can accept
mempoolCapacity = 1000
Expand Down Expand Up @@ -345,7 +345,7 @@ scorex {
nodeName = "ergo-node"

# Network protocol version to be sent in handshakes
appVersion = 4.0.21.1
appVersion = 4.0.22

# Network agent name. May contain information about client code
# stack, starting from core code-base up to the end graphical interface.
Expand Down Expand Up @@ -522,24 +522,4 @@ api-dispatcher {
# processed per actor before the thread jumps to the next actor.
# Set to 1 for as fair as possible.
throughput = 4
}

network-dispatcher {
# Dispatcher is the name of the event-based dispatcher
type = Dispatcher
# What kind of ExecutionService to use
executor = "fork-join-executor"
# Configuration for the fork join pool
fork-join-executor {
# Min number of threads to cap factor-based parallelism number to
parallelism-min = 1
# Parallelism (threads) ... ceil(available processors * factor)
parallelism-factor = 1.0
# Max number of threads to cap factor-based parallelism number to
parallelism-max = 1
}
# Throughput defines the maximum number of messages to be
# processed per actor before the thread jumps to the next actor.
# Set to 1 for as fair as possible.
throughput = 1
}
2 changes: 1 addition & 1 deletion src/main/resources/mainnet.conf
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ scorex {
network {
magicBytes = [1, 0, 2, 4]
bindAddress = "0.0.0.0:9030"
nodeName = "ergo-mainnet-4.0.21.1"
nodeName = "ergo-mainnet-4.0.22"
nodeName = ${?NODENAME}
knownPeers = [
"213.239.193.208:9030",
Expand Down
8 changes: 4 additions & 4 deletions src/main/resources/panel/asset-manifest.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"files": {
"main.css": "/static/css/main.0e9161bb.chunk.css",
"main.js": "/static/js/main.2343b43e.chunk.js",
"main.js.map": "/static/js/main.2343b43e.chunk.js.map",
"main.js": "/static/js/main.2df85f5c.chunk.js",
"main.js.map": "/static/js/main.2df85f5c.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.219240e0.js",
"runtime-main.js.map": "/static/js/runtime-main.219240e0.js.map",
"static/css/2.9338f6a1.chunk.css": "/static/css/2.9338f6a1.chunk.css",
"static/js/2.6b84a7b0.chunk.js": "/static/js/2.6b84a7b0.chunk.js",
"static/js/2.6b84a7b0.chunk.js.map": "/static/js/2.6b84a7b0.chunk.js.map",
"index.html": "/index.html",
"precache-manifest.495a82b903bf93fbd7028c4017ca8dee.js": "/precache-manifest.495a82b903bf93fbd7028c4017ca8dee.js",
"precache-manifest.d5050dc805ea3d39fb8ff28d6cef00ed.js": "/precache-manifest.d5050dc805ea3d39fb8ff28d6cef00ed.js",
"service-worker.js": "/service-worker.js",
"static/css/2.9338f6a1.chunk.css.map": "/static/css/2.9338f6a1.chunk.css.map",
"static/css/main.0e9161bb.chunk.css.map": "/static/css/main.0e9161bb.chunk.css.map",
Expand All @@ -25,6 +25,6 @@
"static/css/2.9338f6a1.chunk.css",
"static/js/2.6b84a7b0.chunk.js",
"static/css/main.0e9161bb.chunk.css",
"static/js/main.2343b43e.chunk.js"
"static/js/main.2df85f5c.chunk.js"
]
}
2 changes: 1 addition & 1 deletion src/main/resources/panel/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="shortcut icon" href="/favicon.svg"/><meta name="viewport" content="minimum-scale=1,initial-scale=1,width=device-width,shrink-to-fit=no"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/manifest.json"/><title>Ergo node interface</title><link href="/static/css/2.9338f6a1.chunk.css" rel="stylesheet"><link href="/static/css/main.0e9161bb.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><div id="modal-root"></div><script>!function(l){function e(e){for(var r,t,n=e[0],o=e[1],u=e[2],f=0,i=[];f<n.length;f++)t=n[f],Object.prototype.hasOwnProperty.call(c,t)&&c[t]&&i.push(c[t][0]),c[t]=0;for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(l[r]=o[r]);for(s&&s(e);i.length;)i.shift()();return p.push.apply(p,u||[]),a()}function a(){for(var e,r=0;r<p.length;r++){for(var t=p[r],n=!0,o=1;o<t.length;o++){var u=t[o];0!==c[u]&&(n=!1)}n&&(p.splice(r--,1),e=f(f.s=t[0]))}return e}var t={},c={1:0},p=[];function f(e){if(t[e])return t[e].exports;var r=t[e]={i:e,l:!1,exports:{}};return l[e].call(r.exports,r,r.exports,f),r.l=!0,r.exports}f.m=l,f.c=t,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(r,e){if(1&e&&(r=f(r)),8&e)return r;if(4&e&&"object"==typeof r&&r&&r.__esModule)return r;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:r}),2&e&&"string"!=typeof r)for(var n in r)f.d(t,n,function(e){return r[e]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="/";var r=this["webpackJsonpergo-node-interface"]=this["webpackJsonpergo-node-interface"]||[],n=r.push.bind(r);r.push=e,r=r.slice();for(var o=0;o<r.length;o++)e(r[o]);var s=n;a()}([])</script><script src="/static/js/2.6b84a7b0.chunk.js"></script><script src="/static/js/main.2343b43e.chunk.js"></script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="shortcut icon" href="/favicon.svg"/><meta name="viewport" content="minimum-scale=1,initial-scale=1,width=device-width,shrink-to-fit=no"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/manifest.json"/><title>Ergo node interface</title><link href="/static/css/2.9338f6a1.chunk.css" rel="stylesheet"><link href="/static/css/main.0e9161bb.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><div id="modal-root"></div><script>!function(l){function e(e){for(var r,t,n=e[0],o=e[1],u=e[2],f=0,i=[];f<n.length;f++)t=n[f],Object.prototype.hasOwnProperty.call(c,t)&&c[t]&&i.push(c[t][0]),c[t]=0;for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(l[r]=o[r]);for(s&&s(e);i.length;)i.shift()();return p.push.apply(p,u||[]),a()}function a(){for(var e,r=0;r<p.length;r++){for(var t=p[r],n=!0,o=1;o<t.length;o++){var u=t[o];0!==c[u]&&(n=!1)}n&&(p.splice(r--,1),e=f(f.s=t[0]))}return e}var t={},c={1:0},p=[];function f(e){if(t[e])return t[e].exports;var r=t[e]={i:e,l:!1,exports:{}};return l[e].call(r.exports,r,r.exports,f),r.l=!0,r.exports}f.m=l,f.c=t,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(r,e){if(1&e&&(r=f(r)),8&e)return r;if(4&e&&"object"==typeof r&&r&&r.__esModule)return r;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:r}),2&e&&"string"!=typeof r)for(var n in r)f.d(t,n,function(e){return r[e]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="/";var r=this["webpackJsonpergo-node-interface"]=this["webpackJsonpergo-node-interface"]||[],n=r.push.bind(r);r.push=e,r=r.slice();for(var o=0;o<r.length;o++)e(r[o]);var s=n;a()}([])</script><script src="/static/js/2.6b84a7b0.chunk.js"></script><script src="/static/js/main.2df85f5c.chunk.js"></script></body></html>
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
self.__precacheManifest = (self.__precacheManifest || []).concat([
{
"revision": "7a445dd2913c13bc0923f8785f906190",
"revision": "07a803448c8cd5afd8c3d399f444b959",
"url": "/index.html"
},
{
"revision": "958afc9417af1de07489",
"url": "/static/css/2.9338f6a1.chunk.css"
},
{
"revision": "623717ef0d9ac2c40350",
"revision": "b6be50d400b93ddc0e13",
"url": "/static/css/main.0e9161bb.chunk.css"
},
{
"revision": "958afc9417af1de07489",
"url": "/static/js/2.6b84a7b0.chunk.js"
},
{
"revision": "623717ef0d9ac2c40350",
"url": "/static/js/main.2343b43e.chunk.js"
"revision": "b6be50d400b93ddc0e13",
"url": "/static/js/main.2df85f5c.chunk.js"
},
{
"revision": "ce813ebd69754efed759",
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/panel/service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");

importScripts(
"/precache-manifest.495a82b903bf93fbd7028c4017ca8dee.js"
"/precache-manifest.d5050dc805ea3d39fb8ff28d6cef00ed.js"
);

self.addEventListener('message', (event) => {
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/main/resources/testnet.conf
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ scorex {
network {
magicBytes = [2, 0, 0, 2]
bindAddress = "0.0.0.0:9020"
nodeName = "ergo-testnet-4.0.21.1"
nodeName = "ergo-testnet-4.0.22"
nodeName = ${?NODENAME}
knownPeers = [
"213.239.193.208:9020",
Expand Down
2 changes: 0 additions & 2 deletions src/main/scala/org/ergoplatform/GlobalConstants.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,4 @@ object GlobalConstants {
* (to avoid clashing between blockchain processing and API actors)
*/
val ApiDispatcher = "api-dispatcher"

val NetworkDispatcher = "network-dispatcher"
}
41 changes: 37 additions & 4 deletions src/main/scala/org/ergoplatform/http/api/ErgoBaseApiRoute.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
package org.ergoplatform.http.api

import akka.actor.ActorRef
import akka.http.scaladsl.server.{Directive1, ValidationRejection}
import org.ergoplatform.settings.Algos
import org.ergoplatform.modifiers.mempool.ErgoTransaction
import org.ergoplatform.nodeView.ErgoReadersHolder.{GetReaders, Readers}
import org.ergoplatform.nodeView.mempool.ErgoMemPoolReader
import org.ergoplatform.nodeView.state.{ErgoStateReader, UtxoStateReader}
import org.ergoplatform.settings.{Algos, ErgoSettings}
import scorex.core.api.http.ApiRoute
import scorex.util.{ModifierId, bytesToId}
import akka.pattern.ask

import scala.concurrent.ExecutionContextExecutor
import scala.util.Success
import scala.concurrent.{ExecutionContextExecutor, Future}
import scala.util.{Success, Try}

trait ErgoBaseApiRoute extends ApiRoute {

Expand All @@ -17,10 +23,37 @@ trait ErgoBaseApiRoute extends ApiRoute {
val modifierIdGet: Directive1[ModifierId] = parameters("id".as[String])
.flatMap(handleModifierId)

private def handleModifierId(value: String): Directive1[ModifierId] =
private def handleModifierId(value: String): Directive1[ModifierId] = {
Algos.decode(value) match {
case Success(bytes) => provide(bytesToId(bytes))
case _ => reject(ValidationRejection("Wrong modifierId format"))
}
}

private def getStateAndPool(readersHolder: ActorRef): Future[(ErgoStateReader, ErgoMemPoolReader)] = {
(readersHolder ? GetReaders).mapTo[Readers].map { rs =>
(rs.s, rs.m)
}
}

/**
* Helper method to verify transaction against UTXO set (and unconfirmed outputs in the mempool), or check
* transaction syntax only if UTXO set is not available (the node is running in "digest" mode)
*
* Used in /transactions (POST /transactions and /transactions/check methods) and /wallet (/wallet/payment/send
* and /wallet/transaction/send) API methods to check submitted or generated transaction
*/
protected def verifyTransaction(tx: ErgoTransaction,
readersHolder: ActorRef,
ergoSettings: ErgoSettings): Future[Try[ErgoTransaction]] = {
getStateAndPool(readersHolder)
.map {
case (utxo: UtxoStateReader, mp: ErgoMemPoolReader) =>
val maxTxCost = ergoSettings.nodeSettings.maxTransactionCost
utxo.withMempool(mp).validateWithCost(tx, maxTxCost).map(_ => tx)
case _ =>
tx.statelessValidity().map(_ => tx)
}
}

}
4 changes: 2 additions & 2 deletions src/main/scala/org/ergoplatform/http/api/ScriptApiRoute.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import sigmastate._
import sigmastate.basics.DLogProtocol.ProveDlog
import sigmastate.eval.{CompiletimeIRContext, IRContext, RuntimeIRContext}
import sigmastate.lang.{CompilerSettings, SigmaCompiler, TransformingSigmaBuilder}
import sigmastate.interpreter.Interpreter
import sigmastate.serialization.ValueSerializer

import scala.concurrent.Future
Expand Down Expand Up @@ -102,8 +103,7 @@ case class ScriptApiRoute(readersHolder: ActorRef, ergoSettings: ErgoSettings)
tree => {
implicit val irc: IRContext = new RuntimeIRContext()
val interpreter: ErgoLikeInterpreter = new ErgoLikeInterpreter()
val prop = interpreter.propositionFromErgoTree(tree, req.ctx.asInstanceOf[interpreter.CTX])
val res = interpreter.reduceToCrypto(req.ctx.asInstanceOf[interpreter.CTX], prop)
val res = Try(interpreter.fullReduction(tree, req.ctx.asInstanceOf[interpreter.CTX], Interpreter.emptyEnv))
res.fold(
e => BadRequest(e.getMessage),
s => ApiResponse(CryptoResult(s.value, s.cost).asJson)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import org.ergoplatform.modifiers.mempool.ErgoTransaction
import org.ergoplatform.nodeView.ErgoReadersHolder.{GetReaders, Readers}
import org.ergoplatform.nodeView.mempool.ErgoMemPoolReader
import org.ergoplatform.nodeView.mempool.HistogramStats.getFeeHistogram
import org.ergoplatform.nodeView.state.{ErgoStateReader, UtxoStateReader}
import org.ergoplatform.nodeView.ErgoNodeViewHolder.ReceivableMessages.LocallyGeneratedTransaction
import org.ergoplatform.settings.ErgoSettings
import scorex.core.api.http.ApiError.BadRequest
Expand Down Expand Up @@ -38,25 +37,13 @@ case class TransactionsApiRoute(readersHolder: ActorRef,

private def getMemPool: Future[ErgoMemPoolReader] = (readersHolder ? GetReaders).mapTo[Readers].map(_.m)

private def getStateAndPool: Future[(ErgoStateReader, ErgoMemPoolReader)] =
(readersHolder ? GetReaders).mapTo[Readers].map { rs =>
(rs.s, rs.m)
}

private def getUnconfirmedTransactions(offset: Int, limit: Int): Future[Json] = getMemPool.map { p =>
p.getAll.slice(offset, offset + limit).map(_.asJson).asJson
}

private def validateTransactionAndProcess(tx: ErgoTransaction)(processFn: ErgoTransaction => Any): Route = {
onSuccess {
getStateAndPool
.map {
case (utxo: UtxoStateReader, mp: ErgoMemPoolReader) =>
val maxTxCost = ergoSettings.nodeSettings.maxTransactionCost
utxo.withMempool(mp).validateWithCost(tx, maxTxCost)
case _ =>
tx.statelessValidity()
}
verifyTransaction(tx, readersHolder, ergoSettings)
} {
_.fold(
e => BadRequest(s"Malformed transaction: ${e.getMessage}"),
Expand Down
Loading

0 comments on commit f38f3a6

Please sign in to comment.