diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6a2c542..c8c56bb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,13 +1,18 @@
# Changelog
+
+## 1.3.0
+* SDK dependency updated to version 0.11.0 (see [SDK changelog](https://github.com/HorizenOfficial/Sidechains-SDK/blob/0.11.0/CHANGELOG.md))
+* Fork configuration to enable: EVM Update, Forger stake native smart contract new methods, Pause Forging feature
+
## 1.2.1
-* SDK dependency updated to version 0.10.1 (see [SDK changelog](https://github.com/HorizenOfficial/Sidechains-SDK/blob/master/CHANGELOG.md))
+* SDK dependency updated to version 0.10.1 (see [SDK changelog](https://github.com/HorizenOfficial/Sidechains-SDK/blob/0.10.1/CHANGELOG.md))
## 1.2.0
-* SDK dependency updated to version 0.10.0 (see [SDK changelog](https://github.com/HorizenOfficial/Sidechains-SDK/blob/master/CHANGELOG.md))
+* SDK dependency updated to version 0.10.0 (see [SDK changelog](https://github.com/HorizenOfficial/Sidechains-SDK/blob/0.10.0/CHANGELOG.md))
* Fork configuration to enable new functionalities (ZenIP 42203/42206 support, ZenDao Multisig support)
## 1.1.0
-* SDK dependency updated to version 0.9.0 (see [SDK changelog](https://github.com/HorizenOfficial/Sidechains-SDK/blob/master/CHANGELOG.md))
+* SDK dependency updated to version 0.9.0 (see [SDK changelog](https://github.com/HorizenOfficial/Sidechains-SDK/blob/0.9.0/CHANGELOG.md))
* Fork configuration to enable Native<>Real smart contract interoperability
* Added endpoints documentation
@@ -19,7 +24,7 @@
## 1.0.0
* SDK dependency updated to version 0.8.0
-* Fork configuration to enable decentralized governance (ZenDao) and change consensus parameters (consensus epoch slot time and lenght, acrive slot coefficient)
+* Fork configuration to enable decentralized governance (ZenDao) and change consensus parameters (consensus epoch slot time and length, active slot coefficient)
* Introduced a delay of 6 blocks in the inclusion of the mainchain blocks
## 0.2.1
diff --git a/README.md b/README.md
index 5868986..11eac85 100644
--- a/README.md
+++ b/README.md
@@ -7,8 +7,8 @@ Horizen EON is a public proof-of-stake sidechain and a fully EVM-compatible smar
[Changelog](/CHANGELOG.md)
### EVM compatibility
-Current EVM implementation is based on go-ethereum [Paravin](https://github.com/ethereum/go-ethereum/releases/tag/v1.10.26) (`v1.10.26`).
-Solidity compiler is supported up to version `0.8.19`.
+Current EVM implementation is based on go-ethereum [Archanes](https://github.com/ethereum/go-ethereum/releases/tag/v1.13.4) (`v1.13.4`).
+Solidity compiler is supported up to version `0.8.23`.
### Supported platforms
diff --git a/api/version.json b/api/version.json
index 275bb95..08e8cc1 100644
--- a/api/version.json
+++ b/api/version.json
@@ -2,15 +2,15 @@
{
"network":"mainnet",
"networkName": "eon",
- "version":"1.2.1",
- "dockerImages":["zencash/evmapp:1.2.1","zencash/evmapp:latest"],
- "ghReleaseLink":"github.com/HorizenOfficial/eon/releases/tag/1.2.1"
+ "version":"1.3.0",
+ "dockerImages":["zencash/evmapp:1.3.0","zencash/evmapp:latest"],
+ "ghReleaseLink":"github.com/HorizenOfficial/eon/releases/tag/1.3.0"
},
{
"network":"testnet",
"networkName": "gobi",
- "version":"1.2.1",
- "dockerImages":["zencash/evmapp:1.2.1","zencash/evmapp:latest"],
- "ghReleaseLink":"github.com/HorizenOfficial/eon/releases/tag/1.2.1"
+ "version":"1.3.0",
+ "dockerImages":["zencash/evmapp:1.3.0","zencash/evmapp:latest"],
+ "ghReleaseLink":"github.com/HorizenOfficial/eon/releases/tag/1.3.0"
}
]
\ No newline at end of file
diff --git a/bootstraptool/pom.xml b/bootstraptool/pom.xml
index 658ed9a..abef513 100644
--- a/bootstraptool/pom.xml
+++ b/bootstraptool/pom.xml
@@ -3,7 +3,7 @@
4.0.0
io.horizen
bootstraptool
- 1.2.1
+ 1.3.0
2023
UTF-8
@@ -16,12 +16,12 @@
io.horizen
sidechains-sdk-account_sctools
- 0.10.1
+ 0.11.0
io.horizen
eon
- 1.2.1
+ 1.3.0
compile
diff --git a/doc/api/wallet/createPrivateKey25519.md b/doc/api/wallet/createPrivateKey25519.md
index ab7638d..15f89d4 100644
--- a/doc/api/wallet/createPrivateKey25519.md
+++ b/doc/api/wallet/createPrivateKey25519.md
@@ -1,9 +1,9 @@
[< EON API Documentation](/doc/api/index.md)
-### wallet/createPrivateKeySecp256k1
+### wallet/createPrivateKey25519
-Create a private key in the Secp256k1 format.\
-Secp256k1 keys are the standard used in Ethereum EVMs and also by EON.\
-Returns the correspondent public address.
+Create a private key in the 25519 format.
+25519 keys are used in EON for designating forgers.
+Returns the correspondent public key.
**Parameters**
@@ -11,12 +11,15 @@ No parameters
**Example request**
- curl -sX POST 'http://127.0.0.1:9085/wallet/createPrivateKeySecp256k1' -H 'Content-Type: application/json' -H 'accept: application/json'
+ curl -sX POST 'http://127.0.0.1:9085/wallet/createPrivateKey25519' -H 'Content-Type: application/json' -H 'accept: application/json'
**Example response**
{
"result" : {
- "address" : "00c8f107a09cd4f463afc2f1e6e5bf6022ad4600"
+ "proposition" : {
+ "publicKey" : "4b50edf43fddcf29afceacfcc9c5c16edb16de6550b9172c7190bfe9fdad0f45"
+ }
}
- }
\ No newline at end of file
+ }
+
diff --git a/doc/api/wallet/createPrivateKeySecp256k1.md b/doc/api/wallet/createPrivateKeySecp256k1.md
index 0e6904e..ab7638d 100644
--- a/doc/api/wallet/createPrivateKeySecp256k1.md
+++ b/doc/api/wallet/createPrivateKeySecp256k1.md
@@ -1,9 +1,9 @@
[< EON API Documentation](/doc/api/index.md)
-### wallet/createPrivateKey25519
+### wallet/createPrivateKeySecp256k1
-Create a private key in the 25519 format.
-25519 keys are used in EON for designating forgers.
-Returns the correspondent public key.
+Create a private key in the Secp256k1 format.\
+Secp256k1 keys are the standard used in Ethereum EVMs and also by EON.\
+Returns the correspondent public address.
**Parameters**
@@ -11,14 +11,12 @@ No parameters
**Example request**
- curl -sX POST 'http://127.0.0.1:9085/wallet/createPrivateKey25519' -H 'Content-Type: application/json' -H 'accept: application/json'
+ curl -sX POST 'http://127.0.0.1:9085/wallet/createPrivateKeySecp256k1' -H 'Content-Type: application/json' -H 'accept: application/json'
**Example response**
{
"result" : {
- "proposition" : {
- "publicKey" : "4b50edf43fddcf29afceacfcc9c5c16edb16de6550b9172c7190bfe9fdad0f45"
- }
+ "address" : "00c8f107a09cd4f463afc2f1e6e5bf6022ad4600"
}
}
\ No newline at end of file
diff --git a/doc/howto/customlog.md b/doc/howto/customlog.md
new file mode 100644
index 0000000..f812961
--- /dev/null
+++ b/doc/howto/customlog.md
@@ -0,0 +1,34 @@
+[< EON Documentation index](/doc/index.md)
+# EON logging configuration
+
+## Simple logging customization
+
+Edit the following variables in the node configuration file to customize path and level of logging:
+
+- **sparkz.logDir**
+
+ Path of the logging directory
+
+- **sparkz.logInfo.logFileName**
+
+ Name of the log file.
+ If you are running via Docker, you can also change it by setting the environment variable: **SCNODE_LOG_FILE_NAME**
+
+- **sparkz.logInfo.logFileLevel** and **sparkz.logInfo.logConsoleLevel**
+
+ Level of logging used for file and console appenders.
+ Can be one of the following: off, fatal, error, warn, info, debug, trace, all
+ If you are running via Docker, you can also change them by setting the environment variables: **SCNODE_LOG_FILE_LEVEL** and **SCNODE_LOG_CONSOLE_LEVEL**
+
+
+## Advanced logging customization
+
+For advanced customization you can setup EON to use a totally custom log4j file instead of the default one:
+
+- if you are running the java process directly, add the following property to the startup command:
+
+ -Dlog4j.configurationFile=filePath
+
+- if you are running via Docker, configure an environment variable **SCNODE_LOG4J_CUSTOM_CONFIG** with the path to the log4j file, and be sure to have the file present inside the container.
+
+Start from [this base template](https://github.com/HorizenOfficial/Sidechains-SDK/blob/master/sdk/src/main/resources/log4j2.xml) to create your cunfiguration file.
\ No newline at end of file
diff --git a/doc/index.md b/doc/index.md
index 0d59575..7c26c32 100644
--- a/doc/index.md
+++ b/doc/index.md
@@ -2,8 +2,17 @@
Find [here documentation](/doc/api/index.md) about how to interact with a running EON node.
+# EON Native smart contracts documentation
+
+Find [here documentation](/doc/nativesc/index.md) about EON native smart contracts
+
+# HowTOs and tutorials
+
+- [EON logging configuration](/doc/howto/customlog.md)
+
# EON Release Notes
+## Version [1.3.0](/doc/release/1.3.0.md)
## Version [1.2.1](/doc/release/1.2.1.md)
## Version [1.2.0](/doc/release/1.2.0.md)
## Version [1.1.0](/doc/release/1.1.0.md)
diff --git a/doc/nativesc/contracts/CertKeyRotation.json b/doc/nativesc/contracts/CertKeyRotation.json
new file mode 100644
index 0000000..da64236
--- /dev/null
+++ b/doc/nativesc/contracts/CertKeyRotation.json
@@ -0,0 +1,140 @@
+{
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint32",
+ "name": "keyType",
+ "type": "uint32"
+ },
+ {
+ "indexed": true,
+ "internalType": "uint32",
+ "name": "keyIndex",
+ "type": "uint32"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "newKeyValue_32",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes1",
+ "name": "newKeyValue_1",
+ "type": "bytes1"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "epochNumber",
+ "type": "uint32"
+ }
+ ],
+ "name": "SubmitKeyRotation",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint32",
+ "name": "key_type",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "index",
+ "type": "uint32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "newKey_1",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes1",
+ "name": "newKey_2",
+ "type": "bytes1"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "signKeySig_1",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "signKeySig_2",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "masterKeySig_1",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "masterKeySig_2",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "newKeySig_1",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "newKeySig_2",
+ "type": "bytes32"
+ }
+ ],
+ "name": "submitKeyRotation",
+ "outputs": [
+ {
+ "internalType": "uint32",
+ "name": "",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint32",
+ "name": "",
+ "type": "uint32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes1",
+ "name": "",
+ "type": "bytes1"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ]
+}
diff --git a/doc/nativesc/contracts/CertKeyRotation.md b/doc/nativesc/contracts/CertKeyRotation.md
new file mode 100644
index 0000000..bbf752e
--- /dev/null
+++ b/doc/nativesc/contracts/CertKeyRotation.md
@@ -0,0 +1,25 @@
+[< EON Native Smart Contracts Documentation](/doc/nativesc/index.md)
+### CertKeyRotation
+
+This native smart contract is used to rotate the master and signers keys of the EON certifiers.
+
+| | |
+| -------- | ------- |
+| Contract address: | 0x0000000000000000000044444444444444444444 |
+| ABI descriptor: | [Click here](/doc/nativesc/contracts/CertKeyRotation.json) |
+| Solidity interface: | [Click here](/doc/nativesc/contracts/CertKeyRotation.sol) |
+
+
+
+**Methods available**
+
+- submitKeyRotation
+
+ function submitKeyRotation(uint32 key_type, uint32 index, bytes32 newKey_1, bytes1 newKey_2, bytes32 signKeySig_1, bytes32 signKeySig_2, bytes32 masterKeySig_1, bytes32 masterKeySig_2, bytes32 newKeySig_1, bytes32 newKeySig_2) external returns (uint32, uint32, bytes32, bytes1, bytes32, bytes32, bytes32, bytes32);
+
+ Executes a signers or masters certificate submitter key rotation.
+
+
+
+
+
diff --git a/doc/nativesc/contracts/CertKeyRotation.sol b/doc/nativesc/contracts/CertKeyRotation.sol
new file mode 100644
index 0000000..07db251
--- /dev/null
+++ b/doc/nativesc/contracts/CertKeyRotation.sol
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.0;
+
+
+// contract address: 0x0000000000000000000044444444444444444444
+interface CertKeyRotation {
+
+ // Event declaration
+ // Up to 3 parameters can be indexed.
+ // Indexed parameters helps you filter the logs by the indexed parameter
+ event SubmitKeyRotation(uint32 indexed keyType, uint32 indexed keyIndex, bytes32 newKeyValue_32, bytes1 newKeyValue_1, uint32 epochNumber);
+
+ function submitKeyRotation(uint32 key_type, uint32 index, bytes32 newKey_1, bytes1 newKey_2, bytes32 signKeySig_1, bytes32 signKeySig_2, bytes32 masterKeySig_1, bytes32 masterKeySig_2, bytes32 newKeySig_1, bytes32 newKeySig_2) external returns (uint32, uint32, bytes32, bytes1, bytes32, bytes32, bytes32, bytes32);
+}
diff --git a/doc/nativesc/contracts/ForgerStakes.json b/doc/nativesc/contracts/ForgerStakes.json
new file mode 100644
index 0000000..d297f32
--- /dev/null
+++ b/doc/nativesc/contracts/ForgerStakes.json
@@ -0,0 +1,399 @@
+{
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "stakeId",
+ "type": "bytes32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "DelegateForgerStake",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "uint32",
+ "name": "forgerIndex",
+ "type": "uint32"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "blockSignProposition",
+ "type": "bytes32"
+ }
+ ],
+ "name": "OpenForgerList",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "oldVersion",
+ "type": "uint32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "newVersion",
+ "type": "uint32"
+ }
+ ],
+ "name": "StakeUpgrade",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "stakeId",
+ "type": "bytes32"
+ }
+ ],
+ "name": "WithdrawForgerStake",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "publicKey",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "vrf1",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes1",
+ "name": "vrf2",
+ "type": "bytes1"
+ },
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "delegate",
+ "outputs": [
+ {
+ "internalType": "StakeID",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getAllForgersStakes",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "StakeID",
+ "name": "stakeId",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "stakedAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "publicKey",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "vrf1",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes1",
+ "name": "vrf2",
+ "type": "bytes1"
+ }
+ ],
+ "internalType": "struct ForgerStakes.StakeInfo[]",
+ "name": "",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "int32",
+ "name": "startIndex",
+ "type": "int32"
+ },
+ {
+ "internalType": "int32",
+ "name": "pageSize",
+ "type": "int32"
+ }
+ ],
+ "name": "getPagedForgersStakes",
+ "outputs": [
+ {
+ "internalType": "int32",
+ "name": "",
+ "type": "int32"
+ },
+ {
+ "components": [
+ {
+ "internalType": "StakeID",
+ "name": "stakeId",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "stakedAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "publicKey",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "vrf1",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes1",
+ "name": "vrf2",
+ "type": "bytes1"
+ }
+ ],
+ "internalType": "struct ForgerStakes.StakeInfo[]",
+ "name": "",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "int32",
+ "name": "startIndex",
+ "type": "int32"
+ },
+ {
+ "internalType": "int32",
+ "name": "pageSize",
+ "type": "int32"
+ }
+ ],
+ "name": "getPagedForgersStakesByUser",
+ "outputs": [
+ {
+ "internalType": "int32",
+ "name": "",
+ "type": "int32"
+ },
+ {
+ "components": [
+ {
+ "internalType": "StakeID",
+ "name": "stakeId",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "stakedAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "publicKey",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "vrf1",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes1",
+ "name": "vrf2",
+ "type": "bytes1"
+ }
+ ],
+ "internalType": "struct ForgerStakes.StakeInfo[]",
+ "name": "",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint32",
+ "name": "forgerIndex",
+ "type": "uint32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "signature1",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "signature2",
+ "type": "bytes32"
+ }
+ ],
+ "name": "openStakeForgerList",
+ "outputs": [
+ {
+ "internalType": "bytes",
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "stakeOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "upgrade",
+ "outputs": [
+ {
+ "internalType": "uint32",
+ "name": "",
+ "type": "uint32"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "StakeID",
+ "name": "stakeId",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes1",
+ "name": "signatureV",
+ "type": "bytes1"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "signatureR",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "signatureS",
+ "type": "bytes32"
+ }
+ ],
+ "name": "withdraw",
+ "outputs": [
+ {
+ "internalType": "StakeID",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ]
+}
diff --git a/doc/nativesc/contracts/ForgerStakes.md b/doc/nativesc/contracts/ForgerStakes.md
new file mode 100644
index 0000000..f85d9bc
--- /dev/null
+++ b/doc/nativesc/contracts/ForgerStakes.md
@@ -0,0 +1,91 @@
+[< EON Native Smart Contracts Documentation](/doc/nativesc/index.md)
+### ForgerStakes
+
+This native smart contract manages the forger stakes.
+
+| | |
+| -------- | ------- |
+| Contract address: | 0x0000000000000000000022222222222222222222 |
+| ABI descriptor: | [Click here](/doc/nativesc/contracts/ForgerStakes.json) |
+| Solidity interface: | [Click here](/doc/nativesc/contracts/ForgerStakes.sol) |
+
+
+
+**Methods available**
+
+- getAllForgersStakes
+
+ function getAllForgersStakes() external view returns (StakeInfo[] memory);
+
+ Return a list of all forgers stakes present.
+
+- delegate
+
+ function delegate(bytes32 publicKey, bytes32 vrf1, bytes1 vrf2, address owner) external payable returns (StakeID);
+
+ Create a new stake and assign it to the forger identified by the specified public key + vrf key.
+ Vrf key is split in two separate parameters, being longer than 32 bytes.
+ The owner parameter is the address authorized to remove the stake by calling the withdraw function.
+ The amount of the stake is specified in the "value" field of the transaction.
+
+- withdraw
+
+ function withdraw(StakeID stakeId, bytes1 signatureV, bytes32 signatureR, bytes32 signatureS) external returns (StakeID);
+
+ Remove the stake identified by stakeId and withdraw the funds, by providing the correct signature.
+ The message to sign is composed by the concatenation of stakeId + sender address + invocation nonce, and is verified against the owner of the stake.
+ Note: the whole amount staked will be removed, it is not allowed to remove only partially a stake. The amount of the stake spent is sent to the balance of the owner.
+
+- openStakeForgerList
+
+ function openStakeForgerList(uint32 forgerIndex, bytes32 signature1, bytes32 signature2) external returns (bytes memory);
+
+ Execute a transaction expressing the vote for opening the restricted forgers list.
+ This transaction is allowed only when the forgers are initially restricted, and can be executed only by one of the allowed forgers.
+ The forger index is determined by the position of the forger in the allowed forger list.
+ The message to sign is composed by the concatenation of forger index + sender address + invocation nonce, and is verified against the blockSignerProposition.
+
+- upgrade
+
+ function upgrade() external returns (uint32);
+
+ This method upgrades the model of the forger stakes storage. It can be called just once. If successful, it returns
+ the number identifying the new storage version (1 => Version 2). It emits a StakeUpgrade event, with the storage
+ versions before and after the upgrade.
+
+- getPagedForgersStakes
+
+ function function getPagedForgersStakes(int32 startIndex, int32 pageSize) external view returns (int32, StakeInfo[] memory);
+
+ Returns the first "pageSize" forger stakes, starting from "startIndex". In case there
+ are additional stakes left, it returns the index of the first of the remaining stakes, otherwise it returns -1.
+ This method requires the Forger Stake storage model version 2, so it will fail if invoked before the “upgrade()” method.
+
+- getPagedForgersStakesByUser
+
+ function function getPagedForgersStakesByUser(address owner, int32 startIndex, int32 pageSize) external view returns (int32, StakeInfo[] memory);
+
+ Returns the first "pageSize" forger stakes, owned by the specified address, starting from "startIndex". In case there
+ are additional stakes left, it returns the index of the first of the remaining stakes, otherwise it returns -1.
+ This method requires the Forger Stake storage model version 2, so it will fail if invoked before the “upgrade()” method.
+
+- stakeOf
+
+ function stakeOf(address owner) external view returns (uint256);
+
+ Returns the total amount of forger stakes owned by the specified address. This method requires the Forger Stake
+ storage model version 2, so it fails when invoked before the “upgrade()” method.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/nativesc/contracts/ForgerStakes.sol b/doc/nativesc/contracts/ForgerStakes.sol
new file mode 100644
index 0000000..b035515
--- /dev/null
+++ b/doc/nativesc/contracts/ForgerStakes.sol
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.0;
+
+type StakeID is bytes32;
+
+// contract address: 0x0000000000000000000022222222222222222222
+interface ForgerStakes {
+
+ struct StakeInfo {
+ StakeID stakeId;
+ uint256 stakedAmount;
+ address owner;
+ bytes32 publicKey;
+ bytes32 vrf1;
+ bytes1 vrf2;
+ }
+
+ // Event declaration
+ // Up to 3 parameters can be indexed.
+ // Indexed parameters helps you filter the logs by the indexed parameter
+ event DelegateForgerStake(address indexed sender, address indexed owner, bytes32 stakeId, uint256 value);
+ event WithdrawForgerStake(address indexed owner, bytes32 stakeId);
+ event StakeUpgrade(uint32 oldVersion, uint32 newVersion);
+ event OpenForgerList(uint32 indexed forgerIndex, address sender, bytes32 blockSignProposition);
+
+ function getAllForgersStakes() external view returns (StakeInfo[] memory);
+
+ function delegate(bytes32 publicKey, bytes32 vrf1, bytes1 vrf2, address owner) external payable returns (StakeID);
+
+ function withdraw(StakeID stakeId, bytes1 signatureV, bytes32 signatureR, bytes32 signatureS) external returns (StakeID);
+
+ function openStakeForgerList(uint32 forgerIndex, bytes32 signature1, bytes32 signature2) external returns (bytes memory);
+
+ function stakeOf(address owner) external view returns (uint256);
+
+ function getPagedForgersStakesByUser(address owner, int32 startIndex, int32 pageSize) external view returns (int32, StakeInfo[] memory);
+
+ function upgrade() external returns (uint32);
+
+ function getPagedForgersStakes(int32 startIndex, int32 pageSize) external view returns (int32, StakeInfo[] memory);
+}
diff --git a/doc/nativesc/contracts/McAddrOwnership.json b/doc/nativesc/contracts/McAddrOwnership.json
new file mode 100644
index 0000000..9ec795c
--- /dev/null
+++ b/doc/nativesc/contracts/McAddrOwnership.json
@@ -0,0 +1,225 @@
+{
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "scAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes3",
+ "name": "mcAddress_3",
+ "type": "bytes3"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "mcAddress_32",
+ "type": "bytes32"
+ }
+ ],
+ "name": "AddMcAddrOwnership",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "scAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes3",
+ "name": "mcAddress_3",
+ "type": "bytes3"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes32",
+ "name": "mcAddress_32",
+ "type": "bytes32"
+ }
+ ],
+ "name": "RemoveMcAddrOwnership",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "getAllKeyOwnerships",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "scAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes3",
+ "name": "mcAddrBytes1",
+ "type": "bytes3"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "mcAddrBytes2",
+ "type": "bytes32"
+ }
+ ],
+ "internalType": "struct McAddrOwnership.McAddrOwnershipData[]",
+ "name": "",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getKeyOwnerScAddresses",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "scAddress",
+ "type": "address"
+ }
+ ],
+ "name": "getKeyOwnerships",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "scAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes3",
+ "name": "mcAddrBytes1",
+ "type": "bytes3"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "mcAddrBytes2",
+ "type": "bytes32"
+ }
+ ],
+ "internalType": "struct McAddrOwnership.McAddrOwnershipData[]",
+ "name": "",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes3",
+ "name": "mcAddrBytes1",
+ "type": "bytes3"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "mcAddrBytes2",
+ "type": "bytes32"
+ }
+ ],
+ "name": "removeKeysOwnership",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes3",
+ "name": "mcAddrBytes1",
+ "type": "bytes3"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "mcAddrBytes2",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes24",
+ "name": "signature1",
+ "type": "bytes24"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "signature2",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "signature3",
+ "type": "bytes32"
+ }
+ ],
+ "name": "sendKeysOwnership",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "mcMultisigAddress",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "redeemScript",
+ "type": "string"
+ },
+ {
+ "internalType": "string[]",
+ "name": "mcSignatures",
+ "type": "string[]"
+ }
+ ],
+ "name": "sendMultisigKeysOwnership",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ]
+}
diff --git a/doc/nativesc/contracts/McAddrOwnership.md b/doc/nativesc/contracts/McAddrOwnership.md
new file mode 100644
index 0000000..2f3ecb2
--- /dev/null
+++ b/doc/nativesc/contracts/McAddrOwnership.md
@@ -0,0 +1,69 @@
+[< EON Native Smart Contracts Documentation](/doc/nativesc/index.md)
+### McAddrOwnership
+
+This native smart contract is used as a support to the ZenDao voting system.
+It allows to track associations between mainchain addresses and EON addresses, in order to sum the ZEN balances in both the chains for calculating voting powers.
+
+| | |
+| -------- | ------- |
+| Contract address: | 0x0000000000000000000088888888888888888888 |
+| ABI descriptor: | [Click here](/doc/nativesc/contracts/McAddrOwnership.json) |
+| Solidity interface: | [Click here](/doc/nativesc/contracts/McAddrOwnership.sol) |
+
+
+
+**Methods available**
+
+- getAllKeyOwnerships
+
+ function getAllKeyOwnerships() external view returns (McAddrOwnershipData[] memory);
+
+ Return a list of all the mainchain keys associated with the EON address that invoked the method.
+
+- getKeyOwnerships
+
+ function getKeyOwnerships(address scAddress) external view returns (McAddrOwnershipData[] memory);
+
+ Return a list of the mainchain keys associated with the EON address specified in the input parameter scAddress
+
+- getKeyOwnerScAddresses
+
+ function getKeyOwnerScAddresses() external view returns (address[] memory);
+
+ Return the list of all the EON addresses with recorded associations to mainchain keys.
+
+- sendKeysOwnership
+
+ function sendKeysOwnership(bytes3 mcAddrBytes1, bytes32 mcAddrBytes2, bytes24 signature1, bytes32 signature2, bytes32 signature3) external returns (bytes32);
+
+ Associate a mainchain address to the EON address that invoked the method.
+ Mainchain address is split in 2 parameters, being longer than 32 bytes.
+ Signature is split in 3 parameters for the same reason. The message to sign is the string representation of the EON address (format EIP-55: Mixed-case checksum address encoding).
+ In case of success, the returned value is the id of the new ownership record created.
+
+- sendMultisigKeysOwnership
+
+ function sendMultisigKeysOwnership(string memory mcMultisigAddress, string memory redeemScript, string[] memory mcSignatures) external returns (bytes32);
+
+ Associate the specified mainchain multisig address to the EON address that invoked the method.
+ Redeem script and signatures must be provided as well.
+ In case of success, the returned value is the id of the new ownership record created.
+
+- removeKeysOwnership
+
+ function removeKeysOwnership(bytes3 mcAddrBytes1, bytes32 mcAddrBytes2) external returns (bytes32);
+
+ Remove an association between the EON address that invoked the method and the specified mainchain address.
+ Mainchain address is split in 2 parameters, being longer more than 32 bytes.
+ In case of success, the returned value is the id of the ownership record removed.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/nativesc/contracts/McAddrOwnership.sol b/doc/nativesc/contracts/McAddrOwnership.sol
new file mode 100644
index 0000000..0da1b79
--- /dev/null
+++ b/doc/nativesc/contracts/McAddrOwnership.sol
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.0;
+
+
+// contract address: 0x0000000000000000000088888888888888888888
+interface McAddrOwnership {
+
+ struct McAddrOwnershipData {
+ address scAddress;
+ bytes3 mcAddrBytes1;
+ bytes32 mcAddrBytes2;
+ }
+
+
+ // Event declaration
+ // Up to 3 parameters can be indexed.
+ // Indexed parameters helps you filter the logs by the indexed parameter
+
+ event AddMcAddrOwnership(address indexed scAddress, bytes3 mcAddress_3, bytes32 mcAddress_32);
+ event RemoveMcAddrOwnership(address indexed scAddress, bytes3 mcAddress_3, bytes32 mcAddress_32);
+
+ function getAllKeyOwnerships() external view returns (McAddrOwnershipData[] memory);
+
+ function getKeyOwnerships(address scAddress) external view returns (McAddrOwnershipData[] memory);
+
+ function getKeyOwnerScAddresses() external view returns (address[] memory);
+
+ function sendKeysOwnership(bytes3 mcAddrBytes1, bytes32 mcAddrBytes2, bytes24 signature1, bytes32 signature2, bytes32 signature3) external returns (bytes32);
+
+ function sendMultisigKeysOwnership(string memory mcMultisigAddress, string memory redeemScript, string[] memory mcSignatures) external returns (bytes32);
+
+ function removeKeysOwnership(bytes3 mcAddrBytes1, bytes32 mcAddrBytes2) external returns (bytes32);
+}
diff --git a/doc/nativesc/contracts/WithdrawalRequests.json b/doc/nativesc/contracts/WithdrawalRequests.json
new file mode 100644
index 0000000..8159530
--- /dev/null
+++ b/doc/nativesc/contracts/WithdrawalRequests.json
@@ -0,0 +1,97 @@
+{
+ "abi": [
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes20",
+ "name": "mcDest",
+ "type": "bytes20"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "epochNumber",
+ "type": "uint32"
+ }
+ ],
+ "name": "AddWithdrawalRequest",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "MCAddress",
+ "name": "mcAddress",
+ "type": "bytes20"
+ }
+ ],
+ "name": "backwardTransfer",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "MCAddress",
+ "name": "mcAddress",
+ "type": "bytes20"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct WithdrawalRequests.WithdrawalRequest",
+ "name": "",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint32",
+ "name": "withdrawalEpoch",
+ "type": "uint32"
+ }
+ ],
+ "name": "getBackwardTransfers",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "MCAddress",
+ "name": "mcAddress",
+ "type": "bytes20"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct WithdrawalRequests.WithdrawalRequest[]",
+ "name": "",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ]
+}
diff --git a/doc/nativesc/contracts/WithdrawalRequests.md b/doc/nativesc/contracts/WithdrawalRequests.md
new file mode 100644
index 0000000..07bf351
--- /dev/null
+++ b/doc/nativesc/contracts/WithdrawalRequests.md
@@ -0,0 +1,36 @@
+[< EON Native Smart Contracts Documentation](/doc/nativesc/index.md)
+### WithdrawalRequests
+
+Allows to request a new withdrawal of funds to the mainchain (also called backward transfer), and see the list of the previous executed ones.
+
+| | |
+| -------- | ------- |
+| Contract address: | 0x0000000000000000000011111111111111111111 |
+| ABI descriptor: | [Click here](/doc/nativesc/contracts/WithdrawalRequests.json) |
+| Solidity interface: | [Click here](/doc/nativesc/contracts/WithdrawalRequests.sol) |
+
+
+
+**Methods available**
+
+- getBackwardTransfers
+
+ function getBackwardTransfers(uint32 withdrawalEpoch) external view returns (WithdrawalRequest[] memory);
+
+ Return a list of all the backward transfers executed in a specific withdrawal epoch.
+
+- backwardTransfer
+
+ function backwardTransfer(MCAddress mcAddress) external payable returns (WithdrawalRequest memory);
+
+ Add a new withdrawal request: if the transaction will be executed, the backward transfer will not be immediately sent to the mainchain but will be enqued to be processed at the end of the withdrawal epoch, when all the requests will be packed into a certificate and sent to the manchain for approval.
+ **Important**: the mcAddress parameter is not directly the mainchain address but its Pay to Script Hash (20 bytes)
+
+
+
+
+
+
+
+
+
diff --git a/doc/nativesc/contracts/WithdrawalRequests.sol b/doc/nativesc/contracts/WithdrawalRequests.sol
new file mode 100644
index 0000000..e8c7c1c
--- /dev/null
+++ b/doc/nativesc/contracts/WithdrawalRequests.sol
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.0;
+
+type MCAddress is bytes20;
+
+// contract address: 0x0000000000000000000011111111111111111111
+interface WithdrawalRequests {
+
+ struct WithdrawalRequest {
+ MCAddress mcAddress;
+ uint256 value;
+ }
+
+ // Event declaration
+ // Up to 3 parameters can be indexed.
+ // Indexed parameters helps you filter the logs by the indexed parameter
+ event AddWithdrawalRequest(address indexed sender, bytes20 indexed mcDest, uint256 value, uint32 epochNumber);
+
+
+ function getBackwardTransfers(uint32 withdrawalEpoch) external view returns (WithdrawalRequest[] memory);
+
+ function backwardTransfer(MCAddress mcAddress) external payable returns (WithdrawalRequest memory);
+}
diff --git a/doc/nativesc/index.md b/doc/nativesc/index.md
new file mode 100644
index 0000000..a168ec6
--- /dev/null
+++ b/doc/nativesc/index.md
@@ -0,0 +1,15 @@
+# EON Native Smart Contracts Documentation
+
+EON offers several native smart contracts available by default at a predefined address.
+They can be invoked as any standard smart contract with rpc method calls or (starting from EON 1.2) referenced by another smart contract.
+
+Below a detailed list:
+
+[WithdrawalRequests](/doc/nativesc/contracts/WithdrawalRequests.md)
+[ForgerStakes](/doc/nativesc/contracts/ForgerStakes.md)
+[McAddrOwnerships](/doc/nativesc/contracts/McAddrOwnership.md)
+[CertKeyRotation](/doc/nativesc/contracts/CertKeyRotation.md)
+
+
+
+
diff --git a/doc/release/1.3.0.md b/doc/release/1.3.0.md
new file mode 100644
index 0000000..b7c28b5
--- /dev/null
+++ b/doc/release/1.3.0.md
@@ -0,0 +1,19 @@
+# Release notes - version 1.3.0
+---
+
+## Notes about new/updated Features
+The 1.3.0 version has been updated to the 0.11.0 SDK version, which introduces several additions: refer to [SDK release notes](https://github.com/HorizenOfficial/Sidechains-SDK/tree/dev/doc/release/0.11.0.md) for a detailed explanation.
+
+### Forger reward address
+See SDK release notes for an explanation of the feature.
+If using docker, you can just configure the env property SCNODE_FORGER_REWARD_ADDRESS: the config file will be automatically generated accordingly.
+
+### Custom log4j file support in docker
+If using docker, it is now possible to configure the env property SCNODE_LOG4J_CUSTOM_CONFIG to use a completely custom log4j configuration file. See ['Advanced logging customization'
+ section in this help](../howto/customlog.md) for further info.
+
+ ### Pause forging
+Please be aware that starting from this version EON block production may temporarily pause if the mainchain block production slows down: EON forgers will automatically stop to produce new blocks if in the latest 99 EON Blocks no reference to mainchain blocks is present.
+
+---
+Full [Changelog](/CHANGELOG.md) available.
diff --git a/dockerfiles/evmapp/Dockerfile b/dockerfiles/evmapp/Dockerfile
index e96ab21..a2e84cc 100644
--- a/dockerfiles/evmapp/Dockerfile
+++ b/dockerfiles/evmapp/Dockerfile
@@ -81,6 +81,7 @@ RUN set -eEuo pipefail && mv /sidechain/entrypoint.sh /usr/local/bin/entrypoint.
jq \
netcat-openbsd \
apache2-utils \
+ ipv6calc \
&& savedAptMark="$(apt-mark showmanual)" \
&& if ! command -v gosu &> /dev/null; then \
if ! command -v gpg2 &> /dev/null; then \
diff --git a/dockerfiles/evmapp/entrypoint.sh b/dockerfiles/evmapp/entrypoint.sh
index 52b7189..9d1be79 100755
--- a/dockerfiles/evmapp/entrypoint.sh
+++ b/dockerfiles/evmapp/entrypoint.sh
@@ -1,6 +1,14 @@
#!/bin/bash
set -eEuo pipefail
+# check if this is an unsupported CPU, warn the user and bail
+if ! grep -iq adx /proc/cpuinfo || ! grep -iq bmi2 /proc/cpuinfo; then
+ echo "Error: the host does not support the required 'adx' and 'bmi2' CPU flags. The application cannot run on older CPUs. Exiting..."
+ sleep 5
+ exit 1
+fi
+
+
USER_ID="${LOCAL_USER_ID:-9001}"
GRP_ID="${LOCAL_GRP_ID:-9001}"
LD_PRELOAD="${LD_PRELOAD:-}"
@@ -13,6 +21,8 @@ MAX_OUTGOING_CONNECTIONS=""
WS_ADDRESS=""
ONLY_CONNECT_TO_KNOWN_PEERS=""
FORGER_MAXCONNECTIONS=""
+FORGER_REWARD_ADDRESS=""
+LOG4J_CUSTOM_CONFIG=""
SCNODE_REMOTE_KEY_MANAGER_ENABLED="${SCNODE_REMOTE_KEY_MANAGER_ENABLED:-false}"
export SCNODE_REMOTE_KEY_MANAGER_ENABLED
@@ -97,6 +107,16 @@ else
fi
export SCNODE_NET_DECLAREDADDRESS
+#Custom log4j file (optional)
+if [ -n "${SCNODE_LOG4J_CUSTOM_CONFIG:-}" ]; then
+ if ! [ -f "${SCNODE_LOG4J_CUSTOM_CONFIG}" ]; then
+ echo "Error: Custom log4j file was not found under the provided path = ${SCNODE_LOG4J_CUSTOM_CONFIG}. Please check the value of the environment variable 'SCNODE_LOG4J_CUSTOM_CONFIG' and make sure your custom log4j file is correctly mapped to the container."
+ sleep 5
+ exit 1
+ fi
+ LOG4J_CUSTOM_CONFIG="-Dlog4j.configurationFile=${SCNODE_LOG4J_CUSTOM_CONFIG}"
+fi
+
to_check=(
"SCNODE_CERT_SIGNERS_MAXPKS"
"SCNODE_CERT_SIGNERS_PUBKEYS"
@@ -201,14 +221,22 @@ if [ "${SCNODE_CERT_SIGNING_ENABLED:-}" = "true" ]; then
fi
fi
-
if [ "${SCNODE_FORGER_ENABLED:-}" = "true" ] || [ "${SCNODE_CERT_SUBMITTER_ENABLED:-}" = "true" ]; then
if [ -z "${SCNODE_WS_ZEN_FQDN:-}" ]; then
echo "Error: Environment variable SCNODE_WS_ZEN_FQDN is required when SCNODE_FORGER_ENABLED=true or SCNODE_CERT_SUBMITTER_ENABLED=true."
sleep 5
exit 1
+ fi
+fi
+
+if [ -n "${SCNODE_FORGER_REWARD_ADDRESS:-}" ]; then
+ if [ "${SCNODE_FORGER_ENABLED:-}" = "true" ]; then
+ FORGER_REWARD_ADDRESS="$(echo -en "\n forgerRewardAddress = \"${SCNODE_FORGER_REWARD_ADDRESS}\"")"
+ else
+ echo "Warn: Environment variable SCNODE_FORGER_REWARD_ADDRESS is set but will be ignored since forging is not enabled"
fi
fi
+export FORGER_REWARD_ADDRESS
# Checking SCNODE_FORGER_MAXCONNECTIONS for Forger nodes
if [ "${SCNODE_FORGER_ENABLED:-}" = "true" ]; then
@@ -228,7 +256,7 @@ if [ -n "${SCNODE_ONLY_CONNECT_TO_KNOWN_PEERS:-}" ]; then
fi
export ONLY_CONNECT_TO_KNOWN_PEERS
-# Flexibility for log levels
+# Flexibility for log levels and log file name
if [ -z "${SCNODE_LOG_FILE_LEVEL:-}" ]; then
SCNODE_LOG_FILE_LEVEL='info'
fi
@@ -236,7 +264,11 @@ fi
if [ -z "${SCNODE_LOG_CONSOLE_LEVEL:-}" ]; then
SCNODE_LOG_CONSOLE_LEVEL='info'
fi
-export SCNODE_LOG_FILE_LEVEL SCNODE_LOG_CONSOLE_LEVEL
+
+if [ -z "${SCNODE_LOG_FILE_NAME:-}" ]; then
+ SCNODE_LOG_FILE_NAME='debug.log'
+fi
+export SCNODE_LOG_FILE_LEVEL SCNODE_LOG_CONSOLE_LEVEL SCNODE_LOG_FILE_NAME
# set REST API password hash
if [ -n "${SCNODE_REST_PASSWORD:-}" ]; then
@@ -348,8 +380,8 @@ SUBST='$SCNODE_CERT_MASTERS_PUBKEYS:$SCNODE_CERT_SIGNERS_MAXPKS:$SCNODE_CERT_SIG
'$SCNODE_GENESIS_WITHDRAWALEPOCHLENGTH:$SCNODE_GENESIS_COMMTREEHASH:$SCNODE_GENESIS_ISNONCEASING:$SCNODE_ALLOWED_FORGERS:$SCNODE_FORGER_ENABLED:$SCNODE_FORGER_RESTRICT:'\
'$SCNODE_NET_DECLAREDADDRESS:$SCNODE_NET_KNOWNPEERS:$SCNODE_NET_MAGICBYTES:$SCNODE_NET_NODENAME:$SCNODE_NET_P2P_PORT:$SCNODE_NET_API_LIMITER_ENABLED:$SCNODE_NET_SLOW_MODE:$SCNODE_NET_REBROADCAST_TXS:$SCNODE_NET_HANDLING_TXS:'\
'$SCNODE_WALLET_GENESIS_SECRETS:$SCNODE_WALLET_MAXTX_FEE:$SCNODE_WALLET_SEED:$WS_ADDRESS:$MAX_INCOMING_CONNECTIONS:$MAX_OUTGOING_CONNECTIONS:$SCNODE_WS_SERVER_PORT:'\
-'$SCNODE_WS_CLIENT_ENABLED:$SCNODE_WS_SERVER_ENABLED:$SCNODE_REMOTE_KEY_MANAGER_ENABLED:$SCNODE_REMOTE_KEY_MANAGER_ADDRESS:$SCNODE_LOG_FILE_LEVEL:$SCNODE_LOG_CONSOLE_LEVEL:$REMOTE_KEY_MANAGER_REQUEST_TIMEOUT:$REMOTE_KEY_MANAGER_PARALLEL_REQUESTS:'\
-'$SCNODE_REST_APIKEYHASH:$SCNODE_REST_PORT:$ONLY_CONNECT_TO_KNOWN_PEERS:$FORGER_MAXCONNECTIONS'\
+'$SCNODE_WS_CLIENT_ENABLED:$SCNODE_WS_SERVER_ENABLED:$SCNODE_REMOTE_KEY_MANAGER_ENABLED:$SCNODE_REMOTE_KEY_MANAGER_ADDRESS:$SCNODE_LOG_FILE_LEVEL:$SCNODE_LOG_CONSOLE_LEVEL:$SCNODE_LOG_FILE_NAME:$REMOTE_KEY_MANAGER_REQUEST_TIMEOUT:$REMOTE_KEY_MANAGER_PARALLEL_REQUESTS:'\
+'$SCNODE_REST_APIKEYHASH:$SCNODE_REST_PORT:$ONLY_CONNECT_TO_KNOWN_PEERS:$FORGER_MAXCONNECTIONS:$FORGER_REWARD_ADDRESS'\
export SUBST
envsubst "${SUBST}" < /sidechain/config/sc_settings.conf.tmpl > /sidechain/config/sc_settings.conf
@@ -363,7 +395,11 @@ path_to_jemalloc="$(ldconfig -p | grep "$(arch)" | grep 'libjemalloc\.so\.2$' |
export LD_PRELOAD="${path_to_jemalloc}:${LD_PRELOAD}"
if [ "${1}" = "/usr/bin/true" ]; then
- set -- java -cp '/sidechain/'"${SC_JAR_NAME}"'-'"${SC_VERSION}"'.jar:/sidechain/lib/*' "$SC_MAIN_CLASS" "$SC_CONF_PATH"
+ if [ -z "${LOG4J_CUSTOM_CONFIG:-}" ]; then
+ set -- java -cp '/sidechain/'"${SC_JAR_NAME}"'-'"${SC_VERSION}"'.jar:/sidechain/lib/*' "$SC_MAIN_CLASS" "$SC_CONF_PATH"
+ else
+ set -- java -cp '/sidechain/'"${SC_JAR_NAME}"'-'"${SC_VERSION}"'.jar:/sidechain/lib/*' "${LOG4J_CUSTOM_CONFIG}" "$SC_MAIN_CLASS" "$SC_CONF_PATH"
+ fi
fi
echo "Username: ${USERNAME}, UID: ${CURRENT_UID}, GID: ${CURRENT_GID}"
diff --git a/dockerfiles/evmapp/sc_settings.conf.tmpl b/dockerfiles/evmapp/sc_settings.conf.tmpl
index f70a3e2..8d5f9c3 100644
--- a/dockerfiles/evmapp/sc_settings.conf.tmpl
+++ b/dockerfiles/evmapp/sc_settings.conf.tmpl
@@ -3,7 +3,7 @@ sparkz {
logDir = /sidechain/logs
logInfo {
- logFileName = "debug.log"
+ logFileName = "$SCNODE_LOG_FILE_NAME"
# levels: off, fatal, error, warn, info, debug, trace, all
logFileLevel = "$SCNODE_LOG_FILE_LEVEL"
logConsoleLevel = "$SCNODE_LOG_CONSOLE_LEVEL"
@@ -82,7 +82,7 @@ sparkz {
forger {
automaticForging = $SCNODE_FORGER_ENABLED
restrictForgers = $SCNODE_FORGER_RESTRICT
- allowedForgersList = [$SCNODE_ALLOWED_FORGERS]
+ allowedForgersList = [$SCNODE_ALLOWED_FORGERS]$FORGER_REWARD_ADDRESS
}
remoteKeysManager {
diff --git a/node/pom.xml b/node/pom.xml
index 637a9ae..0934482 100644
--- a/node/pom.xml
+++ b/node/pom.xml
@@ -3,7 +3,7 @@
4.0.0
io.horizen
eon
- 1.2.1
+ 1.3.0
2023
UTF-8
@@ -11,7 +11,7 @@
11
3.8.1
3.1.1
- 0.10.1
+ 0.11.0
diff --git a/node/src/main/java/io/horizen/eon/ApplicationConstants.java b/node/src/main/java/io/horizen/eon/ApplicationConstants.java
index 51622ba..a3e6a9e 100644
--- a/node/src/main/java/io/horizen/eon/ApplicationConstants.java
+++ b/node/src/main/java/io/horizen/eon/ApplicationConstants.java
@@ -10,6 +10,7 @@ private ApplicationConstants() {}
static final long MAINNET_ID = 7332L;
static final int MAINCHAIN_BLOCK_REFERENCE_DELAY = 6; // in number of mainchain blocks
+ static final int MAX_HISTORY_REWRITING_LENGTH = 100; // max number of SC blocks that can be reverted; in number of SC blocks
public static final String PREGOBI_SIDECHAINID = "1f758350754c12ac8f75a547f745b75eb744b382e15d0d3b0e24a4b5c5acde00";
public static final String GOBI_SIDECHAINID = "264a664c87d438b6983e0e071293e0e50b37eb12976eaa2dcd08d6a1ee16ca71";
diff --git a/node/src/main/java/io/horizen/eon/EonAppModule.java b/node/src/main/java/io/horizen/eon/EonAppModule.java
index aee0872..3a03f27 100644
--- a/node/src/main/java/io/horizen/eon/EonAppModule.java
+++ b/node/src/main/java/io/horizen/eon/EonAppModule.java
@@ -99,6 +99,10 @@ public void configureApp() {
bind(String.class)
.annotatedWith(Names.named("AppVersion"))
.toInstance(getEONVersion());
+
+ bind(Integer.class)
+ .annotatedWith(Names.named("MaxHistoryRewriteLength"))
+ .toInstance(MAX_HISTORY_REWRITING_LENGTH);
}
/**
diff --git a/node/src/main/java/io/horizen/eon/EonForkConfigurator.java b/node/src/main/java/io/horizen/eon/EonForkConfigurator.java
index 58fa01a..4e6fb27 100644
--- a/node/src/main/java/io/horizen/eon/EonForkConfigurator.java
+++ b/node/src/main/java/io/horizen/eon/EonForkConfigurator.java
@@ -1,190 +1,27 @@
package io.horizen.eon;
-import io.horizen.account.fork.ContractInteroperabilityFork;
-import io.horizen.account.fork.GasFeeFork;
-import io.horizen.account.fork.ZenDAOFork;
+import io.horizen.eon.forks.*;
import io.horizen.fork.*;
import io.horizen.utils.Pair;
-
-import java.math.BigInteger;
+import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
-import io.horizen.account.fork.Version1_2_0Fork;
public class EonForkConfigurator extends ForkConfigurator {
- //EON fork 1: change of fee params
- static final int F1_REGTEST_FORKPOINT = 7;
- static final int F1_PREGOBI_TESTNET_FORKPOINT = 718;
- static final int F1_GOBI_TESTNET_FORKPOINT = 624;
- static final int F1_TESTNET_FORKPOINT = 0;
- static final int F1_MAINNET_FORKPOINT = 0;
-
- //EON fork 2: ZenDAO + Change of consensus params + change of active slot coefficient
- static final int F2_REGTEST_FORKPOINT = 7;
- static final int F2_PREGOBI_TESTNET_FORKPOINT = 1698; //estimated start: Wed 13 Sept 2023 15:31 Milano time
- static final int F2_GOBI_TESTNET_FORKPOINT = 1804; ///estimated start: Mon 09 Oct 2023 16:21 Milano time
- static final int F2_TESTNET_FORKPOINT = 800;
- static final int F2_MAINNET_FORKPOINT = 1109; ///estimated start: Thu 19 Oct 2023 15:55 Milano time
-
- //EON fork 3: Native <> Real smart contract interoperability
- static final int F3_REGTEST_FORKPOINT = 7;
- static final int F3_PREGOBI_TESTNET_FORKPOINT = 1815; //estimated start: Mon 13 Nov 2023 13:01 Milano time
- static final int F3_GOBI_TESTNET_FORKPOINT = 1900; //estimated start; Tue 28 Nov 11 2023 15:21 Milano time
- static final int F3_TESTNET_FORKPOINT = 1900; //not used
- static final int F3_MAINNET_FORKPOINT = 1213; //estimated start; Tue 12 Dec 2023 18:55 Milano time
-
- //EON fork 4: ZenIP 42203/42206, ZenDao Multisig
- static final int F4_REGTEST_FORKPOINT = 7;
- static final int F4_PREGOBI_TESTNET_FORKPOINT = 1875; //estimated start: Thu 14 Dec 2023 19:01 Milano time
- static final int F4_GOBI_TESTNET_FORKPOINT = 1982; //estimated start: Wed 10 Jan 2024 08:21 Milano time
- static final int F4_TESTNET_FORKPOINT = 1982; //not used
- static final int F4_MAINNET_FORKPOINT = 1297; //estimated start: Thu 25 Jan 2024 12:55 Milano Time
-
-
-
-
-
private final SidechainForkConsensusEpoch mandatorySidechainFork1;
private final List> optionalSidechainForks;
public EonForkConfigurator(Optional sidechainId) {
- // block gas limit: 10 million
- // minimum base fee: 20 Gwei (20*10^9)
- GasFeeFork feeFork1Params = new GasFeeFork(
- // block gas limit: 10 million
- BigInteger.valueOf(10000000),
- BigInteger.valueOf(2),
- BigInteger.valueOf(8),
- // minimum base fee: 20 Gwei (20*10^9)
- BigInteger.valueOf(20000000000L)
- );
-
- ZenDAOFork zenDAOFork = new ZenDAOFork(true);
-
- ConsensusParamsFork consensusParamsFork = new ConsensusParamsFork(15000, 3);
-
- ActiveSlotCoefficientFork activeSlotCoefficientFork = new ActiveSlotCoefficientFork(0.167);
-
-
- optionalSidechainForks = List.of(
- new Pair<>(new SidechainForkConsensusEpoch(
- F1_REGTEST_FORKPOINT,
- getFeeForkTestnetActivation(sidechainId),
- F1_MAINNET_FORKPOINT),
- feeFork1Params),
-
- new Pair<>(new SidechainForkConsensusEpoch(
- F2_REGTEST_FORKPOINT,
- getFork2TestnetActivation(sidechainId),
- F2_MAINNET_FORKPOINT),
- zenDAOFork),
-
- new Pair<>(new SidechainForkConsensusEpoch(
- F2_REGTEST_FORKPOINT,
- getFork2TestnetActivation(sidechainId),
- F2_MAINNET_FORKPOINT),
- consensusParamsFork),
-
- new Pair<>(new SidechainForkConsensusEpoch(
- F2_REGTEST_FORKPOINT,
- getFork2TestnetActivation(sidechainId),
- F2_MAINNET_FORKPOINT),
- activeSlotCoefficientFork),
-
- new Pair<>(
- new SidechainForkConsensusEpoch(
- F3_REGTEST_FORKPOINT,
- getFork3TestnetActivation(sidechainId),
- F3_MAINNET_FORKPOINT),
- new ContractInteroperabilityFork(true)
- ),
-
- new Pair<>(
- new SidechainForkConsensusEpoch(
- F4_REGTEST_FORKPOINT,
- getFork4TestnetActivation(sidechainId),
- F4_MAINNET_FORKPOINT),
- new Version1_2_0Fork(true)
- )
-
- );
+ optionalSidechainForks = new ArrayList<>();
+ optionalSidechainForks.addAll(new F1Fork(sidechainId).getPairs());
+ optionalSidechainForks.addAll(new F2Fork(sidechainId).getPairs());
+ optionalSidechainForks.addAll(new F3Fork(sidechainId).getPairs());
+ optionalSidechainForks.addAll(new F4Fork(sidechainId).getPairs());
+ optionalSidechainForks.addAll(new F5Fork(sidechainId).getPairs());
mandatorySidechainFork1 = new SidechainForkConsensusEpoch(0, 0, 0);
}
- private int getFeeForkTestnetActivation(Optional sidechainId){
- if (sidechainId.isPresent()){
- switch (sidechainId.get()){
- case ApplicationConstants.PREGOBI_SIDECHAINID:
- //Pre-Gobi (parallel testnet) fork configuration
- return F1_PREGOBI_TESTNET_FORKPOINT;
- case ApplicationConstants.GOBI_SIDECHAINID:
- //Gobi (official testnet) fork configuration
- return F1_GOBI_TESTNET_FORKPOINT;
- default:
- //any other testnet
- return F1_TESTNET_FORKPOINT;
- }
- }else{
- return F1_TESTNET_FORKPOINT;
- }
- }
-
- private int getFork2TestnetActivation(Optional sidechainId){
- if (sidechainId.isPresent()){
- switch (sidechainId.get()){
- case ApplicationConstants.PREGOBI_SIDECHAINID:
- //Pre-Gobi (parallel testnet) fork configuration
- return F2_PREGOBI_TESTNET_FORKPOINT;
- case ApplicationConstants.GOBI_SIDECHAINID:
- //Gobi (official testnet) fork configuration
- return F2_GOBI_TESTNET_FORKPOINT;
- default:
- //any other testnet
- return F2_TESTNET_FORKPOINT;
- }
- } else {
- return F2_TESTNET_FORKPOINT;
- }
- }
-
- private int getFork3TestnetActivation(Optional sidechainId){
- if (sidechainId.isPresent()){
- switch (sidechainId.get()){
- case ApplicationConstants.PREGOBI_SIDECHAINID:
- //Pre-Gobi (parallel testnet) fork configuration
- return F3_PREGOBI_TESTNET_FORKPOINT;
- case ApplicationConstants.GOBI_SIDECHAINID:
- //Gobi (official testnet) fork configuration
- return F3_GOBI_TESTNET_FORKPOINT;
- default:
- //any other testnet
- return F3_TESTNET_FORKPOINT;
- }
- } else {
- return F3_TESTNET_FORKPOINT;
- }
- }
-
- private int getFork4TestnetActivation(Optional sidechainId){
- if (sidechainId.isPresent()){
- switch (sidechainId.get()){
- case ApplicationConstants.PREGOBI_SIDECHAINID:
- //Pre-Gobi (parallel testnet) fork configuration
- return F4_PREGOBI_TESTNET_FORKPOINT;
- case ApplicationConstants.GOBI_SIDECHAINID:
- //Gobi (official testnet) fork configuration
- return F4_GOBI_TESTNET_FORKPOINT;
- default:
- //any other testnet
- return F4_TESTNET_FORKPOINT;
- }
- } else {
- return F4_TESTNET_FORKPOINT;
- }
- }
-
-
@Override
public SidechainForkConsensusEpoch fork1activation() {
return mandatorySidechainFork1;
@@ -194,4 +31,4 @@ public SidechainForkConsensusEpoch fork1activation() {
public List> getOptionalSidechainForks() {
return optionalSidechainForks;
}
-}
+}
\ No newline at end of file
diff --git a/node/src/main/java/io/horizen/eon/forks/EONFork.java b/node/src/main/java/io/horizen/eon/forks/EONFork.java
new file mode 100644
index 0000000..4ae6725
--- /dev/null
+++ b/node/src/main/java/io/horizen/eon/forks/EONFork.java
@@ -0,0 +1,47 @@
+package io.horizen.eon.forks;
+
+import io.horizen.eon.ApplicationConstants;
+import io.horizen.fork.OptionalSidechainFork;
+import io.horizen.fork.SidechainForkConsensusEpoch;
+import io.horizen.utils.Pair;
+
+import java.util.List;
+import java.util.Optional;
+
+public abstract class EONFork {
+
+ protected Optional sidechainId;
+
+ protected abstract int getActivationRegtest();
+ protected abstract int getActivationTestnetPregobi();
+ protected abstract int getActivationTestnetGobi();
+ protected abstract int getActivationTestnet();
+ protected abstract int getActivationMainnet();
+
+ public EONFork(Optional sidechainId){
+ this.sidechainId = sidechainId;
+ }
+
+ public abstract List> getPairs();
+
+ protected int getActivationTestnet(Optional sidechainId){
+ if (sidechainId.isPresent()){
+ switch (sidechainId.get()){
+ case ApplicationConstants.PREGOBI_SIDECHAINID:
+ //Pre-Gobi (parallel testnet) fork configuration
+ return getActivationTestnetPregobi();
+ case ApplicationConstants.GOBI_SIDECHAINID:
+ //Gobi (official testnet) fork configuration
+ return getActivationTestnetGobi();
+ default:
+ //any other testnet
+ return getActivationTestnet();
+ }
+ } else {
+ return getActivationTestnet();
+ }
+ }
+
+
+
+}
diff --git a/node/src/main/java/io/horizen/eon/forks/F1Fork.java b/node/src/main/java/io/horizen/eon/forks/F1Fork.java
new file mode 100644
index 0000000..0a0633c
--- /dev/null
+++ b/node/src/main/java/io/horizen/eon/forks/F1Fork.java
@@ -0,0 +1,62 @@
+package io.horizen.eon.forks;
+
+import io.horizen.account.fork.GasFeeFork;
+import io.horizen.fork.OptionalSidechainFork;
+import io.horizen.fork.SidechainForkConsensusEpoch;
+import io.horizen.utils.Pair;
+import java.math.BigInteger;
+import java.util.List;
+import java.util.Optional;
+
+/**
+EON fork 1: change of fee params
+ */
+public class F1Fork extends EONFork {
+
+ // block gas limit: 10 million
+ // minimum base fee: 20 Gwei (20*10^9)
+ private GasFeeFork feeFork1Params = new GasFeeFork(
+ // block gas limit: 10 million
+ BigInteger.valueOf(10000000),
+ BigInteger.valueOf(2),
+ BigInteger.valueOf(8),
+ // minimum base fee: 20 Gwei (20*10^9)
+ BigInteger.valueOf(20000000000L)
+ );
+
+ @Override
+ protected int getActivationRegtest() {
+ return 7;
+ }
+ @Override
+ protected int getActivationTestnetPregobi() {
+ return 718;
+ }
+ @Override
+ protected int getActivationTestnetGobi() {
+ return 624;
+ }
+ @Override
+ protected int getActivationTestnet() {
+ return 0;
+ }
+ @Override
+ protected int getActivationMainnet() {
+ return 0;
+ }
+
+ public F1Fork(Optional sidechainId) {
+ super(sidechainId);
+ }
+
+ @Override
+ public List> getPairs() {
+ return List.of(
+ new Pair<>(new SidechainForkConsensusEpoch(
+ getActivationRegtest(),
+ getActivationTestnet(sidechainId),
+ getActivationMainnet()),
+ feeFork1Params)
+ );
+ }
+}
diff --git a/node/src/main/java/io/horizen/eon/forks/F2Fork.java b/node/src/main/java/io/horizen/eon/forks/F2Fork.java
new file mode 100644
index 0000000..d952fd0
--- /dev/null
+++ b/node/src/main/java/io/horizen/eon/forks/F2Fork.java
@@ -0,0 +1,68 @@
+package io.horizen.eon.forks;
+
+import io.horizen.account.fork.ZenDAOFork;
+import io.horizen.fork.ActiveSlotCoefficientFork;
+import io.horizen.fork.ConsensusParamsFork;
+import io.horizen.fork.OptionalSidechainFork;
+import io.horizen.fork.SidechainForkConsensusEpoch;
+import io.horizen.utils.Pair;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * EON fork 2: ZenDAO + Change of consensus params + change of active slot coefficient
+ */
+public class F2Fork extends EONFork {
+
+ private ZenDAOFork zenDAOFork = new ZenDAOFork(true);
+ private ConsensusParamsFork consensusParamsFork = new ConsensusParamsFork(15000, 3);
+ private ActiveSlotCoefficientFork activeSlotCoefficientFork = new ActiveSlotCoefficientFork(0.167);
+
+ public F2Fork(Optional sidechainId) {
+ super(sidechainId);
+ }
+
+ @Override
+ protected int getActivationRegtest() {
+ return 7;
+ }
+ @Override
+ protected int getActivationTestnetPregobi() {
+ return 1698; //estimated start: Wed 13 Sept 2023 15:31 Milano time
+ }
+ @Override
+ protected int getActivationTestnetGobi() {
+ return 1804; ///estimated start: Mon 09 Oct 2023 16:21 Milano time
+ }
+ @Override
+ protected int getActivationTestnet() {
+ return 800;
+ }
+ @Override
+ protected int getActivationMainnet() {
+ return 1109; ///estimated start: Thu 19 Oct 2023 15:55 Milano time
+ }
+
+ @Override
+ public List> getPairs() {
+ return List.of(
+ new Pair<>(new SidechainForkConsensusEpoch(
+ getActivationRegtest(),
+ getActivationTestnet(sidechainId),
+ getActivationMainnet()),
+ zenDAOFork),
+
+ new Pair<>(new SidechainForkConsensusEpoch(
+ getActivationRegtest(),
+ getActivationTestnet(sidechainId),
+ getActivationMainnet()),
+ consensusParamsFork),
+
+ new Pair<>(new SidechainForkConsensusEpoch(
+ getActivationRegtest(),
+ getActivationTestnet(sidechainId),
+ getActivationMainnet()),
+ activeSlotCoefficientFork)
+ );
+ }
+}
\ No newline at end of file
diff --git a/node/src/main/java/io/horizen/eon/forks/F3Fork.java b/node/src/main/java/io/horizen/eon/forks/F3Fork.java
new file mode 100644
index 0000000..5f22cd7
--- /dev/null
+++ b/node/src/main/java/io/horizen/eon/forks/F3Fork.java
@@ -0,0 +1,53 @@
+package io.horizen.eon.forks;
+
+import io.horizen.account.fork.ContractInteroperabilityFork;
+import io.horizen.fork.OptionalSidechainFork;
+import io.horizen.fork.SidechainForkConsensusEpoch;
+import io.horizen.utils.Pair;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * EON fork 3: Native <> Real smart contract interoperability
+ */
+public class F3Fork extends EONFork {
+
+
+ public F3Fork(Optional sidechainId) {
+ super(sidechainId);
+ }
+
+ @Override
+ protected int getActivationRegtest() {
+ return 7;
+ }
+ @Override
+ protected int getActivationTestnetPregobi() {
+ return 1815; //estimated start: Mon 13 Nov 2023 13:01 Milano time
+ }
+ @Override
+ protected int getActivationTestnetGobi() {
+ return 1900; //estimated start; Tue 28 Nov 11 2023 15:21 Milano time
+ }
+ @Override
+ protected int getActivationTestnet() { return 1900; //not used
+ }
+ @Override
+ protected int getActivationMainnet() {
+ return 1213; //estimated start; Tue 12 Dec 2023 18:55 Milano time
+ }
+
+ @Override
+ public List> getPairs() {
+ return List.of(
+ new Pair<>(
+ new SidechainForkConsensusEpoch(
+ getActivationRegtest(),
+ getActivationTestnet(sidechainId),
+ getActivationMainnet()),
+ new ContractInteroperabilityFork(true)
+ )
+ );
+ }
+}
\ No newline at end of file
diff --git a/node/src/main/java/io/horizen/eon/forks/F4Fork.java b/node/src/main/java/io/horizen/eon/forks/F4Fork.java
new file mode 100644
index 0000000..1b555ea
--- /dev/null
+++ b/node/src/main/java/io/horizen/eon/forks/F4Fork.java
@@ -0,0 +1,51 @@
+package io.horizen.eon.forks;
+
+import io.horizen.account.fork.Version1_2_0Fork;
+import io.horizen.fork.OptionalSidechainFork;
+import io.horizen.fork.SidechainForkConsensusEpoch;
+import io.horizen.utils.Pair;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * EON fork 4 (introduced in Version 1.2.0)
+ * ZenIP 42203/42206, ZenDao Multisig
+ */
+public class F4Fork extends EONFork {
+ public F4Fork(Optional sidechainId) {
+ super(sidechainId);
+ }
+
+ @Override
+ protected int getActivationRegtest() {
+ return 7;
+ }
+ @Override
+ protected int getActivationTestnetPregobi() {
+ return 1875; //estimated start: Thu 14 Dec 2023 19:01 Milano time
+ }
+ @Override
+ protected int getActivationTestnetGobi() {
+ return 1982; //estimated start: Wed 10 Jan 2024 08:21 Milano time
+ }
+ @Override
+ protected int getActivationTestnet() { return 1982; //not used
+ }
+ @Override
+ protected int getActivationMainnet() {
+ return 1297; //estimated start: Thu 25 Jan 2024 12:55 Milano Time
+ }
+
+ @Override
+ public List> getPairs() {
+ return List.of(
+ new Pair<>(
+ new SidechainForkConsensusEpoch(
+ getActivationRegtest(),
+ getActivationTestnet(sidechainId),
+ getActivationMainnet()),
+ new Version1_2_0Fork(true)
+ )
+ );
+ }
+}
\ No newline at end of file
diff --git a/node/src/main/java/io/horizen/eon/forks/F5Fork.java b/node/src/main/java/io/horizen/eon/forks/F5Fork.java
new file mode 100644
index 0000000..c36c83b
--- /dev/null
+++ b/node/src/main/java/io/horizen/eon/forks/F5Fork.java
@@ -0,0 +1,50 @@
+package io.horizen.eon.forks;
+
+import io.horizen.account.fork.Version1_3_0Fork;
+import io.horizen.fork.OptionalSidechainFork;
+import io.horizen.fork.SidechainForkConsensusEpoch;
+import io.horizen.utils.Pair;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * EON fork 5 (introduced in Version 1.3.0)
+ * EVM update to Shanghai, Updates to native stake smart contract, Pause forging
+ */
+public class F5Fork extends EONFork {
+ public F5Fork(Optional sidechainId) {
+ super(sidechainId);
+ }
+
+ @Override
+ protected int getActivationRegtest() {
+ return 7;
+ }
+ @Override
+ protected int getActivationTestnetPregobi() {return 2007;} //estimated start at WED 21 Feb 2024 13:01 Milano time
+
+ @Override
+ protected int getActivationTestnetGobi() {
+ return 2101; //estimated start at TUE 12 March 2024 07:51 Milano time
+ }
+ @Override
+ protected int getActivationTestnet() { return 2101; //not used
+ }
+ @Override
+ protected int getActivationMainnet() {
+ return 1405; //estimated start at THU 21 March 2024 18:55 Milano time
+ }
+
+ @Override
+ public List> getPairs() {
+ return List.of(
+ new Pair<>(
+ new SidechainForkConsensusEpoch(
+ getActivationRegtest(),
+ getActivationTestnet(sidechainId),
+ getActivationMainnet()),
+ new Version1_3_0Fork(true)
+ )
+ );
+ }
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 8f0fe11..5b8488d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
io.horizen
eonproject
- 1.2.1
+ 1.3.0
pom
2023