diff --git a/.gitmodules b/.gitmodules index 71d8a40837..912de9d4a7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -8,4 +8,4 @@ [submodule "aion_vm_api"] path = aion_vm_api url = https://github.com/aionnetwork/vm_api.git - branch = dev + branch = master diff --git a/DOCKER.md b/DOCKER.md deleted file mode 100644 index c279ac0b8f..0000000000 --- a/DOCKER.md +++ /dev/null @@ -1,199 +0,0 @@ -# Dockerization - -Provides a container that can run the AION kernel. Can also attach a remote debugger if necessary. - -## Limitations - -Currently this image does NOT support running CLI commands before the kernel startup. -One needs to build a custom image and bake in other CLI commands if necessary (override the container startup script). - -## Prerequisites - -- docker-compose (docker-compose version 1.21.0, build 5920eb0) -- docker (>= Docker version 17.12.1-ce, build 7390fc6) - -The kernel can be deployed as a container using the Dockerfile present in the root of the repo. -The docker image can be built using the `packDocker` Gradle target. Local development can -leverage `./gradlew packDevDocker` to build a custom image based on current code base. - -## Building - -### Dev build - -```bash -./gradlew packDevDocker -``` - -##### Description - -This command will: -* build the project with `-Dcompile.debug=true` -* build a custom Docker image using the current code adding java debug libs for remote debugging (this requires -downloading a version of java different from the one automatically packed by the kernel binary) - -This build is conditioned by the `DEV_BUILD` argument in the `Dockerfile` so you can add more development related -behaviour by using this flag. - -##### Remote debug - -If you want to use the remote debugging feature: -* make sure you expose the correct port where you want to attach which is set in the `supporting-services.yml` -and defaults to `6006`: -```bash -- JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:6006 -Xms4g -``` - -* run the image as described below in [Running](#Running) and expose the debug port: -```bash -... --p 6006:6006 -... -``` - -**Note**: The image build uses the binary built in the `pack` directory by Gradle. -If you want to use a specific kernel binary download the binary from the official repo, rename it to `aion.tar.bz2` and -copy it to the `pack` directory - - -### Release build - -#### Build docker image - -```bash -./gradlew packDocker -``` - -This command will create 1 docker image with the tag value as `GITVER` variable from `script/prebuild.sh` which is the -short commit revision. -Eg: -```bash -aion-core:0.2.8f5317462 -``` - -#### Push docker image - -In order to have the image available for deployments/developers you need to tag and push it to you registry of choice manually. - -* tag image according to repo: -```bash -docker tag aion-core: /aion-core: -``` - -* push image: -```bash -docker push /aion-core: -``` - -## Running - -You can start your kernel container using the `docker run` command and you can override a few parameters by passing -environment variables to the command. - -Eg: - -```bash -docker run -it \ --p 8545:8545 \ --p 8547:8547 \ --e difficulty="0x1" \ --e mining="true" \ --e coinbase_password=p@ss \ --e java_api_listen_address="0.0.0.0" \ --e rpc_listen_address="0.0.0.0" \ --e peer_list="p2p://peer-id-1@10.10.10.10:3333,p2p://peer-id-2@12.12.12.12:4444" \ --e override_peer_list="true" \ -aion-core:0.2.8.f5317462 -``` - -**Note**: -We don't support setting options for the script as the container will have to be torn down after -running and recreated again. This is not feasible in a production environment. Instead of passing options to the startup -script we should provide a rpc/java API that will allow the required functionality to be present after kernel startup. -Until then we can still use that functionality by manually starting a bash session in the container and running -the commands that we need. - -Eg: - -* Start the container as described above -* In a separate terminal get the container id -```bash -docker ps -``` - -* Start a bash session in the container -```bash -docker exec -it bash -``` - -* Make sure you are in the `/opt/aion` directory and run your desired commands: -```bash -./aion.sh -a list -``` - -##### Expose API - -```bash -# Support for access outside of the container --e java_api_listen_address="0.0.0.0" \ --e rpc_listen_address="0.0.0.0" \ - -# Exposes the kernel API (web3 and java) --p 8545:8545 \ --p 8547:8547 \ -``` - -##### Override peer list - -```bash --e peer_list="p2p://peer-id-1@10.10.10.10:3333,p2p://peer-id-2@12.12.12.12:4444" \ --e override_peer_list="true" \ -``` - -##### Bootstrap internal mining - -**Note**: The override of these variables are mostly for local development/testing purposes. - -```bash -# This will lower the difficulty for slow machines and generate an account at startup and set it as the coinbase --e difficulty="0x1" \ --e mining="true" \ --e coinbase_password=p@ss \ -``` - - -**Note**: if you built a development image you can override parameters in the `supporting-services.yml` file and run it: - -```bash -docker-compose -f supporting-services.yml up -``` - -List of environment variables than can override xml properties: - -```bash -- difficulty -- coinbase_password -- rpc_listen_address -- rpc_listen_port -- cors_enabled -- apis_enabled -- java_api_listen_address -- java_api_listen_port -- p2p_listen_address -- p2p_listen_port -- discover -- mining -- miner_address -- cpu_mine_threads -- peer_list -- override_peer_list -- log_level_db -- log_level_vm -- log_level_gen -- log_level_api -- log_level_sync -- log_level_cons -- log_file -- log_path -``` - -If you need to override more properties, update `override-config.py` to support those properties. diff --git a/DockerAutomation/Dockerfile b/DockerAutomation/Dockerfile new file mode 100644 index 0000000000..c8ac34e402 --- /dev/null +++ b/DockerAutomation/Dockerfile @@ -0,0 +1,18 @@ +# dist stage: image for end-user distribution +FROM ubuntu:18.04 AS dist +WORKDIR / +RUN apt-get update && apt-get --no-install-recommends --yes install \ + wget \ + unzip \ + lsb-release \ + locales +ADD aion.tar.bz2 / +WORKDIR /aion +ENV LANG C.UTF-8 +ENV LC_ALL C.UTF-8 +CMD ["/aion/aion.sh"] + +# k8s stage: produce image for Kubernetes CI test cluster +FROM dist AS k8s +COPY k8s/custom custom +CMD ["/aion/aion.sh", "-n", "custom"] diff --git a/DockerAutomation/Jenkinsfile b/DockerAutomation/Jenkinsfile new file mode 100644 index 0000000000..c41a81199d --- /dev/null +++ b/DockerAutomation/Jenkinsfile @@ -0,0 +1,65 @@ +properties([[$class: 'jenkins.model.BuildDiscarderProperty', strategy: + [$class: 'LogRotator', numToKeepStr: '10', artifactNumToKeepStr: '10'] + ]]) + +node { + def appName = 'aion' + def deployName + def endPoint + + // docker tags + def k8sTag = "k8s-${env.BUILD_NUMBER}" + def k8sImageName = "aionkuberacr.azurecr.io/aion:${k8sTag}" + def k8sImageNameLatest = "aionkuberacr.azurecr.io/aion:latest" + def distImageName = "aionnetwork/aion-staging:ci-${env.BUILD_NUMBER}" + + stage('Clone repository') { + checkout scm + sh "git submodule update --init --recursive" + } + + stage('Create dist and k8s Docker images from source') { + sh "./gradlew packDocker packK8sDocker " + + "-Pdist_image_tag=${distImageName} " + + "-Pk8s_image_tag=${k8sImageName} " + } + + stage('Push k8s image to Azure private registry') { + docker.withRegistry('https://aionkuberacr.azurecr.io', 'acr') { + sh("docker push ${k8sImageName}") + sh("docker push ${k8sImageNameLatest}") + } + } + + stage("Deploy Image to Kubernetes") { + // Refresh kubectl (Python can have some issues refreshing) + sh('kubectl get nodes') + + withPythonEnv('python3') { + sh 'pip install -r DockerAutomation/k8s/requirements.txt' + deployName = sh(script: "python DockerAutomation/k8s/deploy.py ${k8sTag}", + returnStdout: true) + } + } + + stage("Fetch Deployment Endpoint") { + withPythonEnv('python3') { + endPoint = sh(script: "python DockerAutomation/k8s/find_endpoint.py ${deployName}", + returnStdout: true) + } + } + + stage("Run 'Test'") { + // TODO perform actual verification + sh("echo " + endPoint) + } + + // The rest of this pipeline should only execute when the tests in CI pass + // However, we don't have testing against it right now, so it always "passes" + + stage("Push dist image to DockerHub aion-staging") { + docker.withRegistry('', 'DockerHub') { + sh("docker push ${distImageName}") + } + } +} diff --git a/DockerAutomation/bin/enable-api-servers.py b/DockerAutomation/bin/enable-api-servers.py new file mode 100644 index 0000000000..e9fcaed4b3 --- /dev/null +++ b/DockerAutomation/bin/enable-api-servers.py @@ -0,0 +1,74 @@ +import os +import xml.etree.ElementTree +import subprocess +from xml.dom import minidom +import sys + +indentation = '\t' + +# borrowed from https://stackoverflow.com/questions/33573807/faithfully-preserve-comments-in-parsed-xml-python-2-7 +class CommentedTreeBuilder ( xml.etree.ElementTree.XMLTreeBuilder ): + def __init__ ( self, html = 0, target = None ): + xml.etree.ElementTree.XMLTreeBuilder.__init__( self, html, target ) + self._parser.CommentHandler = self.handle_comment + + def handle_comment ( self, data ): + self._target.start( xml.etree.ElementTree.Comment, {} ) + self._target.data( data ) + self._target.end( xml.etree.ElementTree.Comment ) + + +def override_attrib(element, attrib, name, value): + if name != None and value != None: + print('Overriding kernel property ' + element.tag + '/' + attrib + ' from ' + name + ' to ' + value) + element.attrib[attrib] = value + +# pretty printing does not work with ElementTree +# use this function after inserting new elements in the xml file +def indent(elem, level=0): + i = "\n" + level*indentation + if len(elem): + if not elem.text or not elem.text.strip(): + elem.text = i + indentation + if not elem.tail or not elem.tail.strip(): + elem.tail = i + for elem in elem: + indent(elem, level+1) + if not elem.tail or not elem.tail.strip(): + elem.tail = i + else: + if level and (not elem.tail or not elem.tail.strip()): + elem.tail = i + + +def go(config_file): + parser = xml.etree.ElementTree.XMLParser(target=CommentedTreeBuilder()) + et = xml.etree.ElementTree.parse(config_file, CommentedTreeBuilder()) + root = et.getroot() + + print(config_file + ':') + + api = root.find('api') + new_rpc = api.find('rpc') + override_attrib(new_rpc, 'active', 'false', 'true') + override_attrib(new_rpc, 'ip', '127.0.0.1', '0.0.0.0') + + new_java = api.find('java') + override_attrib(new_java, 'active', 'false', 'true') + override_attrib(new_java, 'ip', '127.0.0.1', '0.0.0.0') + + indent(root) + et.write(config_file, encoding='utf-8', xml_declaration=True) + + +if len(sys.argv) != 2: + print "usage: enable-api-servers.py AION-CONFIG-ROOT" + exit(1) +else: + root = sys.argv[1] + +go(root + '/mainnet/config.xml') +go(root + '/mastery/config.xml') +go(root + '/custom/config.xml') +go(root + '/conquest/config.xml') +go(root + '/avmtestnet/config.xml') diff --git a/k8s/aion_node.yaml b/DockerAutomation/k8s/aion_node.yaml similarity index 100% rename from k8s/aion_node.yaml rename to DockerAutomation/k8s/aion_node.yaml diff --git a/k8s/aion_seed.yaml b/DockerAutomation/k8s/aion_seed.yaml similarity index 100% rename from k8s/aion_seed.yaml rename to DockerAutomation/k8s/aion_seed.yaml diff --git a/k8s/custom/config/config.xml b/DockerAutomation/k8s/custom/config/config.xml similarity index 100% rename from k8s/custom/config/config.xml rename to DockerAutomation/k8s/custom/config/config.xml diff --git a/k8s/custom/config/fork.properties b/DockerAutomation/k8s/custom/config/fork.properties similarity index 100% rename from k8s/custom/config/fork.properties rename to DockerAutomation/k8s/custom/config/fork.properties diff --git a/k8s/custom/config/genesis.json b/DockerAutomation/k8s/custom/config/genesis.json similarity index 100% rename from k8s/custom/config/genesis.json rename to DockerAutomation/k8s/custom/config/genesis.json diff --git a/k8s/custom/keystore/UTC--2018-10-02T18:56:56.324Z--a037818674c51fafbb1da0656dd467076d6a00552e13dfb1137d3ca6f288b65f b/DockerAutomation/k8s/custom/keystore/UTC--2018-10-02T18:56:56.324Z--a037818674c51fafbb1da0656dd467076d6a00552e13dfb1137d3ca6f288b65f similarity index 100% rename from k8s/custom/keystore/UTC--2018-10-02T18:56:56.324Z--a037818674c51fafbb1da0656dd467076d6a00552e13dfb1137d3ca6f288b65f rename to DockerAutomation/k8s/custom/keystore/UTC--2018-10-02T18:56:56.324Z--a037818674c51fafbb1da0656dd467076d6a00552e13dfb1137d3ca6f288b65f diff --git a/k8s/custom/keystore/UTC--2018-10-02T18:57:16.584Z--a006ece379f27a301edd3e58feeca9847dc00f682c379fc9711929c0ca7e3835 b/DockerAutomation/k8s/custom/keystore/UTC--2018-10-02T18:57:16.584Z--a006ece379f27a301edd3e58feeca9847dc00f682c379fc9711929c0ca7e3835 similarity index 100% rename from k8s/custom/keystore/UTC--2018-10-02T18:57:16.584Z--a006ece379f27a301edd3e58feeca9847dc00f682c379fc9711929c0ca7e3835 rename to DockerAutomation/k8s/custom/keystore/UTC--2018-10-02T18:57:16.584Z--a006ece379f27a301edd3e58feeca9847dc00f682c379fc9711929c0ca7e3835 diff --git a/k8s/custom/keystore/UTC--2018-10-02T18:57:31.755Z--a06750add06961701f2e596681823de1b8fb116b3606bcae97e3f2b8feb52fdb b/DockerAutomation/k8s/custom/keystore/UTC--2018-10-02T18:57:31.755Z--a06750add06961701f2e596681823de1b8fb116b3606bcae97e3f2b8feb52fdb similarity index 100% rename from k8s/custom/keystore/UTC--2018-10-02T18:57:31.755Z--a06750add06961701f2e596681823de1b8fb116b3606bcae97e3f2b8feb52fdb rename to DockerAutomation/k8s/custom/keystore/UTC--2018-10-02T18:57:31.755Z--a06750add06961701f2e596681823de1b8fb116b3606bcae97e3f2b8feb52fdb diff --git a/k8s/deploy.py b/DockerAutomation/k8s/deploy.py similarity index 100% rename from k8s/deploy.py rename to DockerAutomation/k8s/deploy.py diff --git a/k8s/find_endpoint.py b/DockerAutomation/k8s/find_endpoint.py similarity index 100% rename from k8s/find_endpoint.py rename to DockerAutomation/k8s/find_endpoint.py diff --git a/k8s/list_deployments.py b/DockerAutomation/k8s/list_deployments.py similarity index 100% rename from k8s/list_deployments.py rename to DockerAutomation/k8s/list_deployments.py diff --git a/k8s/list_image.py b/DockerAutomation/k8s/list_image.py similarity index 100% rename from k8s/list_image.py rename to DockerAutomation/k8s/list_image.py diff --git a/k8s/modify_config.py b/DockerAutomation/k8s/modify_config.py similarity index 100% rename from k8s/modify_config.py rename to DockerAutomation/k8s/modify_config.py diff --git a/k8s/monitor_sync.py b/DockerAutomation/k8s/monitor_sync.py similarity index 100% rename from k8s/monitor_sync.py rename to DockerAutomation/k8s/monitor_sync.py diff --git a/k8s/redeploy.py b/DockerAutomation/k8s/redeploy.py similarity index 100% rename from k8s/redeploy.py rename to DockerAutomation/k8s/redeploy.py diff --git a/k8s/requirements.txt b/DockerAutomation/k8s/requirements.txt similarity index 100% rename from k8s/requirements.txt rename to DockerAutomation/k8s/requirements.txt diff --git a/k8s/seedStorage.yaml b/DockerAutomation/k8s/seedStorage.yaml similarity index 100% rename from k8s/seedStorage.yaml rename to DockerAutomation/k8s/seedStorage.yaml diff --git a/k8s/service.yaml b/DockerAutomation/k8s/service.yaml similarity index 100% rename from k8s/service.yaml rename to DockerAutomation/k8s/service.yaml diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 15bca081b6..0000000000 --- a/Dockerfile +++ /dev/null @@ -1,44 +0,0 @@ -ARG UBUNTU_VER=16.04 -FROM ubuntu:${UBUNTU_VER} - -LABEL maintainers="mihai.cojan@centrys.io, alexandru.laurus@centrys.io" - -# prepare for java instalation -RUN apt-get update && apt-get install -y bzip2 lsb-release wget curl jq locales net-tools libicu-dev libedit-dev libicu55 libedit2 libffi6 libtinfo5 -RUN apt-get clean - -# change locales to UTF-8 in order to avoid bug when changing config.xml -RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen -ENV LANG en_US.UTF-8 -ENV LANGUAGE en_US:en -ENV LC_ALL en_US.UTF-8 - -WORKDIR /opt - -# TODO: use java 10.0.2 -ARG DEV_BUILD=false -RUN if [ "${DEV_BUILD}" = "true" ]; then wget -O jdk.tar.gz \ -https://download.java.net/java/GA/jdk10/10.0.1/fb4372174a714e6b8c52526dc134031e/10/openjdk-10.0.1_linux-x64_bin.tar.gz; fi -RUN if [ "${DEV_BUILD}" = "true" ]; then tar -xf jdk.tar.gz; fi -RUN if [ "${DEV_BUILD}" = "true" ]; then rm -f jdk.tar.gz; fi - -ARG KERNEL_PATH=./pack/aion.tar.bz2 -# COPY has a different behaviour in docker-compose vs docker so we'll have to use ADD -# ADD does some magic and automatically unpacks so we need to fix that -ADD ${KERNEL_PATH} /opt/aion.tar.bz2 -# again different behaivour for ADD when unpacking in docker vs docker-compose -RUN if [ -d /opt/aion.tar.bz2/aion ]; then mkdir -p /opt/aion; fi -RUN if [ -d /opt/aion.tar.bz2/aion ]; then mv /opt/aion.tar.bz2/aion/* /opt/aion/; fi -RUN if [ -d /opt/aion.tar.bz2/aion ]; then rm -rf /opt/aion.tar.bz2; else mv /opt/aion.tar.bz2 /opt/aion; fi - -RUN if [ "${DEV_BUILD}" = "true" ]; then cp jdk-10.0.1/lib/libjdwp.so ./aion/rt/lib/.; fi -RUN if [ "${DEV_BUILD}" = "true" ]; then cp jdk-10.0.1/lib/libdt_socket.so ./aion/rt/lib/.; fi -RUN if [ "${DEV_BUILD}" = "true" ]; then rm -rf jdk-10.0.1; fi - -WORKDIR /opt/aion - -COPY ./override-config.py . -COPY ./create-coinbase.sh . -COPY ./aion-docker.sh . - -CMD [ "/bin/bash", "-c", "./aion-docker.sh" ] diff --git a/README.md b/README.md index f77f9c5510..a8d41af371 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,9 @@ This repository contains the main (Java) kernel implementation and releases for ## Getting Started ### Developers -If you're interested in application development on Aion or make improvements to the Java Implementation of Aion: +If you're interested in application development on Aion or making improvements to the Java Implementation of Aion: -* Refer to the details in the [Build Your Aion Network](https://github.com/aionnetwork/aion/wiki/Build-your-Aion-network) wiki to determine how to start setting up and building your Aion Network. +* Refer to the [Build Aion kernel from source](https://github.com/aionnetwork/aion/wiki/Build-Aion-kernel-from-source) wiki for information on building this source code to a native binary or Docker image * Refer to the [Installation](https://github.com/aionnetwork/aion/wiki/Installation) wiki for a guide on installing and configuring the kernel. * The [Owner's Manual](https://github.com/aionnetwork/aion/wiki/Aion-Owner's-Manual) wiki will include further instructions and details on working with the kernel. diff --git a/aion_fastvm b/aion_fastvm index 95cdff6147..eae7e1c0bc 160000 --- a/aion_fastvm +++ b/aion_fastvm @@ -1 +1 @@ -Subproject commit 95cdff61476efe27739e5d7ec96de255be298e58 +Subproject commit eae7e1c0bc5b84c99a4d3d5c85881608b2aeb5de diff --git a/aion_vm_api b/aion_vm_api index 3212356fb9..df350b1801 160000 --- a/aion_vm_api +++ b/aion_vm_api @@ -1 +1 @@ -Subproject commit 3212356fb914a361e8bde0beb6a60a96c40c5a8d +Subproject commit df350b1801abeb59be973acab06bf9b970df8848 diff --git a/build.gradle b/build.gradle index e5ea11cf41..3075e3d8b4 100644 --- a/build.gradle +++ b/build.gradle @@ -15,6 +15,7 @@ def javaHome = System.getProperty('java.home') def vmVersion = "0.3.2" def dirRuntimeJars = 'jars' // we'll store mod and lib stuff in here + allprojects { apply plugin: 'java' apply plugin: 'idea' @@ -24,6 +25,7 @@ allprojects { repositories { jcenter() + maven { url "https://oss.sonatype.org/content/groups/staging" } flatDir { dirs './lib' // does not recurse, don't make subdirectories in here @@ -303,13 +305,41 @@ task pack(type: Tar) { } } +task createPackConfigOverride(type: Copy) { + from "${rootDir}/config" + into "${dirPack}/config" +} + +task overridePackConfigForDocker(type: Exec) { + dependsOn createPackConfigOverride + commandLine 'python', 'DockerAutomation/bin/enable-api-servers.py', "${dirPack}/config" +} + +task copyPackForDocker(type: Copy) { + dependsOn pack, overridePackConfigForDocker + pack.mustRunAfter overridePackConfigForDocker + + from "${dirPack}/aion.tar.bz2" + from "${rootDir}/DockerAutomation" + into "${buildDir}/docker" +} + task packDocker(type: Exec) { - dependsOn pack - commandLine 'sh', "${dirWorkspace}/script/pack_docker.sh" + dependsOn copyPackForDocker + + def distImageTag = project.findProperty('dist_image_tag') ?: 'aionnetwork/aion:latest' + commandLine 'docker', 'build', + '--target', 'dist', '-t', distImageTag, + "${buildDir}/docker" } -task packDevDocker(type: Exec) { - commandLine 'sh', "${dirWorkspace}/script/pack_dev_docker.sh" +task packK8sDocker(type: Exec) { + dependsOn copyPackForDocker + + def k8sImageTag = project.findProperty('k8s_image_tag') ?: 'aionnetwork/aion-k8s:latest' + commandLine 'docker', 'build', + '--target', 'k8s', '-t', k8sImageTag, + "${buildDir}/docker" } clean { @@ -325,7 +355,6 @@ task ciBuild { def ciModules = [ 'aion_fastvm', 'modAion', - 'modAionBase', 'modAionImpl', 'modApiServer', 'modBoot', diff --git a/config/avmtestnet/config-seed1.xml b/config/avmtestnet/config-seed1.xml new file mode 100644 index 0000000000..e1708b55b1 --- /dev/null +++ b/config/avmtestnet/config-seed1.xml @@ -0,0 +1,102 @@ + + + aion + 10000000-0000-0000-0000-000000000000 + + + + true + + web3,eth,personal,stratum,ops + + + true + + + + 10E9 + + 100E9 + + false + + + + 31 + + p2p://10000000-0000-0000-0000-000000000000@138.91.123.106:30303 + p2p://20000000-0000-0000-0000-000000000000@23.100.52.181:30303 + p2p://30000000-0000-0000-0000-000000000000@13.91.127.35:30303 + + + 0.0.0.0 + 30303 + false + 128 + + + + + 32 + + false + + none + + + true + 0xa0d6dec327f522f9c8d342921148a6c42f40a3ce45c1f56baa7bfa752200d9e5 + 1 + AION + + + + + + + + + + database + + true + + + + + FULL + + + leveldb + + true + + + + true + + log + WARN + INFO + ERROR + INFO + INFO + WARN + INFO + INFO + INFO + + + + + true + + aion.sh + + /placeholder/for/aion_root_dir + + + + + + diff --git a/config/avmtestnet/config-seed2.xml b/config/avmtestnet/config-seed2.xml new file mode 100644 index 0000000000..04091d820d --- /dev/null +++ b/config/avmtestnet/config-seed2.xml @@ -0,0 +1,102 @@ + + + aion + 20000000-0000-0000-0000-000000000000 + + + + false + + web3,eth,personal,stratum,ops + + + true + + + + 10E9 + + 100E9 + + false + + + + 31 + + p2p://10000000-0000-0000-0000-000000000000@138.91.123.106:30303 + p2p://20000000-0000-0000-0000-000000000000@23.100.52.181:30303 + p2p://30000000-0000-0000-0000-000000000000@13.91.127.35:30303 + + + 0.0.0.0 + 30303 + false + 128 + + + + + 32 + + false + + none + + + true + 0xa027e3441b6283222e3ce56d4c08b95f9cc2146dfe43ca697833ebdf413cd24a + 1 + AION + + + + + + + + + + database + + true + + + + + FULL + + + leveldb + + true + + + + true + + log + WARN + INFO + ERROR + INFO + INFO + WARN + INFO + INFO + INFO + + + + + true + + aion.sh + + /placeholder/for/aion_root_dir + + + + + + diff --git a/config/avmtestnet/config-seed3.xml b/config/avmtestnet/config-seed3.xml new file mode 100644 index 0000000000..0549264bc7 --- /dev/null +++ b/config/avmtestnet/config-seed3.xml @@ -0,0 +1,102 @@ + + + aion + 30000000-0000-0000-0000-000000000000 + + + + false + + web3,eth,personal,stratum,ops + + + true + + + + 10E9 + + 100E9 + + false + + + + 31 + + p2p://10000000-0000-0000-0000-000000000000@138.91.123.106:30303 + p2p://20000000-0000-0000-0000-000000000000@23.100.52.181:30303 + p2p://30000000-0000-0000-0000-000000000000@13.91.127.35:30303 + + + 0.0.0.0 + 30303 + false + 128 + + + + + 32 + + false + + none + + + true + 0xa0a49f0298ca87ad01e9256cca8d620d74a253f201a5b5760ba7e626779fd258 + 1 + AION + + + + + + + + + + database + + true + + + + + FULL + + + leveldb + + true + + + + true + + log + WARN + INFO + ERROR + INFO + INFO + WARN + INFO + INFO + INFO + + + + + true + + aion.sh + + /placeholder/for/aion_root_dir + + + + + + diff --git a/config/avmtestnet/config.xml b/config/avmtestnet/config.xml index ec4a96dc59..eaba3188ca 100644 --- a/config/avmtestnet/config.xml +++ b/config/avmtestnet/config.xml @@ -21,15 +21,12 @@ false - - true - 31 - p2p://f66d1000-26c8-5ea6-b973-178f246b33b1@138.91.123.106:30303 - p2p://f66d2000-9805-55be-96a3-f170410a2898@23.100.52.181:30303 - p2p://f66d3000-2581-5979-bf8a-6196dbcd29b9@13.91.127.35:30303 + p2p://10000000-0000-0000-0000-000000000000@138.91.123.106:30303 + p2p://20000000-0000-0000-0000-000000000000@23.100.52.181:30303 + p2p://30000000-0000-0000-0000-000000000000@13.91.127.35:30303 0.0.0.0 @@ -89,9 +86,6 @@ INFO INFO - - true - diff --git a/config/avmtestnet/fork.properties b/config/avmtestnet/fork.properties new file mode 100644 index 0000000000..95d3ed563e --- /dev/null +++ b/config/avmtestnet/fork.properties @@ -0,0 +1,2 @@ +fork0.3.2=0 +fork0.4.0=0 diff --git a/config/avmtestnet/genesis.json b/config/avmtestnet/genesis.json index af28dee12f..153ea9314e 100644 --- a/config/avmtestnet/genesis.json +++ b/config/avmtestnet/genesis.json @@ -20,7 +20,7 @@ "difficulty": "0x0004", "coinbase": "0xa0d6dec327f522f9c8d342921148a6c42f40a3ce45c1f56baa7bfa752200d9e5", "timestamp": "1525924800", - "parentHash": "0x10E71BF54DCB8C60766CCB492AB6E3ACEC1AB08D0D5A088FCF533CBFBC801200", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "chainId": "31" } diff --git a/gradle.properties b/gradle.properties index 502ee95f62..1637839f08 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,15 @@ org.gradle.java.home=/usr/lib/jvm/jdk-11.0.1 org.gradle.daemon=true -org.gradle.jvmargs=-Xmx1g -XX:MaxPermSize=4g -XX:ReservedCodeCacheSize=1024m +org.gradle.jvmargs=-Xmx4g -XX:MaxPermSize=4g -XX:ReservedCodeCacheSize=1024m org.gradle.parallel=false # Uncomment to include modGui in build # modGuiPath=aion_gui + +# The following variables are for pushing the aion libs to the maven repo +ossrhUsername= +ossrhPassword= +signing.keyId= +signing.password= +signing.secretKeyRingFile= + diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 0d4a951687..87b738cbd0 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 75b8c7c8c6..44e7c4d1d7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index cccdd3d517..af6708ff22 100755 --- a/gradlew +++ b/gradlew @@ -28,7 +28,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" diff --git a/gradlew.bat b/gradlew.bat index e95643d6a2..0f8d5937c4 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome diff --git a/k8s/Dockerfile b/k8s/Dockerfile deleted file mode 100644 index 80b705472a..0000000000 --- a/k8s/Dockerfile +++ /dev/null @@ -1,36 +0,0 @@ -# builder stage -FROM ubuntu:18.04 - -RUN apt-get update -RUN apt-get --no-install-recommends --yes install \ - wget \ - unzip \ - lsb-release \ - libedit2 \ - libffi6 \ - libtinfo5 \ - bzip2 \ - jq \ - locales - -WORKDIR / - -# Copy latest build -COPY aion.tar.bz2 aion.tar.bz2 - -# Unpack -RUN tar -xvf aion.tar.bz2 - -# Delete source (Reduce image size) -RUN rm -rf aion.tar.bz2 - -WORKDIR /aion - -# Copy config file for the test network -COPY custom custom - -ENV LANG C.UTF-8 -ENV LC_ALL C.UTF-8 - -# Start aion on image start -CMD ["/aion/aion.sh", "-n", "custom"] diff --git a/k8s/Jenkinsfile b/k8s/Jenkinsfile deleted file mode 100644 index 2fe3beddbb..0000000000 --- a/k8s/Jenkinsfile +++ /dev/null @@ -1,72 +0,0 @@ -//configuration -properties([[$class: 'jenkins.model.BuildDiscarderProperty', strategy: - [$class: 'LogRotator', numToKeepStr: '10', artifactNumToKeepStr: '10'] - ]]) - -node { - def app - def appName = 'aion' - def deployName - def endPoint - - stage('Clone repository') { - /* Let's make sure we have the repository cloned to our workspace */ - - checkout scm - } - - stage('Build') { - // Build steps - sh "git submodule init" - - sh "git submodule update --init --recursive" - - sh "./gradlew build pack" - } - - stage('Create Image') { - // Copy to k8s folder to create image - sh "cp pack/aion.tar.bz2 k8s/aion.tar.bz2" - - app = docker.build("${appName}", "k8s") - - } - - stage('Cleanup') { - //Clean up duplicate files required during the build process - sh "rm k8s/aion.tar.bz2" - } - - stage('Push Image') { - - /*Push image with 2 tags (cheap since all layers are duplicated on 2nd push) - */ - - docker.withRegistry('https://aionkuberacr.azurecr.io', 'acr') { - - app.push("${env.BUILD_NUMBER}") - app.push("latest") - } - } - - stage("Deploy Image") { - - // Refresh kubectl (Python can have some issues refreshing) - sh('kubectl get nodes') - - withPythonEnv('python3') { - sh 'pip install -r k8s/requirements.txt' - deployName = sh(script: "python k8s/deploy.py ${env.BUILD_NUMBER}", returnStdout: true) - } - } - - stage("Fetch Deployment Endpoint") { - withPythonEnv('python3') { - endPoint = sh(script: "python k8s/find_endpoint.py " + deployName, returnStdout: true) - } - } - - stage("Run Test") { - sh("echo " + endPoint) - } -} diff --git a/lib/org-aion-avm-api.jar b/lib/org-aion-avm-api.jar new file mode 100644 index 0000000000..ceb3fac703 Binary files /dev/null and b/lib/org-aion-avm-api.jar differ diff --git a/lib/org-aion-avm-core.jar b/lib/org-aion-avm-core.jar index 50b7719757..3a5d37df0f 100644 Binary files a/lib/org-aion-avm-core.jar and b/lib/org-aion-avm-core.jar differ diff --git a/lib/org-aion-avm-rt.jar b/lib/org-aion-avm-rt.jar index 1cfd688427..397b4dcaa8 100644 Binary files a/lib/org-aion-avm-rt.jar and b/lib/org-aion-avm-rt.jar differ diff --git a/lib/org-aion-avm-userlib.jar b/lib/org-aion-avm-userlib.jar new file mode 100644 index 0000000000..1fecce9bec Binary files /dev/null and b/lib/org-aion-avm-userlib.jar differ diff --git a/modAion/build.gradle b/modAion/build.gradle index 69a76e0e69..281188b5fe 100644 --- a/modAion/build.gradle +++ b/modAion/build.gradle @@ -3,22 +3,19 @@ ext.moduleName = 'aion.zero' test.dependsOn copyNativeLibsForModuleTests dependencies { - compile project(':modAionBase') - compile project(':modRlp') - compile project(':modCrypto') + compile project(':aion_vm_api') + compile 'network.aion:util4j:0.4.0' + compile 'network.aion:rlp4j:0.4.0' + compile 'network.aion:crypto4j:0.4.0' + compile project(':modMcf') - //compile files('../lib/libJson.jar') compile 'org.json:json:20180813' compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.4' compile group: 'org.apache.commons', name: 'commons-collections4', version: '4.0' - testCompile project(':modLogger') - testCompile project(':modCrypto') - testCompile project(':modMcf') - testCompile project(':modRlp') + testCompile 'network.aion:log4j:0.4.0' testCompile 'junit:junit:4.12' testCompile 'org.hamcrest:hamcrest-all:1.3' - testCompile group: 'org.apache.commons', name: 'commons-lang3', version: '3.4' } // Skip unit tests when doing build task; unit tests are all mixed up with diff --git a/modAion/src/module-info.java b/modAion/src/module-info.java index e940d257f9..0fcd3a7745 100644 --- a/modAion/src/module-info.java +++ b/modAion/src/module-info.java @@ -1,15 +1,14 @@ module aion.zero { - requires aion.base; + requires aion.vm.api; + requires aion.util; requires aion.rlp; requires aion.crypto; requires aion.mcf; requires slf4j.api; requires org.json; requires commons.lang3; - requires aion.vm.api; exports org.aion.zero.api; - exports org.aion.zero.db; exports org.aion.zero.types; exports org.aion.zero.exceptions; } diff --git a/modAion/src/org/aion/zero/api/BlockConstants.java b/modAion/src/org/aion/zero/api/BlockConstants.java index 1e9fd087c9..b81e5a49e0 100644 --- a/modAion/src/org/aion/zero/api/BlockConstants.java +++ b/modAion/src/org/aion/zero/api/BlockConstants.java @@ -1,10 +1,9 @@ package org.aion.zero.api; import java.math.BigInteger; -import org.aion.base.type.AionAddress; import org.aion.mcf.blockchain.IBlockConstants; import org.aion.mcf.types.AbstractBlockHeader; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; public class BlockConstants implements IBlockConstants { @@ -180,7 +179,7 @@ public long getClockDriftBufferTime() { * @return {@code address} of the sk owning this pair. Also referred to as the owner's address. */ public Address getTokenBridgingAddress() { - return AionAddress.ZERO_ADDRESS(); + return Address.ZERO_ADDRESS(); } @Override diff --git a/modAion/src/org/aion/zero/db/AionRepositoryCache.java b/modAion/src/org/aion/zero/db/AionRepositoryCache.java deleted file mode 100644 index 0c1da6270c..0000000000 --- a/modAion/src/org/aion/zero/db/AionRepositoryCache.java +++ /dev/null @@ -1,254 +0,0 @@ -package org.aion.zero.db; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.aion.base.db.IContractDetails; -import org.aion.base.db.IRepository; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.mcf.core.AccountState; -import org.aion.mcf.db.AbstractRepositoryCache; -import org.aion.mcf.db.ContractDetailsCacheImpl; -import org.aion.mcf.db.IBlockStoreBase; -import org.aion.vm.api.interfaces.Address; - -public class AionRepositoryCache extends AbstractRepositoryCache> { - - public AionRepositoryCache(final IRepository trackedRepository) { - this.repository = trackedRepository; - this.cachedAccounts = new HashMap<>(); - this.cachedDetails = new HashMap<>(); - } - - @Override - public IRepositoryCache startTracking() { - return new AionRepositoryCache(this); - } - - /** - * Flushes its state to other in such a manner that other receives sufficiently deep copies of - * its {@link AccountState} and {@link IContractDetails} objects. - * - * If {@code clearStateAfterFlush == true} then this repository's state will be completely - * cleared after this method returns, otherwise it will retain all of its state. - * - * A "sufficiently deep copy" is an imperfect deep copy (some original object references get - * leaked) but such that for all conceivable use cases these imperfections should go unnoticed. - * This is because doing something like copying the underlying data store makes no sense, both - * repositories should be accessing it, and there are some other cases where objects are defined - * as type {@link Object} and are cast to their expected types and copied, but will not be copied - * if they are not in fact their expected types. This is something to be aware of. Most of the - * imperfection results from the inability to copy - * {@link org.aion.base.db.IByteArrayKeyValueStore} and {@link org.aion.mcf.trie.SecureTrie} - * perfectly or at all (in the case of the former), for the above reasons. - * - * @param other The repository that will consume the state of this repository. - * @param clearStateAfterFlush True if this repository should clear its state after flushing. - */ - public void flushCopiesTo(IRepository other, boolean clearStateAfterFlush) { - fullyWriteLock(); - try { - // determine which accounts should get stored - HashMap cleanedCacheAccounts = new HashMap<>(); - for (Map.Entry entry : cachedAccounts.entrySet()) { - AccountState account = entry.getValue().copy(); - if (account != null && account.isDirty() && account.isEmpty()) { - // ignore contract state for empty accounts at storage - cachedDetails.remove(entry.getKey()); - } else { - cleanedCacheAccounts.put(new AionAddress(entry.getKey().toBytes()), account); - } - } - // determine which contracts should get stored - for (Map.Entry entry : cachedDetails.entrySet()) { - IContractDetails ctd = entry.getValue().copy(); - // TODO: this functionality will be improved with the switch to a - // different ContractDetails implementation - if (ctd != null && ctd instanceof ContractDetailsCacheImpl) { - ContractDetailsCacheImpl contractDetailsCache = (ContractDetailsCacheImpl) ctd; - contractDetailsCache.commit(); - - if (contractDetailsCache.origContract == null - && other.hasContractDetails(entry.getKey())) { - // in forked block the contract account might not exist thus - // it is created without - // origin, but on the main chain details can contain data - // which should be merged - // into a single storage trie so both branches with - // different stateRoots are valid - contractDetailsCache.origContract = - other.getContractDetails(entry.getKey()).copy(); - contractDetailsCache.commit(); - } - } - } - - other.updateBatch(cleanedCacheAccounts, cachedDetails); - if (clearStateAfterFlush) { - cachedAccounts.clear(); - cachedDetails.clear(); - } - } finally { - fullyWriteUnlock(); - } - } - - @Override - public void flushTo(IRepository other, boolean clearStateAfterFlush) { - fullyWriteLock(); - try { - // determine which accounts should get stored - HashMap cleanedCacheAccounts = new HashMap<>(); - for (Map.Entry entry : cachedAccounts.entrySet()) { - AccountState account = entry.getValue(); - if (account != null && account.isDirty() && account.isEmpty()) { - // ignore contract state for empty accounts at storage - cachedDetails.remove(entry.getKey()); - } else { - cleanedCacheAccounts.put(entry.getKey(), entry.getValue()); - } - } - // determine which contracts should get stored - for (Map.Entry entry : cachedDetails.entrySet()) { - IContractDetails ctd = entry.getValue(); - // TODO: this functionality will be improved with the switch to a - // different ContractDetails implementation - if (ctd != null && ctd instanceof ContractDetailsCacheImpl) { - ContractDetailsCacheImpl contractDetailsCache = (ContractDetailsCacheImpl) ctd; - contractDetailsCache.commit(); - - if (contractDetailsCache.origContract == null - && other.hasContractDetails(entry.getKey())) { - // in forked block the contract account might not exist thus - // it is created without - // origin, but on the main chain details can contain data - // which should be merged - // into a single storage trie so both branches with - // different stateRoots are valid - contractDetailsCache.origContract = - other.getContractDetails(entry.getKey()); - contractDetailsCache.commit(); - } - } - } - - other.updateBatch(cleanedCacheAccounts, cachedDetails); - if (clearStateAfterFlush) { - cachedAccounts.clear(); - cachedDetails.clear(); - } - } finally { - fullyWriteUnlock(); - } - } - - /** - * @implNote To maintain intended functionality this method does not call the parent's {@code - * flush()} method. The changes are propagated to the parent through calling the parent's - * {@code updateBatch()} method. - */ - @Override - public void flush() { - flushTo(repository, true); - } - - @Override - public void updateBatch( - Map accounts, final Map details) { - fullyWriteLock(); - try { - - for (Map.Entry accEntry : accounts.entrySet()) { - this.cachedAccounts.put(accEntry.getKey(), accEntry.getValue()); - } - - for (Map.Entry ctdEntry : details.entrySet()) { - ContractDetailsCacheImpl contractDetailsCache = - (ContractDetailsCacheImpl) ctdEntry.getValue().copy(); - if (contractDetailsCache.origContract != null - && !(contractDetailsCache.origContract - instanceof AionContractDetailsImpl)) { - // Copying the parent because contract details changes were pushed to the parent - // in previous method (flush) - cachedDetails.put( - ctdEntry.getKey(), - ContractDetailsCacheImpl.copy( - (ContractDetailsCacheImpl) contractDetailsCache.origContract)); - } else { - // Either no parent or we have Repo's AionContractDetailsImpl, which should be - // flushed through RepoImpl - cachedDetails.put( - ctdEntry.getKey(), ContractDetailsCacheImpl.copy(contractDetailsCache)); - } - } - } finally { - fullyWriteUnlock(); - } - } - - @Override - public boolean isClosed() { - // delegate to the tracked repository - return repository.isClosed(); - } - - @Override - public void close() { - throw new UnsupportedOperationException( - "The tracking cache cannot be closed. \'Close\' should be called on the tracked repository."); - } - - @Override - public void compact() { - throw new UnsupportedOperationException( - "The tracking cache cannot be compacted. \'Compact\' should be called on the tracked repository."); - } - - @Override - public byte[] getRoot() { - throw new UnsupportedOperationException( - "The tracking cache cannot return the root. \'Get root\' should be called on the tracked repository."); - } - - @Override - public void syncToRoot(byte[] root) { - throw new UnsupportedOperationException( - "The tracking cache cannot sync to root. \'Sync to root\' should be called on the tracked repository."); - } - - @Override - public void addTxBatch(Map pendingTx, boolean isPool) { - throw new UnsupportedOperationException( - "addTxBatch should be called on the tracked repository."); - } - - @Override - public void removeTxBatch(Set pendingTx, boolean isPool) { - throw new UnsupportedOperationException( - "removeTxBatch should be called on the tracked repository."); - } - - @Override - public boolean isValidRoot(byte[] root) { - return this.repository.isValidRoot(root); - } - - @Override - public boolean isIndexed(byte[] hash, long level) { - return repository.isIndexed(hash, level); - } - - @Override - public List getPoolTx() { - throw new UnsupportedOperationException( - "getPoolTx should be called on the tracked repository."); - } - - @Override - public List getCacheTx() { - throw new UnsupportedOperationException( - "getCachelTx should be called on the tracked repository."); - } -} diff --git a/modAion/src/org/aion/zero/types/A0BlockHeader.java b/modAion/src/org/aion/zero/types/A0BlockHeader.java index 6dc9da8b3e..4d7c0bf4f2 100644 --- a/modAion/src/org/aion/zero/types/A0BlockHeader.java +++ b/modAion/src/org/aion/zero/types/A0BlockHeader.java @@ -1,22 +1,21 @@ package org.aion.zero.types; -import static org.aion.base.util.ByteUtil.longToBytes; -import static org.aion.base.util.ByteUtil.merge; -import static org.aion.base.util.ByteUtil.oneByteToHexString; -import static org.aion.base.util.ByteUtil.toHexString; import static org.aion.crypto.HashUtil.EMPTY_TRIE_HASH; +import static org.aion.util.bytes.ByteUtil.longToBytes; +import static org.aion.util.bytes.ByteUtil.merge; +import static org.aion.util.bytes.ByteUtil.oneByteToHexString; +import static org.aion.util.bytes.ByteUtil.toHexString; +import static org.aion.util.time.TimeUtils.longToDateTime; import java.math.BigInteger; import java.util.Objects; -import org.aion.base.type.AionAddress; -import org.aion.base.type.IPowBlockHeader; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.Utils; +import org.aion.interfaces.block.PowBlockHeader; +import org.aion.types.Address; import org.aion.crypto.HashUtil; import org.aion.mcf.types.AbstractBlockHeader; import org.aion.rlp.RLP; import org.aion.rlp.RLPList; -import org.aion.vm.api.interfaces.Address; +import org.aion.util.bytes.ByteUtil; import org.aion.zero.exceptions.HeaderStructureException; import org.json.JSONObject; @@ -25,7 +24,7 @@ * * @author Ross */ -public class A0BlockHeader extends AbstractBlockHeader implements IPowBlockHeader { +public class A0BlockHeader extends AbstractBlockHeader implements PowBlockHeader { static final int RPL_BH_VERSION = 0, RPL_BH_NUMBER = 1, @@ -84,10 +83,10 @@ public A0BlockHeader(RLPList rlpHeader) { // CoinBase byte[] data = rlpHeader.get(RPL_BH_COINBASE).getRLPData(); - this.coinbase = - (data == null) - ? AionAddress.EMPTY_ADDRESS() - : AionAddress.wrap(rlpHeader.get(RPL_BH_COINBASE).getRLPData()); + if (data == null || data.length != Address.SIZE) { + throw new IllegalArgumentException("Coinbase can not be null!"); + } + this.coinbase = Address.wrap(data); // StateRoot this.stateRoot = rlpHeader.get(RPL_BH_STATEROOT).getRLPData(); @@ -157,7 +156,11 @@ public A0BlockHeader(A0BlockHeader toCopy) { System.arraycopy(toCopy.getParentHash(), 0, this.parentHash, 0, this.parentHash.length); // Copy elements in coinbase - this.coinbase = toCopy.coinbase.clone(); + if (toCopy.coinbase == null) { + throw new IllegalArgumentException("Coinbase can not be null!"); + } else { + this.coinbase = toCopy.coinbase.clone(); + } // Copy stateroot this.stateRoot = new byte[toCopy.getStateRoot().length]; @@ -216,7 +219,11 @@ public A0BlockHeader( byte[] nonce, byte[] solution) { this.version = version; - this.coinbase = (AionAddress) coinbase; + if (coinbase == null) { + throw new IllegalArgumentException("Coinbase can not be null!"); + } else { + this.coinbase = coinbase; + } this.parentHash = parentHash; this.logsBloom = logsBloom; this.difficulty = difficulty; @@ -372,7 +379,7 @@ private String toStringWithSuffix(final String suffix) { .append(" timestamp=") .append(timestamp) .append(" (") - .append(Utils.longToDateTime(timestamp)) + .append(longToDateTime(timestamp)) .append(")") .append(suffix); toStringBuff.append(" nonce=").append(toHexString(nonce)).append(suffix); @@ -499,7 +506,7 @@ public static A0BlockHeader fromRLP(RLPList rlpHeader, boolean isUnsafe) throws builder.withParentHash(rlpHeader.get(RPL_BH_PARENTHASH).getRLPData()); // Coinbase (miner) - builder.withCoinbase(new AionAddress(rlpHeader.get(RPL_BH_COINBASE).getRLPData())); + builder.withCoinbase(new Address(rlpHeader.get(RPL_BH_COINBASE).getRLPData())); // State root builder.withStateRoot(rlpHeader.get(RPL_BH_STATEROOT).getRLPData()); @@ -559,7 +566,6 @@ public static class Builder { * Some constants for fallbacks, these are not rigorously defined this; * TODO: define these with explanations in the future */ - protected Address EMPTY_ADDRESS = AionAddress.EMPTY_ADDRESS(); protected byte version; protected byte[] parentHash; @@ -864,7 +870,7 @@ public A0BlockHeader build() { this.version = this.version == 0 ? 1 : this.version; this.parentHash = this.parentHash == null ? HashUtil.EMPTY_DATA_HASH : this.parentHash; - this.coinbase = this.coinbase == null ? AionAddress.ZERO_ADDRESS() : this.coinbase; + this.coinbase = this.coinbase == null ? Address.ZERO_ADDRESS() : this.coinbase; this.stateRoot = this.stateRoot == null ? HashUtil.EMPTY_TRIE_HASH : this.stateRoot; this.txTrieRoot = this.txTrieRoot == null ? HashUtil.EMPTY_TRIE_HASH : this.txTrieRoot; this.receiptTrieRoot = diff --git a/modAion/src/org/aion/zero/types/AionInternalTx.java b/modAion/src/org/aion/zero/types/AionInternalTx.java index 8b28b12dc9..cdcc071d9d 100644 --- a/modAion/src/org/aion/zero/types/AionInternalTx.java +++ b/modAion/src/org/aion/zero/types/AionInternalTx.java @@ -1,19 +1,18 @@ package org.aion.zero.types; -import static org.aion.base.util.ByteUtil.toHexString; +import static org.aion.util.conversions.Hex.toHexString; import static org.apache.commons.lang3.ArrayUtils.getLength; import static org.apache.commons.lang3.ArrayUtils.isEmpty; import static org.apache.commons.lang3.ArrayUtils.nullToEmpty; import java.math.BigInteger; import java.nio.ByteBuffer; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; +import org.aion.types.Address; import org.aion.crypto.ECKey; -import org.aion.mcf.vm.types.DataWord; +import org.aion.mcf.vm.types.DataWordImpl; import org.aion.rlp.RLP; import org.aion.rlp.RLPList; -import org.aion.vm.api.interfaces.Address; +import org.aion.util.bytes.ByteUtil; import org.aion.vm.api.interfaces.InternalTransactionInterface; /** aion internal transaction class. */ @@ -53,7 +52,7 @@ public AionInternalTx( } // @TODO: check this functions used by whom - private static byte[] getData(DataWord nrgPrice) { + private static byte[] getData(DataWordImpl nrgPrice) { return (nrgPrice == null) ? ByteUtil.EMPTY_BYTE_ARRAY : nrgPrice.getData(); } @@ -147,8 +146,8 @@ public void rlpParse() { int rlpIdx = 0; this.nonce = transaction.get(rlpIdx++).getRLPData(); this.parentHash = transaction.get(rlpIdx++).getRLPData(); - this.from = AionAddress.wrap(transaction.get(rlpIdx++).getRLPData()); - this.to = AionAddress.wrap(transaction.get(rlpIdx++).getRLPData()); + this.from = Address.wrap(transaction.get(rlpIdx++).getRLPData()); + this.to = Address.wrap(transaction.get(rlpIdx++).getRLPData()); this.value = transaction.get(rlpIdx++).getRLPData(); // TODO: check the order diff --git a/modAion/src/org/aion/zero/types/AionTransaction.java b/modAion/src/org/aion/zero/types/AionTransaction.java index 896c8f307c..c77fb56c46 100644 --- a/modAion/src/org/aion/zero/types/AionTransaction.java +++ b/modAion/src/org/aion/zero/types/AionTransaction.java @@ -1,12 +1,11 @@ package org.aion.zero.types; -import static org.aion.base.util.ByteUtil.ZERO_BYTE_ARRAY; +import static org.aion.util.bytes.ByteUtil.ZERO_BYTE_ARRAY; import java.math.BigInteger; import java.util.Arrays; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.TimeInstant; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.crypto.ECKey.MissingPrivateKeyException; import org.aion.crypto.HashUtil; @@ -14,10 +13,10 @@ import org.aion.crypto.SignatureFac; import org.aion.mcf.types.AbstractTransaction; import org.aion.mcf.vm.Constants; -import org.aion.mcf.vm.types.DataWord; import org.aion.rlp.RLP; import org.aion.rlp.RLPList; -import org.aion.vm.api.interfaces.Address; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.time.TimeInstant; /** Aion transaction class. */ public class AionTransaction extends AbstractTransaction { @@ -135,10 +134,11 @@ public void rlpParse() { this.value = tx.get(RLP_TX_VALUE).getRLPData(); this.data = tx.get(RLP_TX_DATA).getRLPData(); - if (tx.get(RLP_TX_TO).getRLPData() == null) { + byte[] rlpTo = tx.get(RLP_TX_TO).getRLPData(); + if (rlpTo == null || rlpTo.length == 0) { this.to = null; } else { - this.to = AionAddress.wrap(tx.get(RLP_TX_TO).getRLPData()); + this.to = Address.wrap(tx.get(RLP_TX_TO).getRLPData()); } this.timeStamp = tx.get(RLP_TX_TIMESTAMP).getRLPData(); @@ -287,14 +287,14 @@ public Address getContractAddress() { return null; } - org.aion.vm.api.interfaces.Address from = this.getSenderAddress(); + Address from = this.getSenderAddress(); if (from == null) { return null; } try { - return AionAddress.wrap(HashUtil.calcNewAddr(from.toBytes(), this.getNonce())); + return Address.wrap(HashUtil.calcNewAddr(from.toBytes(), this.getNonce())); } catch (Exception e) { LOG.error(e.getMessage(), e); return null; @@ -307,13 +307,7 @@ public boolean isContractCreationTransaction() { rlpParse(); } - // TODO: all this is a temporary solution. - if (this.to == null) { - return true; - } - byte[] toBytes = this.to.toBytes(); - byte[] emptyBytes = AionAddress.EMPTY_ADDRESS().toBytes(); - return Arrays.equals(toBytes, emptyBytes); + return this.to == null; } @Override @@ -332,7 +326,7 @@ public synchronized Address getSenderAddress() { } try { - from = AionAddress.wrap(this.signature.getAddress()); + from = Address.wrap(this.signature.getAddress()); return from; } catch (Exception e) { LOG.error(e.getMessage(), e); @@ -494,7 +488,7 @@ public static AionTransaction create( throws Exception { return new AionTransaction( nonce.toByteArray(), - AionAddress.wrap(to), + Address.wrap(to), amount.toByteArray(), null, nrg, @@ -507,12 +501,12 @@ public void setEncoded(byte[] _encodedData) { parsed = false; } - public DataWord nrgPrice() { - return new DataWord(this.nrgPrice); + public DataWordImpl nrgPrice() { + return new DataWordImpl(this.nrgPrice); } public long nrgLimit() { - return new DataWord(this.nrg).longValue(); + return new DataWordImpl(this.nrg).longValue(); } @Override diff --git a/modAion/src/org/aion/zero/types/AionTxExecSummary.java b/modAion/src/org/aion/zero/types/AionTxExecSummary.java index 7791413846..4eacbf2d41 100644 --- a/modAion/src/org/aion/zero/types/AionTxExecSummary.java +++ b/modAion/src/org/aion/zero/types/AionTxExecSummary.java @@ -4,7 +4,7 @@ import static java.util.Collections.emptyMap; import static java.util.Collections.unmodifiableList; import static java.util.Collections.unmodifiableMap; -import static org.aion.base.util.BIUtil.toBI; +import static org.aion.util.biginteger.BIUtil.toBI; import static org.apache.commons.lang3.ArrayUtils.isEmpty; import static org.apache.commons.lang3.ArrayUtils.isNotEmpty; @@ -16,21 +16,20 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import org.aion.base.type.AionAddress; -import org.aion.base.type.ITxExecSummary; -import org.aion.base.type.ITxReceipt; +import org.aion.interfaces.tx.TxExecSummary; +import org.aion.interfaces.tx.TxReceipt; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; import org.aion.mcf.core.TxTouchedStorage; import org.aion.mcf.db.DetailsDataStore; -import org.aion.mcf.vm.types.DataWord; import org.aion.mcf.vm.types.Log; import org.aion.rlp.RLP; import org.aion.rlp.RLPElement; import org.aion.rlp.RLPList; -import org.aion.vm.api.interfaces.Address; import org.aion.vm.api.interfaces.IExecutionLog; import org.aion.vm.api.interfaces.InternalTransactionInterface; -public class AionTxExecSummary implements ITxExecSummary { +public class AionTxExecSummary implements TxExecSummary { /** * The receipt associated with {@link AionTransaction} that indicates the results of the @@ -42,7 +41,7 @@ public class AionTxExecSummary implements ITxExecSummary { private List
deletedAccounts = emptyList(); private List internalTransactions = emptyList(); - private Map storageDiff = emptyMap(); + private Map storageDiff = emptyMap(); private TxTouchedStorage touchedStorage = new TxTouchedStorage(); private byte[] result; @@ -134,8 +133,8 @@ protected static TxTouchedStorage decodeTouchedStorage(RLPElement encoded) { for (RLPElement entry : (RLPList) encoded) { RLPList asList = (RLPList) entry; - DataWord key = new DataWord(asList.get(0).getRLPData()); - DataWord value = new DataWord(asList.get(1).getRLPData()); + DataWordImpl key = new DataWordImpl(asList.get(0).getRLPData()); + DataWordImpl value = new DataWordImpl(asList.get(1).getRLPData()); byte[] changedBytes = asList.get(2).getRLPData(); boolean changed = isNotEmpty(changedBytes) && RLP.decodeInt(changedBytes, 0) == 1; @@ -163,10 +162,10 @@ private static byte[] encodeLogs(List logs) { return RLP.encodeList(result); } - private static byte[] encodeStorageDiff(Map storageDiff) { + private static byte[] encodeStorageDiff(Map storageDiff) { byte[][] result = new byte[storageDiff.size()][]; int i = 0; - for (Map.Entry entry : storageDiff.entrySet()) { + for (Map.Entry entry : storageDiff.entrySet()) { byte[] key = RLP.encodeElement(entry.getKey().getData()); byte[] value = RLP.encodeElement(entry.getValue().getData()); result[i++] = RLP.encodeList(key, value); @@ -174,11 +173,11 @@ private static byte[] encodeStorageDiff(Map storageDiff) { return RLP.encodeList(result); } - private static Map decodeStorageDiff(RLPList storageDiff) { - Map result = new HashMap<>(); + private static Map decodeStorageDiff(RLPList storageDiff) { + Map result = new HashMap<>(); for (RLPElement entry : storageDiff) { - DataWord key = new DataWord(((RLPList) entry).get(0).getRLPData()); - DataWord value = new DataWord(((RLPList) entry).get(1).getRLPData()); + DataWordImpl key = new DataWordImpl(((RLPList) entry).get(0).getRLPData()); + DataWordImpl value = new DataWordImpl(((RLPList) entry).get(1).getRLPData()); result.put(key, value); } return result; @@ -213,7 +212,7 @@ private static byte[] encodeDeletedAccounts(List
deletedAccounts) { private static List
decodeDeletedAccounts(RLPList deletedAccounts) { List
result = new ArrayList<>(); for (RLPElement deletedAccount : deletedAccounts) { - result.add(AionAddress.wrap(deletedAccount.getRLPData())); + result.add(Address.wrap(deletedAccount.getRLPData())); } return result; } @@ -252,7 +251,7 @@ public List getInternalTransactions() { @Deprecated /* Use getTouchedStorage().getAll() instead */ - public Map getStorageDiff() { + public Map getStorageDiff() { if (!parsed) { rlpParse(); } @@ -341,7 +340,7 @@ public static Builder builderFor(AionTxReceipt receipt) { } @Override - public Object getBuilder(ITxReceipt receipt) { + public Object getBuilder(TxReceipt receipt) { return builderFor((AionTxReceipt) receipt); } @@ -374,13 +373,13 @@ public Builder deletedAccounts(List
list) { return this; } - public Builder storageDiff(Map storageDiff) { + public Builder storageDiff(Map storageDiff) { summary.storageDiff = unmodifiableMap(storageDiff); return this; } public Builder touchedStorage( - Map touched, Map changed) { + Map touched, Map changed) { summary.touchedStorage.addReading(touched); summary.touchedStorage.addWriting(changed); return this; diff --git a/modAion/src/org/aion/zero/types/AionTxReceipt.java b/modAion/src/org/aion/zero/types/AionTxReceipt.java index 5d5a255792..44e981e7cd 100644 --- a/modAion/src/org/aion/zero/types/AionTxReceipt.java +++ b/modAion/src/org/aion/zero/types/AionTxReceipt.java @@ -1,14 +1,12 @@ package org.aion.zero.types; -import static org.aion.base.util.ByteUtil.EMPTY_BYTE_ARRAY; +import static org.aion.util.bytes.ByteUtil.EMPTY_BYTE_ARRAY; import static org.apache.commons.lang3.ArrayUtils.nullToEmpty; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; import java.util.Objects; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.Hex; import org.aion.mcf.types.AbstractTxReceipt; import org.aion.mcf.vm.types.Bloom; import org.aion.mcf.vm.types.Log; @@ -16,6 +14,8 @@ import org.aion.rlp.RLPElement; import org.aion.rlp.RLPItem; import org.aion.rlp.RLPList; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.conversions.Hex; import org.aion.vm.api.interfaces.IExecutionLog; /** aion transaction receipt class. */ diff --git a/modAion/src/org/aion/zero/types/IAionBlock.java b/modAion/src/org/aion/zero/types/IAionBlock.java index cb462db278..43a0d06a45 100644 --- a/modAion/src/org/aion/zero/types/IAionBlock.java +++ b/modAion/src/org/aion/zero/types/IAionBlock.java @@ -2,11 +2,11 @@ import java.math.BigInteger; import java.util.List; -import org.aion.base.type.IBlock; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; +import org.aion.interfaces.block.Block; /** aion block interface. */ -public interface IAionBlock extends IBlock { +public interface IAionBlock extends Block { Address getCoinbase(); diff --git a/modAion/test/org/aion/types/AionTransactionTest.java b/modAion/test/org/aion/types/AionTransactionTest.java index f460721d7f..5176d0579a 100644 --- a/modAion/test/org/aion/types/AionTransactionTest.java +++ b/modAion/test/org/aion/types/AionTransactionTest.java @@ -3,10 +3,8 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; -import org.aion.base.type.AionAddress; import org.aion.crypto.ECKeyFac; -import org.aion.mcf.vm.types.DataWord; -import org.aion.vm.api.interfaces.Address; +import org.aion.mcf.vm.types.DataWordImpl; import org.aion.zero.types.AionTransaction; import org.apache.commons.lang3.RandomUtils; import org.junit.Test; @@ -31,7 +29,7 @@ private void assertTransactionEquals(AionTransaction tx, AionTransaction tx2) { @Test public void testSerializationZero() { byte[] nonce = RandomUtils.nextBytes(16); - Address to = AionAddress.wrap(RandomUtils.nextBytes(32)); + Address to = Address.wrap(RandomUtils.nextBytes(32)); byte[] value = RandomUtils.nextBytes(16); byte[] data = RandomUtils.nextBytes(64); long nrg = 0; @@ -49,7 +47,7 @@ public void testSerializationZero() { @Test public void testClone() { byte[] nonce = RandomUtils.nextBytes(16); - Address to = AionAddress.wrap(RandomUtils.nextBytes(32)); + Address to = Address.wrap(RandomUtils.nextBytes(32)); byte[] value = RandomUtils.nextBytes(16); byte[] data = RandomUtils.nextBytes(64); long nrg = RandomUtils.nextLong(0, Long.MAX_VALUE); @@ -66,16 +64,16 @@ public void testClone() { @Test public void testTransactionCost() { - byte[] nonce = DataWord.ONE.getData(); + byte[] nonce = DataWordImpl.ONE.getData(); byte[] from = RandomUtils.nextBytes(20); byte[] to = RandomUtils.nextBytes(Address.SIZE); - byte[] value = DataWord.ONE.getData(); + byte[] value = DataWordImpl.ONE.getData(); byte[] data = RandomUtils.nextBytes(128); - long nrg = new DataWord(1000L).longValue(); - long nrgPrice = DataWord.ONE.longValue(); + long nrg = new DataWordImpl(1000L).longValue(); + long nrgPrice = DataWordImpl.ONE.longValue(); AionTransaction tx = - new AionTransaction(nonce, AionAddress.wrap(to), value, data, nrg, nrgPrice); + new AionTransaction(nonce, Address.wrap(to), value, data, nrg, nrgPrice); long expected = 21000; for (byte b : data) { @@ -86,13 +84,13 @@ public void testTransactionCost() { @Test public void testTransactionCost2() { - byte[] nonce = DataWord.ONE.getData(); + byte[] nonce = DataWordImpl.ONE.getData(); byte[] from = RandomUtils.nextBytes(Address.SIZE); - Address to = AionAddress.EMPTY_ADDRESS(); - byte[] value = DataWord.ONE.getData(); + Address to = null; + byte[] value = DataWordImpl.ONE.getData(); byte[] data = RandomUtils.nextBytes(128); - long nrg = new DataWord(1000L).longValue(); - long nrgPrice = DataWord.ONE.longValue(); + long nrg = new DataWordImpl(1000L).longValue(); + long nrgPrice = DataWordImpl.ONE.longValue(); AionTransaction tx = new AionTransaction(nonce, to, value, data, nrg, nrgPrice); diff --git a/modAionBase/.classpath b/modAionBase/.classpath deleted file mode 100644 index fb5011632c..0000000000 --- a/modAionBase/.classpath +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/modAionBase/.gitignore b/modAionBase/.gitignore deleted file mode 100644 index e0cee8d414..0000000000 --- a/modAionBase/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.jar -build/ \ No newline at end of file diff --git a/modAionBase/.project b/modAionBase/.project deleted file mode 100644 index 0402dc7daa..0000000000 --- a/modAionBase/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - modAionBase - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/modAionBase/build.gradle b/modAionBase/build.gradle deleted file mode 100644 index 8b11eed86f..0000000000 --- a/modAionBase/build.gradle +++ /dev/null @@ -1,10 +0,0 @@ -ext.moduleName = 'aion.base' - -dependencies { - compile 'com.google.guava:guava:25.1-jre' - compile project(':aion_vm_api') - testCompile 'junit:junit:4.12' - testCompile 'pl.pragmatists:JUnitParams:1.1.1' - testCompile 'org.hamcrest:hamcrest-core:1.3' - testCompile 'com.google.truth:truth:0.42' -} diff --git a/modAionBase/src/module-info.java b/modAionBase/src/module-info.java deleted file mode 100644 index 80fe7831f6..0000000000 --- a/modAionBase/src/module-info.java +++ /dev/null @@ -1,10 +0,0 @@ -module aion.base { - requires aion.vm.api; - exports org.aion.base.timer; - exports org.aion.base.type; - exports org.aion.base.util; - exports org.aion.base.db; - exports org.aion.base.io; - exports org.aion.base.vm; - exports org.aion.base; -} diff --git a/modAionBase/src/org/aion/base/Constant.java b/modAionBase/src/org/aion/base/Constant.java deleted file mode 100644 index 1f71af6a23..0000000000 --- a/modAionBase/src/org/aion/base/Constant.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.aion.base; - -public class Constant { - - public static final int MAX_BLK_SIZE = 2 * 1024 * 1024; -} diff --git a/modAionBase/src/org/aion/base/db/DetailsProvider.java b/modAionBase/src/org/aion/base/db/DetailsProvider.java deleted file mode 100644 index 76d7cdc14f..0000000000 --- a/modAionBase/src/org/aion/base/db/DetailsProvider.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.aion.base.db; - -/** - * Interface for a details provider, provides instances of contract details - * - * @author yao - */ -public interface DetailsProvider { - IContractDetails getDetails(); -} diff --git a/modAionBase/src/org/aion/base/db/Flushable.java b/modAionBase/src/org/aion/base/db/Flushable.java deleted file mode 100644 index 5460582228..0000000000 --- a/modAionBase/src/org/aion/base/db/Flushable.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.aion.base.db; - -public interface Flushable { - void flush(); -} diff --git a/modAionBase/src/org/aion/base/db/IByteArrayKeyValueDatabase.java b/modAionBase/src/org/aion/base/db/IByteArrayKeyValueDatabase.java deleted file mode 100644 index 7acc2eb139..0000000000 --- a/modAionBase/src/org/aion/base/db/IByteArrayKeyValueDatabase.java +++ /dev/null @@ -1,3 +0,0 @@ -package org.aion.base.db; - -public interface IByteArrayKeyValueDatabase extends IByteArrayKeyValueStore, IDatabase {} diff --git a/modAionBase/src/org/aion/base/db/IByteArrayKeyValueStore.java b/modAionBase/src/org/aion/base/db/IByteArrayKeyValueStore.java deleted file mode 100644 index acabb1fab0..0000000000 --- a/modAionBase/src/org/aion/base/db/IByteArrayKeyValueStore.java +++ /dev/null @@ -1,3 +0,0 @@ -package org.aion.base.db; - -public interface IByteArrayKeyValueStore extends IKeyValueStore {} diff --git a/modAionBase/src/org/aion/base/db/IContractDetails.java b/modAionBase/src/org/aion/base/db/IContractDetails.java deleted file mode 100644 index fe21e2ffa4..0000000000 --- a/modAionBase/src/org/aion/base/db/IContractDetails.java +++ /dev/null @@ -1,186 +0,0 @@ -package org.aion.base.db; - -import java.util.Collection; -import java.util.Map; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.vm.api.interfaces.Address; - -public interface IContractDetails { - - /** - * Inserts a key-value pair containing the given key and the given value. - * - * @param key the key to be inserted - * @param value the value to be inserted - */ - void put(ByteArrayWrapper key, ByteArrayWrapper value); - - /** - * Deletes any key-value pair that matches the given key. - * - * @param key the key to be deleted - */ - void delete(ByteArrayWrapper key); - - /** - * Returns the value associated with key. - * - * @implNote Some implementations may handle a non-existent key-value pair differently. - * @param key The key to query. - * @return The associated value or some non-value indicator in the case of no such key-value - * pair. - */ - ByteArrayWrapper get(ByteArrayWrapper key); - - /** - * Returns the code of the address associated with this IContractDetails class. This is for - * addresses that are smart contracts. - * - * @return the code of the associated address. - */ - byte[] getCode(); - - /** - * Returns the code whose hash is codeHash. - * - * @param codeHash The hashed code. - * @return the code. - */ - byte[] getCode(byte[] codeHash); - - /** - * Sets the code of the associated address to code. - * - * @param code The code to set. - */ - void setCode(byte[] code); - - /** - * Returns the storage hash. - * - * @return the storage hash. - */ - byte[] getStorageHash(); - - /** - * Decodes an IContractDetails object from the RLP encoding rlpCode. - * - * @implNote Implementing classes may not necessarily support this method. - * @param rlpCode The encoding to decode. - */ - void decode(byte[] rlpCode); - - /** - * Decodes an IContractDetails object from the RLP encoding rlpCode including the fast check - * optional. - * - * @implNote Implementing classes may not necessarily support this method. - * @param rlpCode The encoding to decode. - * @param fastCheck fast check does the contractDetails needs syncing with external storage - */ - void decode(byte[] rlpCode, boolean fastCheck); - - /** - * Sets the dirty value to dirty. - * - * @param dirty The dirty value. - */ - void setDirty(boolean dirty); - - /** - * Sets the deleted value to deleted. - * - * @param deleted the deleted value. - */ - void setDeleted(boolean deleted); - - /** - * Returns true iff the IContractDetails is dirty. - * - * @return only if this is dirty. - */ - boolean isDirty(); - - /** - * Returns true iff the IContractDetails is deleted. - * - * @return only if this is deleted. - */ - boolean isDeleted(); - - /** - * Returns an rlp encoding of this IContractDetails object. - * - * @implNote Implementing classes may not necessarily support this method. - * @return an rlp encoding of this. - */ - byte[] getEncoded(); - - /** - * Returns a mapping of all the key-value pairs that have keys in the given collection keys. - * - * @param keys the keys to query for - * @return the associated mappings - */ - Map getStorage(Collection keys); - - /** - * Sets the storage to contain the specified key-value mappings. - * - * @param storage the specified mappings - * @apiNote Used for testing. - * @implNote A {@code null} value is interpreted as deletion. - */ - void setStorage(Map storage); - - /** - * Get the address associated with this IContractDetails. - * - * @return the associated address. - */ - Address getAddress(); - - /** - * Sets the associated address to address. - * - * @param address The address to set. - */ - void setAddress(Address address); - - /** - * Returns a string representation of this IContractDetails. - * - * @return a string representation. - */ - String toString(); - - /** Syncs the storage trie. */ - void syncStorage(); - - /** - * Returns an IContractDetails object pertaining to a specific point in time given by the root - * hash hash. - * - * @implNote Implementing classes may not necessarily support this method. - * @param hash The root hash to search for. - * @return the specified IContractDetails. - */ - IContractDetails getSnapshotTo(byte[] hash); - - /** - * Sets the data source to dataSource. - * - * @implNote Implementing classes may not necessarily support this method. - * @param dataSource The new dataSource. - */ - void setDataSource(IByteArrayKeyValueStore dataSource); - - /** - * Returns a sufficiently deep copy of this object. It is up to all implementations of this - * method to declare which original object references are in fact leaked by this copy, if any, - * and to provide justification of why, despite this, the copy is nonetheless sufficiently deep. - * - * @return A copy of this object. - */ - IContractDetails copy(); -} diff --git a/modAionBase/src/org/aion/base/db/IDatabase.java b/modAionBase/src/org/aion/base/db/IDatabase.java deleted file mode 100644 index c5d545ef5d..0000000000 --- a/modAionBase/src/org/aion/base/db/IDatabase.java +++ /dev/null @@ -1,144 +0,0 @@ -package org.aion.base.db; - -import java.util.Optional; - -/** - * Interface for database connection functionality, to be implemented by all database - * implementations. - * - * @author Alexandra Roatis - * @implNote Note on how a DB is defined and discussed in this driver: a DB is simply a persistent - * key value store with a unique filesystem path (ie. implying that two stores should not exist - * within the same file-system address. - * @apiNote For the underlying DB connection, if [isClosed() == true], then all function calls which - * are documented to throw RuntimeException, must in fact throw a RuntimeException. - */ -public interface IDatabase { - - // Actions that change the state of the database - // ------------------------------------------------------------------- - - /** - * Opens and creates the database connection. If database is already open, returns true. - * - *

Implements the "CREATE_IF_NOT_EXISTS" functionality by default (non-configurable in this - * spec). - * - *

DB file(s) on disk policy: all DBs shall be enclosed in a directory, regardless of the - * underlying implementation being a single file store or a multi-file store, to make DB cleanup - * easiers - * - *

Does NOT throw an exception on failure, simply returns false and logs reason for failure. - * Rationale: don't need complex connection open policy in the application at the moment - * - * @return True if successful, false if not. - */ - boolean open(); - - /** - * Closes private "connection" to DB, relinquishing any underlying resources. Calling {@link - * #close()} on a closed DB has no effect. - * - *

NOTE: All interface calls on an instance for which [isClosed() == true] will throw a - * Runtime Exception - */ - void close(); - - /** - * Makes all changes made since the previous commit/rollback permanent and releases any database - * locks currently held by this Connection object. This method should be used only when - * auto-commit mode has been disabled. - * - * @return {@code true} if the changes were successfully committed to storage, {@code false} if - * the changes could not be committed to storage - * @throws RuntimeException if the data store is closed - * @implNote Returns {@code true} with no other effect when auto-commit is already enabled. - */ - boolean commit(); - - /** Reduce the size of the database when possible. */ - void compact(); - - /** Drop database. Removes all data from source. */ - void drop(); - - // Get information about the database state - // ------------------------------------------------------------------------ - - /** - * Returns the name of the DB - * - * @return name of DB provided at initialization. Optional.empty() if none provided - */ - Optional getName(); - - /** - * Returns DB directory where all DB files are stored. DBFilePath configuration delegated to - * driver instantiating a IDatabase - * - * @return path (as String) to top-level DB directory containing a multi-file or single file - * persistent DB (assuming all driver implementations create paths on filesystem such that - * all DB files, whether single file or a multi-file implementation) - *

Returns empty optional for non-persistent DB. - */ - Optional getPath(); - - /** - * Returns a flag that indicates if the database is open. - * - * @return {@code true} if open, {@code false} otherwise - */ - boolean isOpen(); - - /** - * Returns a flag that indicates if the database is closed. - * - * @return {@code true} if closed, {@code false} otherwise - */ - boolean isClosed(); - - /** - * Returns a flag that indicates if the database is currently locked for reading or writing. - * - * @return {@code true} if locked, {@code false} otherwise - */ - boolean isLocked(); - - /** - * @return {@code true} if changes are automatically committed to storage, {@code false} - * otherwise - */ - boolean isAutoCommitEnabled(); - - /** - * Indicates the method of persistence this database uses. Whether it's written to disk, only - * held in memory, or stored inside a database engine's proprietary format. - * - * @return The method of persistence this database uses. - */ - PersistenceMethod getPersistenceMethod(); - - /** - * Used to validate if the DB file(s) has been created on disk. Can be used any time during this - * object's lifecycle (before or after open() call). Typical use case: used before open() to - * check if the open will need to create new files on the filesystem - * - *

Implementation note: can't just try to open a connection to see if it's successful since a - * second open() on the same db filesystem resource will fail and the whole point of this - * function is to reliably determine (almost like a static function) if the DB file with the - * configured name and path have been created on disk - * - * @return {@code true} if DB file(s) exists at path configured on construction, {@code false} - * otherwise - */ - boolean isCreatedOnDisk(); - - /** - * Returns size of the database in bytes. - * - * @return A {@code long} value representing the approximate size of DB. Returns -1 if the size - * cannot be computed or if the database is not persistent. - * @throws RuntimeException if the data store is closed - */ - long approximateSize(); -} diff --git a/modAionBase/src/org/aion/base/db/IKeyValueStore.java b/modAionBase/src/org/aion/base/db/IKeyValueStore.java deleted file mode 100644 index 4ef37d9e15..0000000000 --- a/modAionBase/src/org/aion/base/db/IKeyValueStore.java +++ /dev/null @@ -1,159 +0,0 @@ -package org.aion.base.db; - -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.Optional; - -/** - * Functionality for a key-value store allowing itemized updates. - * - * @param the data type of the keys - * @param the data type of the values - * @author Alexandra Roatis - * @implNote For the underlying database connection, if {@code isClosed() == true}, then all - * function calls which require the database connection will throw a {@link RuntimeException}, - * as documented by this interface. - */ -public interface IKeyValueStore extends AutoCloseable { - - /** - * Returns {@code true} if this data store contains no elements. - * - * @return {@code true} if this data store contains no elements - * @throws RuntimeException if the data store is closed - */ - boolean isEmpty(); - - /** - * Returns an {@link Iterator} over the set of keys stored in the database at the time when the - * keys were requested. A snapshot can be used to ensure that the entries do not change while - * iterating through the keys. - * - * @return an iterator over the set of stored keys - * @throws RuntimeException if the data store is closed - * @apiNote Returns an empty iterator if the database keys could not be retrieved. - */ - Iterator keys(); - - /** - * Retrieves a value from the data store, wrapped in an {@link Optional} object. It is fulfilled - * if a value was retrieved from the data store, otherwise the optional is empty. - * - * @param key the key for the new entry - * @throws RuntimeException if the data store is closed - * @throws IllegalArgumentException if the key is {@code null} - */ - Optional get(KeyT key); - - /** - * Stores or updates a value at the corresponding key. Makes no guarantees about when the value - * is actually inserted into the underlying data store. - * - * @param key the key for the new entry - * @param value the value for the new entry - * @throws RuntimeException if the underlying data store is closed - * @throws IllegalArgumentException if either the key or the value is {@code null} - * @implNote The choice of when to push the changes to the data store is left up to the - * implementation. - * @apiNote Put must have the following properties: - *

    - *
  1. Creates a new entry in the cache, if the key-value pair does not exist in the cache - * or underlying data store. - *
  2. Updates the entry in the cache when the key-value pair already exists. - *
- * To delete a key one must explicitly call {@link #delete(Object)}. - */ - void put(KeyT key, ValueT value); - - /** - * Deletes a key from the data store. Makes no guarantees about when the value is actually - * deleted from the underlying data store. - * - * @param key the key of the entry to be deleted - * @throws RuntimeException if the underlying data store is closed - * @throws IllegalArgumentException if the key is {@code null} - * @implNote The choice of when to push the changes to the data store is left up to the - * implementation. - */ - void delete(KeyT key); - - /** - * Stores or updates a value at the corresponding key. The changes are cached until {@link - * #commitBatch()} is called. - * - *

May delegate to calling {@link #put(Object, Object)} if batch functionality fails or is - * not implemented. - * - * @param key the key for the new entry - * @param value the value for the new entry - * @throws RuntimeException if the underlying data store is closed - * @throws IllegalArgumentException if either the key or the value is {@code null} - * @implNote The choice of when to push the changes to the data store is left up to the - * implementation. - * @apiNote Put must have the following properties: - *

    - *
  1. Creates a new entry in the cache, if the key-value pair does not exist in the cache - * or underlying data store. - *
  2. Updates the entry in the cache when the key-value pair already exists. - *
- * To delete a key one must explicitly call {@link #deleteInBatch(Object)}. - */ - void putToBatch(KeyT key, ValueT value); - - /** - * Deletes a key from the data store. The changes are cached until {@link #commitBatch()} is - * called. - * - *

May delegate to calling {@link #delete(Object)} if batch functionality fails or is not - * implemented. - * - * @param key the key of the entry to be deleted - * @throws RuntimeException if the underlying data store is closed - * @throws IllegalArgumentException if the key is {@code null} - * @implNote The choice of when to push the changes to the data store is left up to the - * implementation. - */ - void deleteInBatch(KeyT key); - - /** - * Pushes updates made using {@link #putToBatch(Object, Object)} and {@link - * #deleteInBatch(Object)} to the underlying data source. - */ - void commitBatch(); - - /** - * Puts or updates the data store with the given key-value pairs, as follows: - * - *

    - *
  • if the key is present in the data store, the stored value is overwritten - *
  • if the key is not present in the data store, the new key-value pair is - * stored - *
- * - * @param input a {@link Map} of key-value pairs to be updated in the database - * @throws RuntimeException if the data store is closed - * @throws IllegalArgumentException if the map contains a {@code null} key - * @apiNote To delete a set of keys one must explicitly call {@link #deleteBatch(Collection)}. - */ - void putBatch(Map input); - - /** - * Deletes the given keys from the data store. Makes no guarantees about when the entries are - * actually deleted from the underlying data store. - * - * @param keys a {@link Collection} of keys to be deleted form storage - * @throws RuntimeException if the data store is closed - * @throws IllegalArgumentException if the collection contains a {@code null} key - */ - void deleteBatch(Collection keys); - - /** - * Checks that the data source connection is open. Throws a {@link RuntimeException} if the data - * source connection is closed. - * - * @implNote Always do this check after acquiring a lock on the class/data. Otherwise it might - * produce inconsistent results due to lack of synchronization. - */ - void check(); -} diff --git a/modAionBase/src/org/aion/base/db/IPruneConfig.java b/modAionBase/src/org/aion/base/db/IPruneConfig.java deleted file mode 100644 index 3b93b1fb50..0000000000 --- a/modAionBase/src/org/aion/base/db/IPruneConfig.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.aion.base.db; - -/** - * Interface for pruning configuration parameters. - * - * @author Alexandra Roatis - */ -public interface IPruneConfig { - - /** - * Indicates if pruning should be enabled or disabled. - * - * @return {@code true} when pruning enabled, {@code false} when pruning disabled. - */ - boolean isEnabled(); - - /** - * Indicates if archiving should be enabled or disabled. - * - * @return {@code true} when archiving enabled, {@code false} when archiving disabled. - */ - boolean isArchived(); - - /** - * @return the number of topmost blocks for which the full data should be maintained on disk. - */ - int getCurrentCount(); - - /** - * Gets the rate at which blocks should be archived (for which the full data should be - * maintained on disk). Blocks that are exact multiples of the returned value should be - * persisted on disk, regardless of other pruning. - * - * @return integer value representing the archive rate - */ - int getArchiveRate(); -} diff --git a/modAionBase/src/org/aion/base/db/IRepository.java b/modAionBase/src/org/aion/base/db/IRepository.java deleted file mode 100644 index 98d806910c..0000000000 --- a/modAionBase/src/org/aion/base/db/IRepository.java +++ /dev/null @@ -1,99 +0,0 @@ -package org.aion.base.db; - -import java.util.Map; -import java.util.Set; -import org.aion.vm.api.interfaces.Address; - -/** - * Database-like functionality. - * - * @apiNote Allows only batch operations on data. - */ -public interface IRepository extends IRepositoryQuery { - - /** - * Creates a tracker repository for caching future changes. - * - * @return the new tracker repository - */ - IRepositoryCache startTracking(); - - /** Commits all the changes made in this repository to the database storage. */ - void flush(); - - /** - * Performs batch updates on the data. - * - * @param accountStates cached account states - * @param contractDetails cached contract details - */ - void updateBatch( - Map accountStates, Map contractDetails); - - /** Reverts all the changes performed by this repository. */ - void rollback(); - - /** - * Checks if the current repository has an open connection to the database. - * - * @return {@code true} if the database connection is open, {@code false} otherwise - */ - boolean isClosed(); - - /** Closes the connection to the database. */ - void close(); - - /** Reduce the size of the database when possible. */ - void compact(); - - // navigate through snapshots - // -------------------------------------------------------------------------------------- - - /** - * Used to check for corruption in the state database. - * - * @param root a world state trie root - * @return {@code true} if the root is valid, {@code false} otherwise - */ - boolean isValidRoot(byte[] root); - - /** - * Used to check for corruption in the index database. - * - * @param hash a block hash - * @return {@code true} if the block hash has a corresponding index, {@code false} otherwise - */ - boolean isIndexed(byte[] hash, long level); - - byte[] getRoot(); - - /** - * Return to one of the previous snapshots by moving the root. - * - * @param root - new root - */ - void syncToRoot(byte[] root); - - /** - * TODO: differentiate between the sync to root and snapshot functionality - * - * @param root - * @return - */ - IRepository getSnapshotTo(byte[] root); - - /** - * @return {@code true} if the repository is a snapshot (with limited functionality), {@code - * false} otherwise - */ - boolean isSnapshot(); - - // TODO: perhaps remove - BSB getBlockStore(); - - /** Performs batch transactions add. */ - void addTxBatch(Map pendingTx, boolean isPool); - - /** Performs batch transactions remove. */ - void removeTxBatch(Set pendingTx, boolean isPool); -} diff --git a/modAionBase/src/org/aion/base/db/IRepositoryCache.java b/modAionBase/src/org/aion/base/db/IRepositoryCache.java deleted file mode 100644 index ce8cc4f0c8..0000000000 --- a/modAionBase/src/org/aion/base/db/IRepositoryCache.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.aion.base.db; - -import java.math.BigInteger; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.vm.api.interfaces.Address; - -/** - * Repository interface for individual account additions and updates. - * - * @implNote Tracking a repository should be done through implementing this interface. - */ -public interface IRepositoryCache extends IRepository { - - // setters relating to user accounts - // ------------------------------------------------------------------------------- - - /** - * Creates a new account state in the database or cache. - * - * @param address the address of the account to be created - * @return a {@link AS} object storing the newly created account state - */ - AS createAccount(Address address); - - /** - * Deletes the account from the cache and database. - * - * @param address the address of the account to be deleted - * @implNote This method only marks the account for deletion. Removing the account from the - * database is done at the next flush operation. - */ - void deleteAccount(Address address); - - /** - * Increases by one the account associated with the given address. - * - * @param address the address of the account of interest - * @return the updated value of the nonce - */ - BigInteger incrementNonce(Address address); - - /** - * Sets to a specific value the nonce of the account associated with the given address. - * - * @param address the address of the account of interest - * @return the updated nonce value for the account - */ - BigInteger setNonce(Address address, BigInteger nonce); - - /** - * Adds the given value to the balance of the account associated with the given address. - * - * @param address the address of the account of interest - * @param value to be added to the balance - * @return the updated balance for the account - */ - BigInteger addBalance(Address address, BigInteger value); - - // setters relating to contracts - // ----------------------------------------------------------------------------------- - - /** - * Stores code associated with an account. - * - * @param address the address of the account of interest - * @param code the code that will be associated with this account - * @implNote Calling this method on already initialized code should leave the account and - * contract state unaltered. - */ - void saveCode(Address address, byte[] code); - - // setters relating to storage - // ------------------------------------------------------------------------------------- - - /** - * Store the given data at the given key in the account associated with the given address. - * - * @param address the address of the account of interest - * @param key the key at which the data will be stored - * @param value the data to be stored - */ - void addStorageRow(Address address, ByteArrayWrapper key, ByteArrayWrapper value); - - /** - * Remove the given storage key from the account associated with the given address. - * - * @param address the address of the account of interest - * @param key the key for which the data will be removed - */ - void removeStorageRow(Address address, ByteArrayWrapper key); - - void flushTo(IRepository repo, boolean clearStateAfterFlush); -} diff --git a/modAionBase/src/org/aion/base/db/IRepositoryConfig.java b/modAionBase/src/org/aion/base/db/IRepositoryConfig.java deleted file mode 100644 index 2a6566a31c..0000000000 --- a/modAionBase/src/org/aion/base/db/IRepositoryConfig.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.aion.base.db; - -import java.util.Properties; - -/** - * Represents a configuration interface accepted that should be accepted by the repository to - * implement necessary configs - * - * @author yao - */ -public interface IRepositoryConfig { - - /** @return absolute path to the DB folder containing files */ - String getDbPath(); - - IPruneConfig getPruneConfig(); - - IContractDetails contractDetailsImpl(); - - Properties getDatabaseConfig(String db_name); -} diff --git a/modAionBase/src/org/aion/base/db/IRepositoryQuery.java b/modAionBase/src/org/aion/base/db/IRepositoryQuery.java deleted file mode 100644 index c1757de740..0000000000 --- a/modAionBase/src/org/aion/base/db/IRepositoryQuery.java +++ /dev/null @@ -1,150 +0,0 @@ -package org.aion.base.db; - -import java.math.BigInteger; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.vm.api.interfaces.Address; - -/** Repository interface for information retrieval. */ -public interface IRepositoryQuery { - - // getters relating to user accounts - // ------------------------------------------------------------------------------- - - /** - * Checks if the database contains an account state associated with the given address. - * - * @param address the address of the account of interest - * @return {@code true} if the account exists, {@code false} otherwise - */ - boolean hasAccountState(Address address); - - /** - * Loads the account (and contract) state associated with the given address into the given hash - * maps. - * - * @param address the address of the account of interest - * @param accounts a map representing a cache of {@link AS} where the account state will be - * loaded - * @param details a map representing a cache of {@link IContractDetails>} where the contract - * details will be loaded - */ - void loadAccountState( - Address address, Map accounts, Map details); - - /** - * Retrieves the current state of the account associated with the given address. - * - * @param address the address of the account of interest - * @return a {@link AS} object representing the account state as is stored in the database or - * cache - */ - AS getAccountState(Address address); - - /** - * Retrieves the current balance of the account associated with the given address. - * - * @param address the address of the account of interest - * @return a {@link BigInteger} value representing the current account balance - */ - BigInteger getBalance(Address address); - - /** - * Retrieves the current nonce of the account associated with the given address. - * - * @param address the address of the account of interest - * @return a {@link BigInteger} value representing the current account nonce - */ - BigInteger getNonce(Address address); - - // getters relating to contracts - // ----------------------------------------------------------------------------------- - - /** - * Checks if the database contains contract details associated with the given address. - * - * @param addr the address of the account of interest - * @return {@code true} if there are contract details associated with the account, {@code false} - * otherwise - */ - boolean hasContractDetails(Address addr); - - /** - * Retrieves the contract details of the account associated with the given address. - * - * @param addr the address of the account of interest - * @return a {@link IContractDetails} object representing the contract details - * as are stored in the database or cache - */ - IContractDetails getContractDetails(Address addr); - - /** - * Retrieves the code for the account associated with the given address. - * - * @param address the address of the account of interest - * @return the code associated to the account in {@code byte} array format - */ - byte[] getCode(Address address); - - // getters relating to storage - // ------------------------------------------------------------------------------------- - - /** - * Retrieves the entries for the specified key values stored at the account associated with the - * given address. - * - * @param address the address of the account of interest - * @param keys the collection of keys of interest (which may be {@code null}) - * @return the storage entries for the specified keys, or the full storage if the key collection - * is {@code null} - * @apiNote When called with a null key collection, the method retrieves all the storage keys. - */ - Map getStorage( - Address address, Collection keys); - - // /** - // * Retrieves the storage size the account associated with the given address. - // * - // * @param address - // * the address of the account of interest - // * @return the number of storage entries for the given account - // */ - // int getStorageSize(Address address); - // - // /** - // * Retrieves all the storage keys for the account associated with the given - // * address. - // * - // * @param address - // * the address of the account of interest - // * @return the set of storage keys, or an empty set if the given account - // * address does not exist - // */ - // Set getStorageKeys(Address address); - - /** - * Retrieves the stored value for the specified key stored at the account associated with the - * given address. - * - * @param address the address of the account of interest - * @param key the key of interest - * @return a {@link ByteArrayWrapper} representing the data associated with the given key - */ - ByteArrayWrapper getStorageValue(Address address, ByteArrayWrapper key); - - /** - * Retrieves the stored transactions for recovering pool tx. - * - * @return the list of transactions encoded bytes. - */ - List getPoolTx(); - - /** - * Retrieves the stored transactions for recovering caching tx. - * - * @return the list of transactions encoded bytes. - */ - List getCacheTx(); -} diff --git a/modAionBase/src/org/aion/base/db/PersistenceMethod.java b/modAionBase/src/org/aion/base/db/PersistenceMethod.java deleted file mode 100644 index 9c0f2cefe8..0000000000 --- a/modAionBase/src/org/aion/base/db/PersistenceMethod.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.aion.base.db; - -public enum PersistenceMethod { - UNKNOWN, - - // The data isn't actually persisted but just stored temporarily in memory - IN_MEMORY, - - // The data is stored in a file directory - FILE_BASED, - - // The data is stored in the proprietary format of a database management system - DBMS -} diff --git a/modAionBase/src/org/aion/base/timer/ITimer.java b/modAionBase/src/org/aion/base/timer/ITimer.java deleted file mode 100644 index 400864c9c9..0000000000 --- a/modAionBase/src/org/aion/base/timer/ITimer.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.aion.base.timer; - -/** - * Interface so we can create a mock - * - * @author yao - */ -public interface ITimer { - void shutdown(); - - void sched(TimerTask timer); -} diff --git a/modAionBase/src/org/aion/base/timer/PoisonPillTask.java b/modAionBase/src/org/aion/base/timer/PoisonPillTask.java deleted file mode 100644 index 8415a1a14e..0000000000 --- a/modAionBase/src/org/aion/base/timer/PoisonPillTask.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.aion.base.timer; - -/** - * Used to destroy the timers - * - * @author yao - */ -public class PoisonPillTask extends TimerTask { - - public PoisonPillTask() { - super(0L); - } -} diff --git a/modAionBase/src/org/aion/base/timer/StackTimer.java b/modAionBase/src/org/aion/base/timer/StackTimer.java deleted file mode 100644 index 506e7f1e7d..0000000000 --- a/modAionBase/src/org/aion/base/timer/StackTimer.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.aion.base.timer; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; - -/** - * Modified to use caching thread pools instead - * - *

Note: cannot be shared between threads - * - * @author yao - */ -public class StackTimer implements ITimer { - - public static int NANO_INTERVAL = 10; - - // private final TimerThread thread = new TimerThread(stack); - private final StackTimerRunnable timerRunnable; - - /** - * We won't shutdown the thread pool until the very end, (when we need to shutdown the program) - */ - private static final ExecutorService timers = - Executors.newCachedThreadPool( - new ThreadFactory() { - - @Override - public Thread newThread(Runnable arg0) { - Thread thread = new Thread(arg0, "StackTimer"); - thread.setPriority(Thread.MAX_PRIORITY); - return thread; - } - }); - - /** Called upon program exit, to shutdown the thread pool */ - public static void shutdownPool() { - timers.shutdown(); - } - - public StackTimer() { - timerRunnable = new StackTimerRunnable(); - timers.execute(timerRunnable); - } - - @Override - public void sched(TimerTask task) { - if (task == null) { - throw new RuntimeException("task cannot be null"); - } - - if (!(task.getTimeout() > 0)) { - throw new RuntimeException("timeout has to be > 0"); - } - task.start(); - timerRunnable.submit(task); - } - - @Override - public void shutdown() { - timerRunnable.shutdown(); - } - - public boolean completed() { - return timerRunnable.done(); - } - - protected StackTimerRunnable getTimerRunnable() { - return this.timerRunnable; - } -} diff --git a/modAionBase/src/org/aion/base/timer/StackTimerRunnable.java b/modAionBase/src/org/aion/base/timer/StackTimerRunnable.java deleted file mode 100644 index 047e497c4e..0000000000 --- a/modAionBase/src/org/aion/base/timer/StackTimerRunnable.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.aion.base.timer; - -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Deque; -import java.util.List; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; - -/** - * Runnable for VMTimer, allowing us to leverage CachedThreadPools for fast thread allocation - * - * @author yao - */ -public class StackTimerRunnable implements Runnable { - private final Deque stack = new ArrayDeque<>(); - private final BlockingQueue inputQueue = new LinkedBlockingQueue<>(); - - private volatile boolean done; - - public StackTimerRunnable() {} - - public void submit(TimerTask task) { - synchronized (inputQueue) { - this.inputQueue.add(task); - } - } - - @Override - public void run() { - try { - loop(); - } finally { - this.stack.clear(); - } - this.done = true; - } - - public void shutdown() { - inputQueue.add(new PoisonPillTask()); - } - - private void loop() { - MAIN_LOOP: - while (!Thread.currentThread().isInterrupted()) { - List tasks = new ArrayList<>(); - if (stack.isEmpty() && inputQueue.isEmpty()) { - try { - // works under the assumption that task should never be null - // please do not feed it nulls - tasks.add(inputQueue.take()); - } catch (InterruptedException e) { - break MAIN_LOOP; // if any interrupted exceptions, shut down - // the timer - } - } - - /** - * The stack might not be empty, in this case, we need to check for any new items that - * may have gathered inside our queue - */ - synchronized (inputQueue) { - if (!inputQueue.isEmpty()) { - inputQueue.drainTo(tasks); - } - } - - // at this point we should have all tasks, check if any of them are - // poison pills - for (int i = 0; i < tasks.size(); i++) { - if (tasks.get(i) instanceof PoisonPillTask) { - break MAIN_LOOP; - } - } - - /** - * At this point, stack may be empty, but we should always have a task we perform the - * following operations at this point: - * - *

1) If stack is not empty, check for done() at the top of the stack, and iterate - * down the stack until we reach a task that is not done - * - *

2) We check for timeouts on any task that is not done, working under the - * assumption of a stack model, tasks that are not yet done should not have any tasks - * that are done below them in the stack - * - *

3) Remove any tasks (iteratively) that are timed out - * - *

4) Insert any new tasks for the queue - */ - if (!stack.isEmpty()) { - // check tasks that are done first - { - TimerTask peeked = stack.peek(); - while (peeked != null && peeked.getDone()) { - stack.pop(); - peeked = stack.peek(); - } - } - - // check tasks that are timed out - { - TimerTask peeked = stack.peek(); - long currentTime = System.nanoTime(); - while (peeked != null && (currentTime > peeked.getEndTime())) { - peeked.setTimeOut(); - stack.pop(); - peeked = stack.peek(); - } - } - } - - /** Finally add the new tasks */ - for (int i = 0; i < tasks.size(); i++) { - stack.push(tasks.get(i)); - } - } - } - - /** - * Checks if this runnable is done - * - * @return - */ - public boolean done() { - return this.done; - } -} diff --git a/modAionBase/src/org/aion/base/timer/TimerDummy.java b/modAionBase/src/org/aion/base/timer/TimerDummy.java deleted file mode 100644 index dc41dff7c2..0000000000 --- a/modAionBase/src/org/aion/base/timer/TimerDummy.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.aion.base.timer; - -/** - * Dummy timer for call methods (since I don't have a good way to allocate resources for them yet) - * - * @author yao - */ -public class TimerDummy implements ITimer { - - @Override - public void shutdown() { - // TODO Auto-generated method stub - - } - - @Override - public void sched(TimerTask timer) { - // TODO Auto-generated method stub - - } -} diff --git a/modAionBase/src/org/aion/base/timer/TimerTask.java b/modAionBase/src/org/aion/base/timer/TimerTask.java deleted file mode 100644 index 113903ad4c..0000000000 --- a/modAionBase/src/org/aion/base/timer/TimerTask.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.aion.base.timer; - -/** @author jin */ -public class TimerTask { - - public TimerTask(long timeOut) { - this.timeOut = timeOut; - } - - public Object lock = new Object(); - - private long timeOut; - private long startTime; - private long timeoutAt; - private long endTime; - - private boolean isTimeOut; - private boolean isDone; - - public long getEndTime() { - return this.endTime; - } - - public long getTimeout() { - return this.timeOut; - } - - public void start() { - this.startTime = System.nanoTime(); - this.endTime = this.startTime + this.timeOut; - } - - public long getRemaining() { - return Math.max(getEndTime() - System.nanoTime(), 1L); - } - - public boolean isTimeOut() { - return isTimeOut; - } - - public synchronized void setDone() { - this.isDone = true; - } - - public boolean getDone() { - return this.isDone; - } - - protected synchronized void setTimeOut() { - if (isTimeOut == false) { - isTimeOut = true; - timeoutAt = System.nanoTime(); - } - } - - public long getTimeoutDuration() { - return this.timeoutAt - this.startTime; - } -} diff --git a/modAionBase/src/org/aion/base/type/AionAddress.java b/modAionBase/src/org/aion/base/type/AionAddress.java deleted file mode 100644 index 18fdf5c570..0000000000 --- a/modAionBase/src/org/aion/base/type/AionAddress.java +++ /dev/null @@ -1,149 +0,0 @@ -package org.aion.base.type; - -import java.util.Arrays; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.Bytesable; -import org.aion.vm.api.interfaces.Address; - -/** - * The address class is a byte array wrapper represent fixed-32bytes array for the kernel account - * (public key) has more security compare with 20bytes address blockchain system. - * - * @author jay - */ -public final class AionAddress - implements org.aion.vm.api.interfaces.Address, - Comparable, - Bytesable, - Cloneable { - private static final AionAddress zeroAddr = AionAddress.wrap(new byte[SIZE]); - private static final AionAddress emptyAddr = AionAddress.wrap(new byte[0]); - - private byte[] address; - private int hashCode = 0; - - public AionAddress(final byte[] in) { - - if (in == null) { - throw new IllegalArgumentException("Null input!"); - } - - if (in.length != SIZE && in.length != 0) { - throw new IllegalArgumentException(); - } - - setupData(in); - } - - public AionAddress(final ByteArrayWrapper in) { - - if (in == null) { - throw new IllegalArgumentException("Null input!"); - } - - byte[] data = in.getData(); - if (data == null || (data.length != SIZE && data.length != 0)) { - throw new IllegalArgumentException(); - } - - setupData(data); - } - - public AionAddress(final String in) { - - if (in == null) { - throw new IllegalArgumentException(); - } - - byte[] hexByte = ByteUtil.hexStringToBytes(in); - - if (hexByte.length != SIZE && hexByte.length != 0) { - throw new IllegalArgumentException(); - } - - setupData(hexByte); - } - - private void setupData(final byte[] in) { - this.address = in; - this.hashCode = Arrays.hashCode(in); - } - - public static AionAddress wrap(final byte[] addr) { - return new AionAddress(addr); - } - - public static AionAddress wrap(final String addr) { - return new AionAddress(addr); - } - - public static AionAddress wrap(final ByteArrayWrapper addr) { - return new AionAddress(addr); - } - - public final String toString() { - return ByteUtil.toHexString(address); - } - - public final ByteArrayWrapper toByteArrayWrapper() { - return ByteArrayWrapper.wrap(this.address); - } - - @Override - public final byte[] toBytes() { - return this.address; - } - - @Override - public final AionAddress clone() { - if (this.address.length == 0) { - return emptyAddr; - } else { - return new AionAddress(Arrays.copyOf(this.address, SIZE)); - } - } - - public boolean equals(Object other) { - if (!(other instanceof Address)) { - return false; - } else { - byte[] otherAddress = ((Address) other).toBytes(); - return Arrays.equals(this.address, otherAddress); - } - } - - public int hashCode() { - return this.hashCode; - } - - @Override - public int compareTo(AionAddress o) { - return Arrays.compare(this.address, o.toBytes()); - } - - public int compareTo(byte[] o) { - return Arrays.compare(this.address, o); - } - - @Override - public final AionAddress fromBytes(byte[] bs) { - return new AionAddress(bs); - } - - public static AionAddress ZERO_ADDRESS() { - return zeroAddr; - } - - public static AionAddress EMPTY_ADDRESS() { - return emptyAddr; - } - - public boolean isEmptyAddress() { - return Arrays.equals(address, emptyAddr.toBytes()); - } - - public boolean isZeroAddress() { - return Arrays.equals(address, zeroAddr.toBytes()); - } -} diff --git a/modAionBase/src/org/aion/base/type/Hash256.java b/modAionBase/src/org/aion/base/type/Hash256.java deleted file mode 100644 index 59f3c73ea8..0000000000 --- a/modAionBase/src/org/aion/base/type/Hash256.java +++ /dev/null @@ -1,166 +0,0 @@ -package org.aion.base.type; - -import java.util.Arrays; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.Bytesable; - -public final class Hash256 implements Comparable, Bytesable, Cloneable { - - public static final int BYTES = 32; - private static final Hash256 zeroHash = Hash256.wrap(new byte[BYTES]); - - private byte[] hash = new byte[BYTES]; - private int hashCode = 0; - - public Hash256(byte[] in) { - - if (in == null) { - throw new IllegalArgumentException("Null input!"); - } - - if (in.length != BYTES) { - throw new IllegalArgumentException(); - } - - setupData(in); - } - - public Hash256(String in) { - - if (in == null) { - throw new IllegalArgumentException("Null input!"); - } - - byte[] out = ByteUtil.hexStringToBytes(in); - - if (out.length != BYTES) { - throw new IllegalArgumentException(); - } - - setupData(out); - } - - public Hash256(final ByteArrayWrapper in) { - - if (in == null) { - throw new IllegalArgumentException("Null input!"); - } - - byte[] data = in.getData(); - if (data == null || data.length != BYTES) { - throw new IllegalArgumentException(); - } - - setupData(data); - } - - private void setupData(final byte[] in) { - this.hash = in; - this.hashCode = Arrays.hashCode(in); - } - - public static Hash256 wrap(final byte[] hash) { - return new Hash256(hash); - } - - public static Hash256 wrap(final String hash) { - return new Hash256(hash); - } - - public static Hash256 wrap(final ByteArrayWrapper hash) { - return new Hash256(hash); - } - - public final String toString() { - return ByteUtil.toHexString(hash); - } - - public final ByteArrayWrapper toByteArrayWrapper() { - return ByteArrayWrapper.wrap(this.hash); - } - - @Override - public final byte[] toBytes() { - return this.hash; - } - - @Override - public Hash256 clone() throws CloneNotSupportedException { - try { - return new Hash256(Arrays.copyOf(this.hash, BYTES)); - } catch (Exception e) { - throw new CloneNotSupportedException(e.toString()); - } - } - - public boolean equals(Object other) { - if (!(other instanceof Hash256)) { - return false; - } else { - byte[] otherAddress = ((Hash256) other).toBytes(); - return Arrays.compare(this.hash, otherAddress) == 0; - } - } - - public int hashCode() { - return this.hashCode; - } - - /** - * Compares this object with the specified object for order. Returns a negative integer, zero, - * or a positive integer as this object is less than, equal to, or greater than the specified - * object. - * - *

- * - *

The implementor must ensure {@code sgn(x.compareTo(y)) == -sgn(y.compareTo(x))} for all - * {@code x} and {@code y}. (This implies that {@code x.compareTo(y)} must throw an exception - * iff {@code y.compareTo(x)} throws an exception.) - * - *

- * - *

The implementor must also ensure that the relation is transitive: {@code (x.compareTo(y) > - * 0 && y.compareTo(z) > 0)} implies {@code x.compareTo(z) > 0}. - * - *

- * - *

Finally, the implementor must ensure that {@code x.compareTo(y)==0} implies that {@code - * sgn(x.compareTo(z)) == sgn(y.compareTo(z))}, for all {@code z}. - * - *

- * - *

It is strongly recommended, but not strictly required that {@code - * (x.compareTo(y)==0) == (x.equals(y))}. Generally speaking, any class that implements the - * {@code Comparable} interface and violates this condition should clearly indicate this fact. - * The recommended language is "Note: this class has a natural ordering that is inconsistent - * with equals." - * - *

- * - *

In the foregoing description, the notation {@code sgn(}expression{@code )} - * designates the mathematical signum function, which is defined to return one of {@code - * -1}, {@code 0}, or {@code 1} according to whether the value of expression is negative, - * zero, or positive, respectively. - * - * @param o the object to be compared. - * @return a negative integer, zero, or a positive integer as this object is less than, equal - * to, or greater than the specified object. - * @throws NullPointerException if the specified object is null - * @throws ClassCastException if the specified object's type prevents it from being compared to - * this object. - */ - @Override - public int compareTo(Hash256 o) { - return Arrays.compare(this.hash, o.toBytes()); - } - - @Override - public final Hash256 fromBytes(byte[] bs) { - return new Hash256(bs); - } - - public static final Hash256 ZERO_HASH() { - return zeroHash; - } -} diff --git a/modAionBase/src/org/aion/base/type/IBlock.java b/modAionBase/src/org/aion/base/type/IBlock.java deleted file mode 100644 index 63e71be8b9..0000000000 --- a/modAionBase/src/org/aion/base/type/IBlock.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * @Copyright Nuco Inc. 2016 - * @Author jin@nuco.io * - */ -package org.aion.base.type; - -import java.util.List; - -/** @author jin */ -public interface IBlock { - - long getNumber(); - - byte[] getParentHash(); - - byte[] getHash(); - - byte[] getEncoded(); - - String getShortHash(); - - boolean isEqual(IBlock block); - - String getShortDescr(); - - List getTransactionsList(); - - BH getHeader(); - - /** - * Newly added with the refactory of API for libNc, both chains should have implemented this - * - * @return - */ - byte[] getReceiptsRoot(); - - long getTimestamp(); -} diff --git a/modAionBase/src/org/aion/base/type/IBlockHeader.java b/modAionBase/src/org/aion/base/type/IBlockHeader.java deleted file mode 100644 index 7b7092737f..0000000000 --- a/modAionBase/src/org/aion/base/type/IBlockHeader.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.aion.base.type; - -import org.aion.vm.api.interfaces.Address; - -/** @author jay */ -public interface IBlockHeader { - - // Getter - byte[] getParentHash(); - - byte[] getStateRoot(); - - byte[] getTxTrieRoot(); - - byte[] getReceiptsRoot(); - - byte[] getLogsBloom(); - - byte[] getExtraData(); - - byte[] getNonce(); - - byte[] getHash(); - - byte[] getEncoded(); - - Address getCoinbase(); - - long getTimestamp(); - - long getNumber(); - - // Setter - void setCoinbase(Address _cb); - - void setStateRoot(byte[] _strt); - - void setReceiptsRoot(byte[] _rcrt); - - void setTransactionsRoot(byte[] _txrt); - - void setTimestamp(long _ts); - - void setNumber(long _nb); - - void setNonce(byte[] _nc); - - void setLogsBloom(byte[] _lb); - - void setExtraData(byte[] _ed); - - boolean isGenesis(); -} diff --git a/modAionBase/src/org/aion/base/type/IBlockIdentifier.java b/modAionBase/src/org/aion/base/type/IBlockIdentifier.java deleted file mode 100644 index bea6979de9..0000000000 --- a/modAionBase/src/org/aion/base/type/IBlockIdentifier.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.aion.base.type; - -/** @author jay */ -public interface IBlockIdentifier { - - byte[] getHash(); - - long getNumber(); -} diff --git a/modAionBase/src/org/aion/base/type/IBlockSummary.java b/modAionBase/src/org/aion/base/type/IBlockSummary.java deleted file mode 100644 index 8d300e3e92..0000000000 --- a/modAionBase/src/org/aion/base/type/IBlockSummary.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.aion.base.type; - -import java.util.List; - -/** @author jay */ -public interface IBlockSummary { - List getReceipts(); - - IBlock getBlock(); -} diff --git a/modAionBase/src/org/aion/base/type/IPowBlockHeader.java b/modAionBase/src/org/aion/base/type/IPowBlockHeader.java deleted file mode 100644 index 85fbaf10e1..0000000000 --- a/modAionBase/src/org/aion/base/type/IPowBlockHeader.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.aion.base.type; - -import java.math.BigInteger; - -/** @author jay */ -public interface IPowBlockHeader extends IBlockHeader { - - byte[] getDifficulty(); - - BigInteger getDifficultyBI(); - - void setDifficulty(byte[] _diff); - - byte[] getPowBoundary(); -} diff --git a/modAionBase/src/org/aion/base/type/ISolution.java b/modAionBase/src/org/aion/base/type/ISolution.java deleted file mode 100644 index 04fd8797a1..0000000000 --- a/modAionBase/src/org/aion/base/type/ISolution.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.aion.base.type; - -/** Interface for any PoW and PoI miner solution. */ -public interface ISolution {} diff --git a/modAionBase/src/org/aion/base/type/ITransaction.java b/modAionBase/src/org/aion/base/type/ITransaction.java deleted file mode 100644 index 360993d84c..0000000000 --- a/modAionBase/src/org/aion/base/type/ITransaction.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.aion.base.type; - -import java.math.BigInteger; -import org.aion.vm.api.interfaces.TransactionInterface; - -/** @author jin */ -public interface ITransaction extends Cloneable, TransactionInterface { - - byte[] getEncoded(); - - BigInteger getNonceBI(); - - BigInteger getTimeStampBI(); - - ITransaction clone(); - - long getNrgConsume(); - - void setEncoded(byte[] _encodedData); - - void setNrgConsume(long _nrg); -} diff --git a/modAionBase/src/org/aion/base/type/ITxExecSummary.java b/modAionBase/src/org/aion/base/type/ITxExecSummary.java deleted file mode 100644 index 1589e0722b..0000000000 --- a/modAionBase/src/org/aion/base/type/ITxExecSummary.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.aion.base.type; - -import java.math.BigInteger; -import java.util.List; - -public interface ITxExecSummary { - - Object getBuilder(ITxReceipt receipt); - - boolean isRejected(); - - BigInteger getRefund(); - - BigInteger getFee(); - - ITxReceipt getReceipt(); - - List getLogs(); -} diff --git a/modAionBase/src/org/aion/base/type/ITxReceipt.java b/modAionBase/src/org/aion/base/type/ITxReceipt.java deleted file mode 100644 index 728d3a4c66..0000000000 --- a/modAionBase/src/org/aion/base/type/ITxReceipt.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.aion.base.type; - -import java.util.List; - -/** @author jay */ -public interface ITxReceipt { - void setTransaction(TX tx); - - void setLogs(List logs); - - void setNrgUsed(long nrg); - - void setExecutionResult(byte[] result); - - void setError(String error); -} diff --git a/modAionBase/src/org/aion/base/util/ByteArrayMap.java b/modAionBase/src/org/aion/base/util/ByteArrayMap.java deleted file mode 100644 index f707910339..0000000000 --- a/modAionBase/src/org/aion/base/util/ByteArrayMap.java +++ /dev/null @@ -1,132 +0,0 @@ -package org.aion.base.util; - -import java.util.Arrays; -import java.util.Map; - -/** - * hashmap class for byte[] -> byte[] mapping. - * - * @author jin - */ -public class ByteArrayMap extends HashMap { - - private static final long serialVersionUID = -5203317888679449508L; - transient ByteArrayNode[] table; - - public ByteArrayMap() { - super(); - } - - public ByteArrayMap(int cap) { - super(cap); - } - - @Override - protected int hash(Object key) { - if (key == null || !(key instanceof byte[])) { - return 0; - } - byte[] bs = (byte[]) key; - return Arrays.hashCode(bs); - } - - @Override - protected boolean keyEquals(Object key, byte[] k) { - if (!(key instanceof byte[])) { - return false; - } - return Arrays.equals((byte[]) key, k); - } - - @Override - protected boolean valEquals(Object val, byte[] v) { - if (!(val instanceof byte[])) { - return false; - } - return Arrays.equals((byte[]) val, v); - } - - @Override - protected Node newNode( - int hash, byte[] key, byte[] value, Node next) { - return new ByteArrayNode(hash, key, value, next); - } - - @Override - protected Node replacementNode( - Node p, Node next) { - return new ByteArrayNode(p.hash, p.key, p.value, next); - } - - @Override - protected TreeNode newTreeNode( - int hash, byte[] key, byte[] value, Node next) { - return new ByteArrayTreeNode(hash, key, value, next); - } - - @Override - protected TreeNode replacementTreeNode( - Node p, Node next) { - return new ByteArrayTreeNode(p.hash, p.key, p.value, next); - } - - static class ByteArrayNode extends Node { - - ByteArrayNode(int hash, byte[] key, byte[] value, Node next) { - super(hash, key, value, next); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (o instanceof Map.Entry) { - Map.Entry e = (Map.Entry) o; - if (Arrays.equals(key, (byte[]) e.getKey()) - && Arrays.equals(value, (byte[]) e.getValue())) { - return true; - } - } - return false; - } - } - - static class ByteArrayTreeNode extends TreeNode { - - ByteArrayTreeNode(int hash, byte[] key, byte[] value, Node next) { - super(hash, key, value, next); - } - - @Override - protected boolean keyEquals(Object key, byte[] k) { - if (!(key instanceof byte[])) { - return false; - } - return Arrays.equals((byte[]) key, k); - } - - @Override - protected boolean valEquals(Object val, byte[] v) { - if (!(val instanceof byte[])) { - return false; - } - return Arrays.equals((byte[]) val, v); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (o instanceof Map.Entry) { - Map.Entry e = (Map.Entry) o; - if (Arrays.equals(key, (byte[]) e.getKey()) - && Arrays.equals(value, (byte[]) e.getValue())) { - return true; - } - } - return false; - } - } -} diff --git a/modAionBase/src/org/aion/base/util/ByteArrayWrapper.java b/modAionBase/src/org/aion/base/util/ByteArrayWrapper.java deleted file mode 100644 index 441d55213d..0000000000 --- a/modAionBase/src/org/aion/base/util/ByteArrayWrapper.java +++ /dev/null @@ -1,108 +0,0 @@ -package org.aion.base.util; - -import java.io.Serializable; -import java.util.Arrays; - -public class ByteArrayWrapper - implements Comparable, Serializable, Bytesable { - - private static final long serialVersionUID = -2937011296133778157L; - private final byte[] data; - private int hashCode = 0; - - public ByteArrayWrapper(byte[] data) { - if (data == null) { - throw new NullPointerException("Data must not be null"); - } - this.data = data; - this.hashCode = Arrays.hashCode(data); - } - - /** Constructor based on the hex representation of the byte array. */ - public ByteArrayWrapper(String data) { - if (data == null) { - throw new NullPointerException("Data must not be null"); - } - this.data = Hex.decode(data); - this.hashCode = Arrays.hashCode(this.data); - } - - public boolean equals(Object other) { - if (!(other instanceof ByteArrayWrapper)) { - return false; - } - - return Arrays.equals(data, ((ByteArrayWrapper) other).getData()); - } - - @Override - public int hashCode() { - return hashCode; - } - - @Override - public int compareTo(ByteArrayWrapper o) { - return Arrays.compare(data, o.getData()); - } - - public byte[] getData() { - return data; - } - - @Override - public String toString() { - return Hex.toHexString(data); - } - - // toBytes() and getData() have identical functionality - @Override - public byte[] toBytes() { - return data; - } - - @Override - public ByteArrayWrapper fromBytes(byte[] bs) { - return new ByteArrayWrapper(bs); - } - - public static ByteArrayWrapper wrap(byte[] data) { - return new ByteArrayWrapper(data); - } - - /** - * Checks if every byte in the array has the value 0. - * - * @return {@code true} if every byte in the array has the value 0, {@code false} otherwise - */ - public boolean isZero() { - int length = data.length; - for (int i = 0; i < length; i++) { - if (data[length - 1 - i] != 0) { - return false; - } - } - return true; - } - - /** - * Checks if the stored byte array is empty. - * - * @return {@code true} if empty, {@code false} otherwise - */ - public boolean isEmpty() { - return data.length == 0; - } - - public ByteArrayWrapper copy() { - int length = data.length; - byte[] bs = new byte[length]; - System.arraycopy(data, 0, bs, 0, length); - return new ByteArrayWrapper(bs); - } - - public static final ByteArrayWrapper ZERO = ByteArrayWrapper.wrap(new byte[] {0}); - - public byte[] getNoLeadZeroesData() { - return ByteUtil.stripLeadingZeroes(data); - } -} diff --git a/modAionBase/src/org/aion/base/util/ByteUtil.java b/modAionBase/src/org/aion/base/util/ByteUtil.java deleted file mode 100644 index ddfa984950..0000000000 --- a/modAionBase/src/org/aion/base/util/ByteUtil.java +++ /dev/null @@ -1,704 +0,0 @@ -package org.aion.base.util; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -/** @apiNote This functionality is migrated to modUtil. Use that class instead. */ -@Deprecated -public class ByteUtil { - - public static final byte[] EMPTY_WORD = new byte[32]; - public static final byte[] EMPTY_HALFWORD = new byte[16]; - public static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; - public static final byte[] ZERO_BYTE_ARRAY = new byte[] {0}; - public static final String EMPTY_STRING = ""; - - /** Creates a copy of bytes and appends b to the end of it */ - public static byte[] appendByte(byte[] bytes, byte b) { - byte[] result = Arrays.copyOf(bytes, bytes.length + 1); - result[result.length - 1] = b; - return result; - } - - /** - * The regular {@link java.math.BigInteger#toByteArray()} method isn't quite what we often need: - * it appends a leading zero to indicate that the number is positive and may need padding. - * - * @param b the integer to format into a byte array - * @param numBytes the desired size of the resulting byte array - * @return numBytes byte long array. - */ - public static byte[] bigIntegerToBytes(BigInteger b, int numBytes) { - if (b == null) { - return null; - } - byte[] bytes = new byte[numBytes]; - byte[] biBytes = b.toByteArray(); - int start = (biBytes.length == numBytes + 1) ? 1 : 0; - int length = Math.min(biBytes.length, numBytes); - System.arraycopy(biBytes, start, bytes, numBytes - length, length); - return bytes; - } - - public static byte[] bigIntegerToBytesSigned(BigInteger b, int numBytes) { - if (b == null) { - return null; - } - byte[] bytes = new byte[numBytes]; - Arrays.fill(bytes, b.signum() < 0 ? (byte) 0xFF : 0x00); - byte[] biBytes = b.toByteArray(); - int start = (biBytes.length == numBytes + 1) ? 1 : 0; - int length = Math.min(biBytes.length, numBytes); - System.arraycopy(biBytes, start, bytes, numBytes - length, length); - return bytes; - } - - /** - * Omitting sign indication byte.
- *
- * Instead of {@link org.spongycastle.util.BigIntegers#asUnsignedByteArray(BigInteger)}
- * we use this custom method to avoid an empty array in case of BigInteger.ZERO - * - * @param value - any big integer number. A null-value will return null - * - * @return A byte array without a leading zero byte if present in the signed encoding. - * BigInteger.ZERO will return an array with length 1 and byte-value 0. - */ - public static byte[] bigIntegerToBytes(BigInteger value) { - if (value == null) { - return null; - } - - byte[] data = value.toByteArray(); - - if (data.length != 1 && data[0] == 0) { - byte[] tmp = new byte[data.length - 1]; - System.arraycopy(data, 1, tmp, 0, tmp.length); - data = tmp; - } - return data; - } - - public static BigInteger bytesToBigInteger(byte[] bb) { - return bb.length == 0 ? BigInteger.ZERO : new BigInteger(1, bb); - } - - /** - * Returns the amount of nibbles that match each other from 0 ... amount will never be larger - * than smallest input - * - * @param a - first input - * @param b - second input - * @return Number of bytes that match - */ - public static int matchingNibbleLength(byte[] a, byte[] b) { - int i = 0; - int length = a.length < b.length ? a.length : b.length; - while (i < length) { - if (a[i] != b[i]) { - return i; - } - i++; - } - return i; - } - - /** Perform an in-place conversion of a byte array from big endian to little endian. */ - public static void toLEByteArray(byte[] toConvert) { - - if (toConvert == null) { - return; - } - - for (int i = 0; i < toConvert.length / 2; i++) { - byte temp = toConvert[i]; - toConvert[i] = toConvert[toConvert.length - 1 - i]; - toConvert[toConvert.length - 1 - i] = temp; - } - } - - /** - * Converts a long value into a byte array. - * - * @param val - long value to convert - * @return byte[] of length 8, representing the long value - */ - public static byte[] longToBytes(long val) { - return ByteBuffer.allocate(8).putLong(val).array(); - } - - public static byte[] longToBytesLE(long val) { - ByteBuffer bb = ByteBuffer.allocate(8); - bb.order(ByteOrder.LITTLE_ENDIAN); - return bb.putLong(val).array(); - } - - /** - * Converts a long value into a byte array. - * - * @param val - long value to convert - * @return decimal value with leading byte that are zeroes striped - */ - public static byte[] longToBytesNoLeadZeroes(long val) { - - // todo: improve performance by while strip numbers until (long >> 8 == - // 0) - if (val == 0) { - return EMPTY_BYTE_ARRAY; - } - - byte[] data = ByteBuffer.allocate(8).putLong(val).array(); - - return stripLeadingZeroes(data); - } - - /** - * Converts int value into a byte array. - * - * @param val - int value to convert - * @return byte[] of length 4, representing the int value - */ - public static byte[] intToBytes(int val) { - return ByteBuffer.allocate(4).putInt(val).array(); - } - - /** - * Converts and int value to a byte array (Little Endian) @ param val - * - * @return byte[] of length 4; representing the int value in LE order - */ - public static byte[] intToBytesLE(int val) { - ByteBuffer bb = ByteBuffer.allocate(4); - bb.order(ByteOrder.LITTLE_ENDIAN); - return bb.putInt(val).array(); - } - - /** - * Converts and int value to a byte array (Big Endian) @ param val - * - * @return byte[] of length 4; representing the int value in LE order - */ - public static byte[] intToBytesBE(int val) { - ByteBuffer bb = ByteBuffer.allocate(4); - bb.order(ByteOrder.BIG_ENDIAN); - return bb.putInt(val).array(); - } - - /** - * Converts a int value into a byte array. - * - * @param val - int value to convert - * @return value with leading byte that are zeroes striped - */ - public static byte[] intToBytesNoLeadZeroes(int val) { - - if (val == 0) { - return EMPTY_BYTE_ARRAY; - } - - int lenght = 0; - - int tmpVal = val; - while (tmpVal != 0) { - tmpVal = tmpVal >>> 8; - ++lenght; - } - - byte[] result = new byte[lenght]; - - int index = result.length - 1; - while (val != 0) { - - result[index] = (byte) (val & 0xFF); - val = val >>> 8; - index -= 1; - } - - return result; - } - - /** - * Convert a byte-array into a hex String.
- * Works similar to {@link Hex#toHexString} but allows for null - * - * @param data - byte-array to convert to a hex-string - * @return hex representation of the data.
- * Returns an empty String if the input is null TODO: swap out with more - * efficient implementation, for now seems like we are stuck with this - * @see Hex#toHexString - */ - public static String toHexString(byte[] data) { - return data == null ? "" : Hex.toHexString(data); - } - - public static String toHexStringWithPrefix(byte[] data) { - return "0x" + toHexString(data); - } - - /** - * Calculate packet length - * - * @param msg byte[] - * @return byte-array with 4 elements - */ - public static byte[] calcPacketLength(byte[] msg) { - int msgLen = msg.length; - return new byte[] { - (byte) ((msgLen >> 24) & 0xFF), - (byte) ((msgLen >> 16) & 0xFF), - (byte) ((msgLen >> 8) & 0xFF), - (byte) ((msgLen) & 0xFF) - }; - } - - /** - * Cast hex encoded value from byte[] to int - * - *

Limited to Integer.MAX_VALUE: 2^31-1 (4 bytes) - * - * @param b array contains the values - * @return unsigned positive int value. - */ - public static int byteArrayToInt(byte[] b) { - if (b == null || b.length == 0) { - return 0; - } - return new BigInteger(1, b).intValue(); - } - - /** - * Cast hex encoded value from byte[] to long - * - *

Limited to Long.MAX_VALUE: 2^63-1 (8 bytes) - * - * @param b array contains the values - * @return unsigned positive long value. - */ - public static long byteArrayToLong(byte[] b) { - if (b == null || b.length == 0) { - return 0; - } - return new BigInteger(1, b).longValue(); - } - - /** Used in conjunction w/ RLP, casts to byte */ - public static byte toByte(byte[] b) { - if (b == null || b.length == 0) { - return 0; - } - return b[0]; - } - - /** - * Turn nibbles to a pretty looking output string - * - *

Example. [ 1, 2, 3, 4, 5 ] becomes '\x11\x23\x45' - * - * @param nibbles - getting byte of data [ 04 ] and turning it to a '\x04' representation - * @return pretty string of nibbles - */ - public static String nibblesToPrettyString(byte[] nibbles) { - StringBuilder builder = new StringBuilder(); - for (byte nibble : nibbles) { - final String nibbleString = oneByteToHexString(nibble); - builder.append("\\x").append(nibbleString); - } - return builder.toString(); - } - - public static String oneByteToHexString(byte value) { - String retVal = Integer.toString(value & 0xFF, 16); - if (retVal.length() == 1) { - retVal = "0" + retVal; - } - return retVal; - } - - /** - * Calculate the number of bytes need to encode the number - * - * @param val - number - * @return number of min bytes used to encode the number - */ - public static int numBytes(String val) { - - BigInteger bInt = new BigInteger(val); - int bytes = 0; - - while (!bInt.equals(BigInteger.ZERO)) { - bInt = bInt.shiftRight(8); - ++bytes; - } - if (bytes == 0) { - ++bytes; - } - return bytes; - } - - /** - * @param arg - not more that 32 bits - * @return - bytes of the value pad with complete to 32 zeroes - */ - public static byte[] encodeValFor32Bits(Object arg) { - - byte[] data; - - // check if the string is numeric - if (arg.toString().trim().matches("-?\\d+(\\.\\d+)?")) { - data = new BigInteger(arg.toString().trim()).toByteArray(); - } // check if it's hex number - else if (arg.toString().trim().matches("0[xX][0-9a-fA-F]+")) { - data = new BigInteger(arg.toString().trim().substring(2), 16).toByteArray(); - } else { - data = arg.toString().trim().getBytes(); - } - - if (data.length > 32) { - throw new RuntimeException("values can't be more than 32 byte"); - } - - byte[] val = new byte[32]; - - int j = 0; - for (int i = data.length; i > 0; --i) { - val[31 - j] = data[i - 1]; - ++j; - } - return val; - } - - /** - * encode the values and concatenate together - * - * @param args Object - * @return byte[] - */ - public static byte[] encodeDataList(Object... args) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - for (Object arg : args) { - byte[] val = encodeValFor32Bits(arg); - try { - baos.write(val); - } catch (IOException e) { - throw new Error("Happen something that should never happen ", e); - } - } - return baos.toByteArray(); - } - - public static int firstNonZeroByte(byte[] data) { - for (int i = 0; i < data.length; ++i) { - if (data[i] != 0) { - return i; - } - } - return -1; - } - - public static byte[] stripLeadingZeroes(byte[] data) { - - if (data == null) { - return null; - } - - final int firstNonZero = firstNonZeroByte(data); - switch (firstNonZero) { - case -1: - return ZERO_BYTE_ARRAY; - - case 0: - return data; - - default: - byte[] result = new byte[data.length - firstNonZero]; - System.arraycopy(data, firstNonZero, result, 0, data.length - firstNonZero); - - return result; - } - } - - /** - * increment byte array as a number until max is reached - * - * @param bytes byte[] - * @return boolean - */ - public static boolean increment(byte[] bytes) { - final int startIndex = 0; - int i; - for (i = bytes.length - 1; i >= startIndex; i--) { - bytes[i]++; - if (bytes[i] != 0) { - break; - } - } - // we return false when all bytes are 0 again - return (i >= startIndex || bytes[startIndex] != 0); - } - - /** - * Utility function to copy a byte array into a new byte array with given size. If the src - * length is smaller than the given size, the result will be left-padded with zeros. - * - * @param value - a BigInteger with a maximum value of 2^256-1 - * @return Byte array of given size with a copy of the src - */ - public static byte[] copyToArray(BigInteger value) { - byte[] src = ByteUtil.bigIntegerToBytes(value); - byte[] dest = ByteBuffer.allocate(32).array(); - System.arraycopy(src, 0, dest, dest.length - src.length, src.length); - return dest; - } - - public static byte[] setBit(byte[] data, int pos, int val) { - - if ((data.length * 8) - 1 < pos) { - throw new Error("outside byte array limit, pos: " + pos); - } - - int posByte = data.length - 1 - (pos) / 8; - int posBit = (pos) % 8; - byte setter = (byte) (1 << (posBit)); - byte toBeSet = data[posByte]; - byte result; - if (val == 1) { - result = (byte) (toBeSet | setter); - } else { - result = (byte) (toBeSet & ~setter); - } - - data[posByte] = result; - return data; - } - - public static int getBit(byte[] data, int pos) { - - if ((data.length * 8) - 1 < pos) { - throw new Error("outside byte array limit, pos: " + pos); - } - - int posByte = data.length - 1 - pos / 8; - int posBit = pos % 8; - byte dataByte = data[posByte]; - return Math.min(1, (dataByte & (1 << (posBit)))); - } - - public static byte[] and(byte[] b1, byte[] b2) { - if (b1.length != b2.length) { - throw new RuntimeException("Array sizes differ"); - } - byte[] ret = new byte[b1.length]; - for (int i = 0; i < ret.length; i++) { - ret[i] = (byte) (b1[i] & b2[i]); - } - return ret; - } - - public static byte[] or(byte[] b1, byte[] b2) { - if (b1.length != b2.length) { - throw new RuntimeException("Array sizes differ"); - } - byte[] ret = new byte[b1.length]; - for (int i = 0; i < ret.length; i++) { - ret[i] = (byte) (b1[i] | b2[i]); - } - return ret; - } - - public static byte[] xor(byte[] b1, byte[] b2) { - if (b1.length != b2.length) { - throw new RuntimeException("Array sizes differ"); - } - byte[] ret = new byte[b1.length]; - for (int i = 0; i < ret.length; i++) { - ret[i] = (byte) (b1[i] ^ b2[i]); - } - return ret; - } - - /** - * XORs byte arrays of different lengths by aligning length of the shortest via adding zeros at - * beginning - */ - public static byte[] xorAlignRight(byte[] b1, byte[] b2) { - if (b1.length > b2.length) { - byte[] b2_ = new byte[b1.length]; - System.arraycopy(b2, 0, b2_, b1.length - b2.length, b2.length); - b2 = b2_; - } else if (b2.length > b1.length) { - byte[] b1_ = new byte[b2.length]; - System.arraycopy(b1, 0, b1_, b2.length - b1.length, b1.length); - b1 = b1_; - } - - return xor(b1, b2); - } - - /** - * @param arrays - arrays to merge - * @return - merged array - */ - public static byte[] merge(byte[]... arrays) { - int count = 0; - for (byte[] array : arrays) { - count += array.length; - } - - // Create new array and copy all array contents - byte[] mergedArray = new byte[count]; - int start = 0; - for (byte[] array : arrays) { - System.arraycopy(array, 0, mergedArray, start, array.length); - start += array.length; - } - return mergedArray; - } - - public static boolean isNullOrZeroArray(byte[] array) { - return (array == null) || (array.length == 0); - } - - public static boolean isSingleZero(byte[] array) { - return (array.length == 1 && array[0] == 0); - } - - public static Set difference(Set setA, Set setB) { - - Set result = new HashSet<>(); - - for (byte[] elementA : setA) { - boolean found = false; - for (byte[] elementB : setB) { - - if (Arrays.equals(elementA, elementB)) { - found = true; - break; - } - } - if (!found) { - result.add(elementA); - } - } - - return result; - } - - public static int length(byte[]... bytes) { - int result = 0; - for (byte[] array : bytes) { - result += (array == null) ? 0 : array.length; - } - return result; - } - - public static byte[] intsToBytes(int[] arr, boolean bigEndian) { - byte[] ret = new byte[arr.length * 4]; - intsToBytes(arr, ret, bigEndian); - return ret; - } - - public static int[] bytesToInts(byte[] arr, boolean bigEndian) { - int[] ret = new int[arr.length / 4]; - bytesToInts(arr, ret, bigEndian); - return ret; - } - - public static void bytesToInts(byte[] b, int[] arr, boolean bigEndian) { - if (!bigEndian) { - int off = 0; - for (int i = 0; i < arr.length; i++) { - int ii = b[off++] & 0x000000FF; - ii |= (b[off++] << 8) & 0x0000FF00; - ii |= (b[off++] << 16) & 0x00FF0000; - ii |= (b[off++] << 24); - arr[i] = ii; - } - } else { - int off = 0; - for (int i = 0; i < arr.length; i++) { - int ii = b[off++] << 24; - ii |= (b[off++] << 16) & 0x00FF0000; - ii |= (b[off++] << 8) & 0x0000FF00; - ii |= b[off++] & 0x000000FF; - arr[i] = ii; - } - } - } - - public static void intsToBytes(int[] arr, byte[] b, boolean bigEndian) { - if (!bigEndian) { - int off = 0; - for (int i = 0; i < arr.length; i++) { - int ii = arr[i]; - b[off++] = (byte) (ii & 0xFF); - b[off++] = (byte) ((ii >> 8) & 0xFF); - b[off++] = (byte) ((ii >> 16) & 0xFF); - b[off++] = (byte) ((ii >> 24) & 0xFF); - } - } else { - int off = 0; - for (int i = 0; i < arr.length; i++) { - int ii = arr[i]; - b[off++] = (byte) ((ii >> 24) & 0xFF); - b[off++] = (byte) ((ii >> 16) & 0xFF); - b[off++] = (byte) ((ii >> 8) & 0xFF); - b[off++] = (byte) (ii & 0xFF); - } - } - } - - public static short bigEndianToShort(byte[] bs) { - return bigEndianToShort(bs, 0); - } - - public static short bigEndianToShort(byte[] bs, int off) { - int n = bs[off] << 8; - ++off; - n |= bs[off] & 0xFF; - return (short) n; - } - - public static byte[] shortToBytes(short n) { - return ByteBuffer.allocate(2).putShort(n).array(); - } - - /** - * Converts string hex representation to data bytes Accepts following hex: - with or without 0x - * prefix - with no leading 0, like 0xabc -> 0x0abc - * - * @param data String like '0xa5e..' or just 'a5e..' - * @return decoded bytes array - */ - public static byte[] hexStringToBytes(String data) { - if (data == null) { - return EMPTY_BYTE_ARRAY; - } - if (data.startsWith("0x")) { - data = data.substring(2); - } - if (data.length() % 2 == 1) { - data = "0" + data; - } - return Hex.decode(data); - } - - /** - * Chops a 32-byte value into a 16-byte value. Keep in mind the subtlety that a "chopped" - * bytearray is a different reference from a "unchopped" bytearray, so make no assummptions as - * to whether this function news the element. - * - * @return 16-byte value representing the LOWER portion of the original - */ - public static byte[] chop(byte[] in) { - if (in.length <= 16) { - return in; - } - return Arrays.copyOfRange(in, in.length - 16, in.length); - } -} diff --git a/modAionBase/src/org/aion/base/util/Bytesable.java b/modAionBase/src/org/aion/base/util/Bytesable.java deleted file mode 100644 index ae6bc4189a..0000000000 --- a/modAionBase/src/org/aion/base/util/Bytesable.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.aion.base.util; - -/** @author jin */ -public interface Bytesable { - - byte[] NULL_BYTE = new byte[] {(byte) 0x0}; - - byte[] toBytes(); - - T fromBytes(byte[] bs); -} diff --git a/modAionBase/src/org/aion/base/util/Copyable.java b/modAionBase/src/org/aion/base/util/Copyable.java deleted file mode 100644 index 5a3dc0daec..0000000000 --- a/modAionBase/src/org/aion/base/util/Copyable.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.aion.base.util; - -/** - * Alternative to Cloneable from java read: http://www.artima.com/intv/bloch13.html - * - * @author yao - * @param - */ -public interface Copyable { - T copy(); -} diff --git a/modAionBase/src/org/aion/base/util/FastByteComparisons.java b/modAionBase/src/org/aion/base/util/FastByteComparisons.java deleted file mode 100644 index 1cbfb79740..0000000000 --- a/modAionBase/src/org/aion/base/util/FastByteComparisons.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.aion.base.util; - -import java.util.Arrays; - -public final class FastByteComparisons { - /** - * Check if two byte arrays are equal. - * - * @param array1 - * @param array2 - * @return - */ - public static boolean equal(byte[] array1, byte[] array2) { - return Arrays.equals(array1, array2); - } - - /** - * Compares two byte arrays. - * - * @param array1 - * @param array2 - * @return - */ - public static int compareTo(byte[] array1, byte[] array2) { - return Arrays.compare(array1, array2); - } - - /** - * Compares two regions of byte array. - * - * @param array1 - * @param offset1 - * @param size1 - * @param array2 - * @param offset2 - * @param size2 - * @return - */ - public static int compareTo( - byte[] array1, int offset1, int size1, byte[] array2, int offset2, int size2) { - byte[] b1 = Arrays.copyOfRange(array1, offset1, offset1 + size1); - byte[] b2 = Arrays.copyOfRange(array2, offset2, offset2 + size2); - - return Arrays.compare(b1, b2); - } -} diff --git a/modAionBase/src/org/aion/base/util/Functional.java b/modAionBase/src/org/aion/base/util/Functional.java deleted file mode 100644 index 1bfd9fb3eb..0000000000 --- a/modAionBase/src/org/aion/base/util/Functional.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.aion.base.util; - -public interface Functional { - - /** - * Represents an operation that accepts a single input argument and returns no result. Unlike - * most other functional interfaces, {@code Consumer} is expected to operate via side-effects. - * - * @param the type of the input to the operation - */ - interface Consumer { - - /** - * Performs this operation on the given argument. - * - * @param t the input argument - */ - void accept(T t); - } - - /** - * Represents an operation that accepts two input arguments and returns no result. This is the - * two-arity specialization of {@link java.util.function.Consumer}. Unlike most other functional - * interfaces, {@code BiConsumer} is expected to operate via side-effects. - * - * @param the type of the first argument to the operation - * @param the type of the second argument to the operation - * @see org.ethereum.util.Functional.Consumer - */ - interface BiConsumer { - - /** - * Performs this operation on the given arguments. - * - * @param t the first input argument - * @param u the second input argument - */ - void accept(T t, U u); - } - - /** - * Represents a function that accepts one argument and produces a result. - * - * @param the type of the input to the function - * @param the type of the result of the function - */ - interface Function { - - /** - * Applies this function to the given argument. - * - * @param t the function argument - * @return the function result - */ - R apply(T t); - } - - interface Supplier { - - /** - * Gets a result. - * - * @return a result - */ - T get(); - } - - interface InvokeWrapper { - - void invoke(); - } - - interface InvokeWrapperWithResult { - - R invoke(); - } - - interface Predicate { - - boolean test(T t); - } -} diff --git a/modAionBase/src/org/aion/base/util/Hex.java b/modAionBase/src/org/aion/base/util/Hex.java deleted file mode 100644 index 0fb02b3ae4..0000000000 --- a/modAionBase/src/org/aion/base/util/Hex.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.aion.base.util; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -/** - * Utility class for converting hex data to bytes and back again. - * - * @apiNote This functionality is migrated to modUtil. Use that class instead. - */ -@Deprecated -public class Hex { - - private static final HexEncoder encoder = new HexEncoder(); - - public static String toHexString(byte[] data) { - return toHexString(data, 0, data.length); - } - - public static String toHexString(byte[] data, int off, int length) { - byte[] encoded = encode(data, off, length); - return new String(encoded); - } - - /** - * encode the input data producing a Hex encoded byte array. - * - * @return a byte array containing the Hex encoded data. - */ - public static byte[] encode(byte[] data) { - return encode(data, 0, data.length); - } - - /** - * encode the input data producing a Hex encoded byte array. - * - * @return a byte array containing the Hex encoded data. - */ - public static byte[] encode(byte[] data, int off, int length) { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - - encoder.encode(data, off, length, bOut); - - return bOut.toByteArray(); - } - - /** - * Hex encode the byte data writing it to the given output stream. - * - * @return the number of bytes produced. - */ - public static int encode(byte[] data, OutputStream out) throws IOException { - return encoder.encode(data, 0, data.length, out); - } - - /** - * Hex encode the byte data writing it to the given output stream. - * - * @return the number of bytes produced. - */ - public static int encode(byte[] data, int off, int length, OutputStream out) - throws IOException { - return encoder.encode(data, off, length, out); - } - - /** - * decode the Hex encoded input data. It is assumed the input data is valid. - * - * @return a byte array representing the decoded data. - */ - public static byte[] decode(byte[] data) { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - try { - encoder.decode(data, 0, data.length, bOut); - } catch (IOException e) { - System.err.println("Hex decode failed! " + data); - return null; - } - - return bOut.toByteArray(); - } - - /** - * decode the Hex encoded String data - whitespace will be ignored. - * - * @return a byte array representing the decoded data. - */ - public static byte[] decode(String data) { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - try { - encoder.decode(data, bOut); - } catch (IOException e) { - System.err.println("Hex decode failed! " + data); - return null; - } - return bOut.toByteArray(); - } - - /** - * decode the Hex encoded String data writing it to the given output stream, whitespace - * characters will be ignored. - * - * @return the number of bytes produced. - */ - public static int decode(String data, OutputStream out) throws IOException { - return encoder.decode(data, out); - } -} diff --git a/modAionBase/src/org/aion/base/util/HexEncoder.java b/modAionBase/src/org/aion/base/util/HexEncoder.java deleted file mode 100644 index f8d688f406..0000000000 --- a/modAionBase/src/org/aion/base/util/HexEncoder.java +++ /dev/null @@ -1,164 +0,0 @@ -package org.aion.base.util; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * A streaming Hex encoder. - * - * @apiNote This functionality is migrated to modUtil. Use that class instead. - */ -@Deprecated -public class HexEncoder { - - protected final byte[] encodingTable = { - (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', - (byte) '7', - (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', - (byte) 'f' - }; - - /* - * set up the decoding table. - */ - protected final byte[] decodingTable = new byte[128]; - - protected void initialiseDecodingTable() { - for (int i = 0; i < decodingTable.length; i++) { - decodingTable[i] = (byte) 0xff; - } - - for (int i = 0; i < encodingTable.length; i++) { - decodingTable[encodingTable[i]] = (byte) i; - } - - decodingTable['A'] = decodingTable['a']; - decodingTable['B'] = decodingTable['b']; - decodingTable['C'] = decodingTable['c']; - decodingTable['D'] = decodingTable['d']; - decodingTable['E'] = decodingTable['e']; - decodingTable['F'] = decodingTable['f']; - } - - public HexEncoder() { - initialiseDecodingTable(); - } - - /** - * encode the input data producing a Hex output stream. - * - * @return the number of bytes produced. - */ - public int encode(byte[] data, int off, int length, OutputStream out) { - for (int i = off; i < (off + length); i++) { - int v = data[i] & 0xff; - try { - out.write(encodingTable[(v >>> 4)]); - out.write(encodingTable[v & 0xf]); - } catch (Exception e) { - } - } - - return length * 2; - } - - private static boolean ignore(char c) { - return c == '\n' || c == '\r' || c == '\t' || c == ' '; - } - - /** - * decode the Hex encoded byte data writing it to the given output stream, whitespace characters - * will be ignored. - * - * @return the number of bytes produced. - */ - public int decode(byte[] data, int off, int length, OutputStream out) throws IOException { - byte b1, b2; - int outLen = 0; - - int end = off + length; - - while (end > off) { - if (!ignore((char) data[end - 1])) { - break; - } - - end--; - } - - int i = off; - while (i < end) { - while (i < end && ignore((char) data[i])) { - i++; - } - - b1 = decodingTable[data[i++]]; - - while (i < end && ignore((char) data[i])) { - i++; - } - - b2 = decodingTable[data[i++]]; - - if ((b1 | b2) < 0) { - throw new IOException("invalid characters encountered in Hex data"); - } - - try { - out.write((b1 << 4) | b2); - } catch (Exception e) { - - } - - outLen++; - } - - return outLen; - } - - /** - * decode the Hex encoded String data writing it to the given output stream, whitespace - * characters will be ignored. - * - * @return the number of bytes produced. - */ - public int decode(String data, OutputStream out) throws IOException { - byte b1, b2; - int length = 0; - - int end = data.length(); - - while (end > 0) { - if (!ignore(data.charAt(end - 1))) { - break; - } - - end--; - } - - int i = 0; - while (i < end) { - while (i < end && ignore(data.charAt(i))) { - i++; - } - - b1 = decodingTable[data.charAt(i++)]; - - while (i < end && ignore(data.charAt(i))) { - i++; - } - - b2 = decodingTable[data.charAt(i++)]; - - if ((b1 | b2) < 0) { - throw new IOException("invalid characters encountered in Hex string"); - } - - out.write((b1 << 4) | b2); - - length++; - } - - return length; - } -} diff --git a/modAionBase/src/org/aion/base/util/ImmutableByteArrayWrapper.java b/modAionBase/src/org/aion/base/util/ImmutableByteArrayWrapper.java deleted file mode 100644 index 5262341723..0000000000 --- a/modAionBase/src/org/aion/base/util/ImmutableByteArrayWrapper.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.aion.base.util; - -import java.util.Arrays; - -/** - * Immutable byte array wrapper used when storing keys inside HashMap, this way we guarantee that - * keys inside HashMap never change - * - * @author yao - */ -public class ImmutableByteArrayWrapper implements Comparable { - protected byte[] data; - protected int hashCode; - - /** For us to be able to create MutableByteArrayObserver */ - protected ImmutableByteArrayWrapper() { - data = null; - hashCode = 0; - } - - public ImmutableByteArrayWrapper(byte[] data) { - if (data == null) throw new NullPointerException("data cannot be null"); - this.data = new byte[data.length]; - System.arraycopy(data, 0, this.data, 0, data.length); - this.hashCode = Arrays.hashCode(this.data); - } - - public ByteArrayWrapper toByteArrayWrapper() { - byte[] d = new byte[data.length]; - System.arraycopy(this.data, 0, d, 0, this.data.length); - return new ByteArrayWrapper(d); - } - - public byte[] getData() { - byte[] d = new byte[data.length]; - System.arraycopy(this.data, 0, d, 0, this.data.length); - return d; - } - - /** - * Utility constructor, for us to easily convert ByteArrayWrapper over to immutable form - * - * @param other - */ - public ImmutableByteArrayWrapper(ByteArrayWrapper other) { - this(other.getData()); - } - - /** - * Copy constructor - * - * @param other - */ - public ImmutableByteArrayWrapper(ImmutableByteArrayWrapper other) { - this(other.data); - } - - /** Allow comparisons between both ByteArrayWrapper and ImmutableByteArrayWrapper */ - @Override - public boolean equals(Object other) { - if (!(other instanceof ByteArrayWrapper) && !(other instanceof ImmutableByteArrayWrapper)) { - return false; - } - - byte[] otherData = null; - if (other instanceof ByteArrayWrapper) otherData = ((ByteArrayWrapper) other).getData(); - - if (other instanceof ImmutableByteArrayWrapper) - otherData = ((ImmutableByteArrayWrapper) other).data; - - // probably impossible, but be safe - if (otherData == null) return false; - - return Arrays.compare(data, otherData) == 0; - } - - @Override - public int hashCode() { - return hashCode; - } - - @Override - public String toString() { - return ByteUtil.toHexString(this.data); - } - - /** TODO: what happens when one is null and the other is not? */ - @Override - public int compareTo(ImmutableByteArrayWrapper o) { - return Arrays.compare(data, o.data); - } -} diff --git a/modAionBase/src/org/aion/base/util/MAFast.java b/modAionBase/src/org/aion/base/util/MAFast.java deleted file mode 100644 index 3c11566f4f..0000000000 --- a/modAionBase/src/org/aion/base/util/MAFast.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.aion.base.util; - -/** - * http://www.daycounter.com/LabBook/Moving-Average.phtml - * - *

The best way to remove noise and smooth out sensor data is to compute a moving average. The - * moving average is a running average computer over a window the last N points of data. The average - * is expressed as the sum of the last N points divided by N: - * - *

MA[i]= sum(x[i]+x[i-(N-1)])/N - * - *

The brute force way to compute this is to repeat the computation for every new data point. - * This requires that N data points are stored, and N-1 additions are computed with a single divide. - * - *

Another way to update the moving average is to merely subtract x[i-N-1]/N and to add x[i]/N to - * the current MA. This requires 2 additions and 2 divisions, but still this requires that N data - * points be saved. - * - *

The following method doesn't require any storage of previous data values, and minimizes - * divisions which are computationally intensive. It works by subtracting out the mean each time, - * and adding in a new point. - * - *

MA*[i]= MA*[i-1] +X[i] - MA*[i-1]/N - * - *

where MA* is the moving average*N. - * - *

MA[i]= MA*[i]/N - * - *

The advantage of this technique is that previous data values need not be stored. If N is a - * power of 2 the division can be accomplished with a computationally efficient shift. So a single - * division and subtraction and 2 shifts are all that are needed, rendering suitable for a simple - * microcontroller. - */ -// public class MAFast { -// private double MAStar; // MA*[i-1] -// private volatile double MA; // MA[i] -// private int N; -// -// public MAFast(int N) { -// this.N = N; -// this.MAStar = 0D; -// this.MA = 0D; -// } -// -// public synchronized double compute(int X) { // X[i] -// double MAStar_i = MAStar + X + (MAStar / N); -// MA = MAStar_i/N; -// MAStar = MAStar_i; -// return MA; -// } -// -// public double get() { -// return MA; -// } -// } diff --git a/modAionBase/src/org/aion/base/util/NativeLoader.java b/modAionBase/src/org/aion/base/util/NativeLoader.java deleted file mode 100644 index 3e00ed14b4..0000000000 --- a/modAionBase/src/org/aion/base/util/NativeLoader.java +++ /dev/null @@ -1,144 +0,0 @@ -package org.aion.base.util; - -import java.io.File; -import java.io.IOException; -import java.util.Scanner; - -// import java.io.FileNotFoundException; -// import java.io.FileOutputStream; -// import java.io.InputStream; -// import java.io.OutputStream; - -/** - * Native library loader. - * - * @author jin - * @apiNote This functionality is migrated to modUtil. Use that class instead. - */ -@Deprecated -public class NativeLoader { - - /** - * Returns the current OS name. - * - * @return - */ - public static String getOS() { - String osName = System.getProperty("os.name").toLowerCase(); - if (osName.contains("win")) { - return "win"; - } else if (osName.contains("linux")) { - return "linux"; - } else if (osName.contains("mac")) { - return "mac"; - } else { - throw new RuntimeException("Unrecognized OS: " + osName); - } - } - - /** - * Builds a file path given a list of folder names. - * - * @param args - * @return - */ - public static File buildPath(String... args) { - StringBuilder sb = new StringBuilder(); - for (String arg : args) { - sb.append(File.separator); - sb.append(arg); - } - - return sb.length() > 0 ? new File(sb.substring(1)) : new File("."); - } - - /** - * Loads library based on the file list in the given module folder. - * - * @param module - */ - public static void loadLibrary(String module) { - File dir = buildPath("native", getOS(), module); - - try (Scanner s = new Scanner(new File(dir, "file.list"))) { - while (s.hasNextLine()) { - String line = s.nextLine(); - - if (line.startsWith("/") || line.startsWith(".")) { // for debug - // purpose - // mainly - System.load(line); - } else { - System.load(new File(dir, line).getCanonicalPath()); - } - } - } catch (IOException e) { - throw new RuntimeException("Failed to load libraries for " + module, e); - } - } - - // public static void loadLibraryFromJar(@SuppressWarnings("rawtypes") Class clz, String - // path) - // throws IOException { - // - // if (!path.startsWith("/")) { - // throw new IllegalArgumentException("The path has to be absolute (start with - // '/')."); - // } - // - // // Obtain filename from path - // String[] parts = path.split("/"); - // String filename = (parts.length > 1) ? parts[parts.length - 1] : null; - // - // // Split filename to prexif and suffix (extension) - // String prefix = ""; - // String suffix = null; - // if (filename != null) { - // parts = filename.split("\\.", 2); - // prefix = parts[0]; - // suffix = (parts.length > 1) ? "." + parts[parts.length - 1] : null; - // } - // - // // Check if the filename is okay - // if (filename == null || prefix.length() < 3) { - // throw new IllegalArgumentException( - // "The filename has to be at least 3 characters long."); - // } - // - // // Prepare temporary file - // File temp = File.createTempFile(prefix, suffix); - // temp.deleteOnExit(); - // - // if (!temp.exists()) { - // throw new FileNotFoundException("File " + temp.getAbsolutePath() + " does not - // exist."); - // } - // - // // Prepare buffer for data copying - // byte[] buffer = new byte[1024]; - // int readBytes; - // - // // Open and check input stream - // InputStream is = clz.getResourceAsStream(path); - // if (is == null) { - // throw new FileNotFoundException("File " + path + " was not found inside JAR."); - // } - // - // // Open output stream and copy data between source file in JAR and the - // // temporary file - // OutputStream os = new FileOutputStream(temp); - // try { - // while ((readBytes = is.read(buffer)) != -1) { - // os.write(buffer, 0, readBytes); - // } - // } finally { - // // If read/write fails, close streams safely before throwing an - // // exception - // os.close(); - // is.close(); - // } - // - // // Finally, load the library - // System.load(temp.getAbsolutePath()); - // } -} diff --git a/modAionBase/src/org/aion/base/util/TypeConverter.java b/modAionBase/src/org/aion/base/util/TypeConverter.java deleted file mode 100644 index 16e0483023..0000000000 --- a/modAionBase/src/org/aion/base/util/TypeConverter.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.aion.base.util; - -import java.math.BigInteger; - -public class TypeConverter { - - // public static byte[] StringNumberAsBytes(String input) { - // return ByteUtil.bigIntegerToBytes(StringDecimalToBigInteger(input)); - // } - - public static BigInteger StringNumberAsBigInt(String input) { - if (input.startsWith("0x")) { - return TypeConverter.StringHexToBigInteger(input); - } else { - return TypeConverter.StringDecimalToBigInteger(input); - } - } - - public static BigInteger StringHexToBigInteger(String input) { - String hexa = input.startsWith("0x") ? input.substring(2) : input; - return new BigInteger(hexa, 16); - } - - private static BigInteger StringDecimalToBigInteger(String input) { - return new BigInteger(input); - } - - public static byte[] StringHexToByteArray(String x) { - if (x.startsWith("0x")) { - x = x.substring(2); - } - if (x.length() % 2 != 0) { - x = "0" + x; - } - return Hex.decode(x); - } - - public static String toJsonHex(byte[] x) { - return "0x" + Hex.toHexString(x); - } - - public static String toJsonHex(String x) { - return x.startsWith("0x") ? x : "0x" + x; - } - - public static String toJsonHex(long n) { - return "0x" + Long.toHexString(n); - } - - public static String toJsonHex(BigInteger n) { - return "0x" + n.toString(16); - } -} diff --git a/modAionBase/src/org/aion/base/util/Utils.java b/modAionBase/src/org/aion/base/util/Utils.java deleted file mode 100644 index 81cce12e01..0000000000 --- a/modAionBase/src/org/aion/base/util/Utils.java +++ /dev/null @@ -1,328 +0,0 @@ -package org.aion.base.util; - -// import java.lang.reflect.Array; - -import java.math.BigInteger; -import java.security.SecureRandom; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -// import java.util.List; - -public class Utils { - - private static SecureRandom random = new SecureRandom(); - - public static final Object dummy = new Object(); - - /** - * @param number should be in form '0x34fabd34....' - * @return String - */ - // public static BigInteger unifiedNumericToBigInteger(String number) { - // - // boolean match = Pattern.matches("0[xX][0-9a-fA-F]+", number); - // if (!match) { - // return (new BigInteger(number)); - // } else { - // number = number.substring(2); - // number = number.length() % 2 != 0 ? "0".concat(number) : number; - // byte[] numberBytes = Hex.decode(number); - // return (new BigInteger(1, numberBytes)); - // } - // } - - /** - * Return formatted Date String: yyyy.MM.dd HH:mm:ss Based on Unix's time() input in seconds - * - * @param timestamp seconds since start of Unix-time - * @return String formatted as - yyyy.MM.dd HH:mm:ss - */ - public static String longToDateTime(long timestamp) { - Date date = new Date(timestamp * 1000); - DateFormat formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); - return formatter.format(date); - } - - // public static ImageIcon getImageIcon(String resource) { - // URL imageURL = ClassLoader.getSystemResource(resource); - // ImageIcon image = new ImageIcon(imageURL); - // return image; - // } - static BigInteger _1000_ = new BigInteger("1000"); - - public static String getValueShortString(BigInteger number) { - BigInteger result = number; - int pow = 0; - while (result.compareTo(_1000_) == 1 || result.compareTo(_1000_) == 0) { - result = result.divide(_1000_); - pow += 3; - } - return result.toString() + "\u00b7(" + "10^" + pow + ")"; - } - - /** - * Decodes a hex string to address bytes and checks validity - * - * @param hex - a hex string of the address, e.g., 6c386a4b26f73c802f34673f7248bb118f97424a - * @return - decode and validated address byte[] - */ - // public static byte[] addressStringToBytes(String hex) { - // final byte[] addr; - // try { - // addr = Hex.decode(hex); - // } catch (Exception addressIsNotValid) { - // return null; - // } - // - // if (isValidAddress(addr)) { - // return addr; - // } - // return null; - // } - - public static boolean isValidAddress(byte[] addr) { - return addr != null && addr.length == 20; - } - - /** Validate a passed hex string is a valid address */ - public static boolean isValidAddress(String address) { - if (address == null || address.isEmpty() || address.length() < 64) { - return false; - } - - if (address.startsWith("0x")) { - address = address.substring(2); - } - - // Will need to change this for a1, a2.... - if (address.startsWith("a0")) { - return address.length() == 64 && address.substring(2).matches("^[0-9A-Fa-f]+$"); - } else { - return false; - } - } - - /** - * @param addr length should be 20 - * @return short string represent 1f21c... - */ - // public static String getAddressShortString(byte[] addr) { - // - // if (!isValidAddress(addr)) { - // throw new Error("not an address"); - // } - // - // String addrShort = Hex.toHexString(addr, 0, 3); - // - // StringBuffer sb = new StringBuffer(); - // sb.append(addrShort); - // sb.append("..."); - // - // return sb.toString(); - // } - - public static SecureRandom getRandom() { - return random; - } - - public static double JAVA_VERSION = getJavaVersion(); - - static double getJavaVersion() { - String version = System.getProperty("java.version"); - - // on android this property equals to 0 - if (version.equals("0")) { - return 0; - } - - int dpos = 0; - for (; dpos < version.length(); dpos++) { - if (version.charAt(dpos) == '-') { - version = version.substring(0, dpos); - break; - } - } - - if (version.length() == 1) { - return Double.parseDouble(version); - } - - int pos = 0, count = 0; - for (; pos < version.length() && count < 2; pos++) { - if (version.charAt(pos) == '.') { - count++; - } - } - return Double.parseDouble(version.substring(0, pos - 1)); - } - - // public static String getHashListShort(List blockHashes) { - // if (blockHashes.isEmpty()) { - // return "[]"; - // } - // - // StringBuilder sb = new StringBuilder(); - // String firstHash = Hex.toHexString(blockHashes.get(0)); - // String lastHash = Hex.toHexString(blockHashes.get(blockHashes.size() - 1)); - // return sb.append(" ").append(firstHash).append("...").append(lastHash).toString(); - // } - - public static String getNodeIdShort(String nodeId) { - return nodeId == null ? "" : nodeId.substring(0, 8); - } - - // public static long toUnixTime(long javaTime) { - // return javaTime / 1000; - // } - - // public static long fromUnixTime(long unixTime) { - // return unixTime * 1000; - // } - - @SuppressWarnings("unchecked") - // public static T[] mergeArrays(T[]... arr) { - // int size = 0; - // for (T[] ts : arr) { - // size += ts.length; - // } - // T[] ret = (T[]) Array.newInstance(arr[0].getClass().getComponentType(), size); - // int off = 0; - // for (T[] ts : arr) { - // System.arraycopy(ts, 0, ret, off, ts.length); - // off += ts.length; - // } - // return ret; - // } - - public static String align(String s, char fillChar, int targetLen, boolean alignRight) { - if (targetLen <= s.length()) { - return s; - } - String alignString = repeat("" + fillChar, targetLen - s.length()); - return alignRight ? alignString + s : s + alignString; - } - - public static String repeat(String s, int n) { - if (s.length() == 1) { - byte[] bb = new byte[n]; - Arrays.fill(bb, s.getBytes()[0]); - return new String(bb); - } else { - StringBuilder ret = new StringBuilder(); - for (int i = 0; i < n; i++) { - ret.append(s); - } - return ret.toString(); - } - } - - private static final Pattern matchPattern = Pattern.compile("^([0-9]+)([a-zA-Z]+)$"); - public static final long KILO_BYTE = 1024; - public static final long MEGA_BYTE = 1048576; - public static final long GIGA_BYTE = 1073741824; - /** - * Matches file sizes based on fileSize string, in the format: [numericalValue][sizeDescriptor] - * - *

Examples of acceptable formats: - *

  • - * - *
      - * 10b - *
    - * - *
      - * 10B - *
    - * - *
      - * 10K - *
    - * - *
      - * 10KB - *
    - * - *
      - * 10kB - *
    - * - *
      - * 10M - *
    - * - *
      - * 10mB - *
    - * - *
      - * 10MB - *
    - * - *
      - * 10G - *
    - * - *
      - * 10gB - *
    - * - *
      - * 10GB - *
    - * - *

    Commas are not accepted by the parser, and are considered invalid. - * - *

    Note: Anything beyond {@code gigaByte (GB, G, gB)} is not considered valid, and will be - * treated as a parse exception. - * - *

    Note: this function assumes the binary representation of magnitudes, therefore 1kB - * (kiloByte) is not {@code 1000 bytes} but rather {@code 1024 bytes}. - * - * @param fileSize file size string - * @return {@code Optional.of(fileSizeInt)} if we were able to successfully decode the filesize - * string, otherwise outputs {@code Optional.empty()} indicating that we were unable to - * decode the file size string, this usually refers to some sort of syntactic error made by - * the user. - */ - public static Optional parseSize(String fileSize) { - Matcher m = matchPattern.matcher(fileSize); - // if anything does not match - if (!m.find()) { - return Optional.empty(); - } - - String numerical = m.group(1); - String sizeSuffix = m.group(2); - - long size = Integer.parseInt(numerical); - switch (sizeSuffix) { - case "B": - break; - case "K": - case "kB": - case "KB": - // process kiloByte (1024 * byte) here - size = size * KILO_BYTE; - break; - case "M": - case "mB": - case "MB": - size = size * MEGA_BYTE; - break; - case "G": - case "gB": - case "GB": - size = size * GIGA_BYTE; - break; - default: - return Optional.empty(); - } - return Optional.of(size); - } -} diff --git a/modAionBase/src/org/aion/base/vm/IDataWord.java b/modAionBase/src/org/aion/base/vm/IDataWord.java deleted file mode 100644 index 974d461965..0000000000 --- a/modAionBase/src/org/aion/base/vm/IDataWord.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.aion.base.vm; - -import java.math.BigInteger; -import org.aion.base.util.ByteArrayWrapper; - -public interface IDataWord { - - byte[] getData(); - - byte[] getNoLeadZeroesData(); - - BigInteger value(); - - IDataWord copy(); - - boolean isZero(); - - ByteArrayWrapper toWrapper(); -} diff --git a/modAionBase/src/org/aion/base/vm/VirtualMachineSpecs.java b/modAionBase/src/org/aion/base/vm/VirtualMachineSpecs.java deleted file mode 100644 index f53f8d2b4c..0000000000 --- a/modAionBase/src/org/aion/base/vm/VirtualMachineSpecs.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.aion.base.vm; - -public final class VirtualMachineSpecs { - - public static final byte AVM_CREATE_CODE = 0x0f; - public static final byte FVM_ALLOWED_TX_TYPE = 0x00; - public static final byte FVM_DEFAULT_TX_TYPE = 0x01; -} diff --git a/modAionBase/test/org/aion/base/type/AddressTest.java b/modAionBase/test/org/aion/base/type/AddressTest.java deleted file mode 100644 index 7e28a8f900..0000000000 --- a/modAionBase/test/org/aion/base/type/AddressTest.java +++ /dev/null @@ -1,205 +0,0 @@ -package org.aion.base.type; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; -import org.junit.Test; - -public class AddressTest { - - private final String[] addrHex = { - null, // 0 - Null - "", // 1 - Empty - "eE55fF66eE55fF66eE55fF66eE55fF66", // 2 - Short - "aA11bB22cC33dd44aA11bB22cC33dd44aA11bB22cC33dd44aA11bB22cC33dd44", // 3 - Upper/Lower - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", // 4 - Negative (-1) - "0000000000000000000000000000000000000000000000000000000000000000", // 5 - Zeroes - "0000000000000000000000000000000000000000000000000000000000000001", // 6 - Positive (+1) - }; - - private final byte[][] addrByte = { // Changes every time - null, - AionAddress.EMPTY_ADDRESS().toBytes(), - ByteUtil.hexStringToBytes(addrHex[2]), - ByteUtil.hexStringToBytes(addrHex[3]), - ByteUtil.hexStringToBytes(addrHex[4]), - AionAddress.ZERO_ADDRESS().toBytes(), - ByteUtil.hexStringToBytes(addrHex[6]) - }; - - private final ByteArrayWrapper[] addrArray = { // Same as addrHex - null, - new ByteArrayWrapper(new byte[0]), - new ByteArrayWrapper(addrByte[2]), - new ByteArrayWrapper(addrByte[3]), - new ByteArrayWrapper(addrByte[4]), - new ByteArrayWrapper(new byte[32]), - new ByteArrayWrapper(addrByte[6]) - }; - - /** - * Test address wrap function for each input type; String(Hex), Byte, ByteArrayWrapper For each - * input type: 1. Wrap the input data 2. Clone, Convert and Wrap as other input type 3. Assert - * they are all equal - */ - @Test - public void testWrap() { - - AionAddress tempHex; - AionAddress tempByte; - AionAddress tempArray; - - System.out.println("\nHex address test:"); - for (int a = 0; a < addrHex.length; a++) { - try { - tempHex = AionAddress.wrap(addrHex[a]); - tempByte = AionAddress.wrap(tempHex.clone().toBytes()); - tempArray = AionAddress.wrap(tempHex.clone().toByteArrayWrapper()); - - assertTrue(tempHex.equals(tempByte)); - assertTrue(tempByte.equals(tempArray)); - assertTrue(tempArray.equals(tempHex)); - assertEquals(tempHex.toString(), addrHex[a].toLowerCase()); - - System.out.println("Test " + a + ": Valid " + tempHex.toString()); - } catch (IllegalArgumentException e) { - System.out.println("Test " + a + ": Invalid"); - } - } - - System.out.println("\nByte address test:"); - for (int a = 0; a < addrByte.length; a++) { - try { - tempByte = AionAddress.wrap(addrByte[a]); - tempArray = AionAddress.wrap(tempByte.clone().toByteArrayWrapper()); - tempHex = AionAddress.wrap(tempByte.clone().toString()); - - assertTrue(tempByte.equals(tempArray)); - assertTrue(tempArray.equals(tempHex)); - assertTrue(tempHex.equals(tempByte)); - // assertEquals(tempByte.toBytes(), addrByte[a]); - - System.out.println("Test " + a + ": Valid " + tempByte); - } catch (IllegalArgumentException e) { - System.out.println("Test " + a + ": Invalid"); - } - } - - System.out.println("\nArray address test:"); - for (int a = 0; a < addrArray.length; a++) { - try { - tempArray = AionAddress.wrap(addrArray[a]); - tempHex = AionAddress.wrap(tempArray.clone().toString()); - tempByte = AionAddress.wrap(tempArray.clone().toBytes()); - - assertTrue(tempArray.equals(tempHex)); - assertTrue(tempHex.equals(tempByte)); - assertTrue(tempByte.equals(tempArray)); - assertEquals(tempArray.toByteArrayWrapper(), addrArray[a]); - - System.out.println("Test " + a + ": Valid " + tempArray.toByteArrayWrapper()); - } catch (IllegalArgumentException e) { - System.out.println("Test " + a + ": Invalid"); - } - } - } - - /** - * Test address comparison; A compareTo B For each input type: 1. Wrap the two inputs 2. Assert - * (-ve: A < B && +ve: A > B) 3. Increment Up/Down - */ - @Test - public void testCompare() { - - System.out.println("\nHex address test:"); - for (int b = 3; b < 6; b++) { - try { - int temp = AionAddress.wrap(addrHex[b]).compareTo(AionAddress.wrap(addrHex[b + 1])); - boolean same = - AionAddress.wrap(addrHex[b]).equals(AionAddress.wrap(addrHex[b + 1])); - boolean negative = temp < 0; - System.out.println("Test " + b + " & " + (b + 1) + " >> " + temp); - assertFalse(same); - assertTrue(negative); - } catch (IllegalArgumentException e) { - System.out.println("Test " + b + ": Input Invalid"); - } - } - for (int b = 6; b > 3; b--) { - try { - int temp = AionAddress.wrap(addrHex[b]).compareTo(AionAddress.wrap(addrHex[b - 1])); - boolean same = - AionAddress.wrap(addrHex[b]).equals(AionAddress.wrap(addrHex[b - 1])); - boolean positive = temp > 0; - System.out.println("Test " + b + " & " + (b - 1) + " >> " + temp); - assertFalse(same); - assertTrue(positive); - } catch (IllegalArgumentException e) { - System.out.println("Test " + b + ": Input Invalid"); - } - } - - System.out.println("\nByte address test:"); - for (int b = 3; b < 6; b++) { - try { - int temp = AionAddress.wrap(addrByte[b]).compareTo(addrByte[b + 1]); - boolean same = - AionAddress.wrap(addrByte[b]).equals(AionAddress.wrap(addrByte[b + 1])); - boolean negative = temp < 0; - System.out.println("Test " + b + " & " + (b + 1) + " >> " + temp); - assertFalse(same); - assertTrue(negative); - } catch (IllegalArgumentException e) { - System.out.println("Test " + b + ": Input Invalid"); - } - } - for (int b = 6; b > 3; b--) { - try { - int temp = AionAddress.wrap(addrByte[b]).compareTo(addrByte[b - 1]); - boolean same = - AionAddress.wrap(addrByte[b]).equals(AionAddress.wrap(addrByte[b - 1])); - boolean positive = temp > 0; - System.out.println("Test " + b + " & " + (b - 1) + " >> " + temp); - assertFalse(same); - assertTrue(positive); - } catch (IllegalArgumentException e) { - System.out.println("Test " + b + ": Input Invalid"); - } - } - - System.out.println("\nArray address test:"); - for (int b = 3; b < 6; b++) { - try { - int temp = - AionAddress.wrap(addrArray[b]) - .compareTo(AionAddress.wrap(addrArray[b + 1])); - boolean same = - AionAddress.wrap(addrArray[b]).equals(AionAddress.wrap(addrArray[b + 1])); - boolean negative = temp < 0; - System.out.println("Test " + b + " & " + (b + 1) + " >> " + temp); - assertFalse(same); - assertTrue(negative); - } catch (IllegalArgumentException e) { - System.out.println("Test " + b + ": Input Invalid"); - } - } - for (int b = 6; b > 3; b--) { - try { - int temp = - AionAddress.wrap(addrArray[b]) - .compareTo(AionAddress.wrap(addrArray[b - 1])); - boolean same = - AionAddress.wrap(addrArray[b]).equals(AionAddress.wrap(addrArray[b - 1])); - boolean positive = temp > 0; - System.out.println("Test " + b + " & " + (b - 1) + " >> " + temp); - assertFalse(same); - assertTrue(positive); - } catch (IllegalArgumentException e) { - System.out.println("Test " + b + ": Input Invalid"); - } - } - } -} diff --git a/modAionBase/test/org/aion/base/type/Hash256Test.java b/modAionBase/test/org/aion/base/type/Hash256Test.java deleted file mode 100644 index d4acf2d494..0000000000 --- a/modAionBase/test/org/aion/base/type/Hash256Test.java +++ /dev/null @@ -1,195 +0,0 @@ -package org.aion.base.type; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; -import org.junit.Test; - -public class Hash256Test { - - private final String[] hashHex = { - null, // 0 - Null - "", // 1 - Empty - "eE55fF66eE55fF66eE55fF66eE55fF66", // 2 - Short - "aA11bB22cC33dd44aA11bB22cC33dd44aA11bB22cC33dd44aA11bB22cC33dd44", // 3 - Upper/Lower - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", // 4 - Negative (-1) - "0000000000000000000000000000000000000000000000000000000000000000", // 5 - Zeroes - "0000000000000000000000000000000000000000000000000000000000000001", // 6 - Positive (+1) - }; - - private final byte[][] hashByte = { // Changes every time - null, - ByteUtil.hexStringToBytes(hashHex[1]), - ByteUtil.hexStringToBytes(hashHex[2]), - ByteUtil.hexStringToBytes(hashHex[3]), - ByteUtil.hexStringToBytes(hashHex[4]), - Hash256.ZERO_HASH().toBytes(), - ByteUtil.hexStringToBytes(hashHex[6]) - }; - - private final ByteArrayWrapper[] hashArray = { // Same as hashHex - null, - new ByteArrayWrapper(new byte[0]), - new ByteArrayWrapper(hashByte[2]), - new ByteArrayWrapper(hashByte[3]), - new ByteArrayWrapper(hashByte[4]), - new ByteArrayWrapper(new byte[32]), - new ByteArrayWrapper(hashByte[6]) - }; - - /** - * Test hash wrap function for each input type; String(Hex), Byte, ByteArrayWrapper For each - * input type: 1. Wrap the input data 2. Convert and Wrap as other input type 3. Assert they are - * all equal - */ - @Test - public void testWrap() { - - Hash256 tempHex; - Hash256 tempByte; - Hash256 tempArray; - - System.out.println("\nHex hash test:"); - for (int a = 0; a < hashHex.length; a++) { - try { - tempHex = Hash256.wrap(hashHex[a]); - tempByte = Hash256.wrap(tempHex.toBytes()); - tempArray = Hash256.wrap(tempHex.toByteArrayWrapper()); - - assertTrue(tempHex.equals(tempByte)); - assertTrue(tempByte.equals(tempArray)); - assertTrue(tempArray.equals(tempHex)); - assertEquals(tempHex.toString(), hashHex[a].toLowerCase()); - - System.out.println("Test " + a + ": Valid " + tempHex.toString()); - } catch (IllegalArgumentException e) { - System.out.println("Test " + a + ": Invalid"); - } - } - - System.out.println("\nByte hash test:"); - for (int a = 0; a < hashByte.length; a++) { - try { - tempByte = Hash256.wrap(hashByte[a]); - tempArray = Hash256.wrap(tempByte.toByteArrayWrapper()); - tempHex = Hash256.wrap(tempByte.toString()); - - assertTrue(tempByte.equals(tempArray)); - assertTrue(tempArray.equals(tempHex)); - assertTrue(tempHex.equals(tempByte)); - // assertEquals(tempByte.toBytes(), hashByte[a]); - - System.out.println("Test " + a + ": Valid " + tempByte.toBytes()); - } catch (IllegalArgumentException e) { - System.out.println("Test " + a + ": Invalid"); - } - } - - System.out.println("\nArray hash test:"); - for (int a = 0; a < hashArray.length; a++) { - try { - tempArray = Hash256.wrap(hashArray[a]); - tempHex = Hash256.wrap(tempArray.toString()); - tempByte = Hash256.wrap(tempArray.toBytes()); - - assertTrue(tempArray.equals(tempHex)); - assertTrue(tempHex.equals(tempByte)); - assertTrue(tempByte.equals(tempArray)); - assertEquals(tempArray.toByteArrayWrapper(), hashArray[a]); - - System.out.println("Test " + a + ": Valid " + tempArray.toByteArrayWrapper()); - } catch (IllegalArgumentException e) { - System.out.println("Test " + a + ": Invalid"); - } - } - } - - /** - * Test hash comparison; A compareTo B For each input type: 1. Wrap the two inputs 2. Assert - * (-ve: A < B && +ve: A > B) 3. Increment Up/Down - */ - @Test - public void testCompare() { - - System.out.println("\nHex hash test:"); - for (int b = 3; b < 6; b++) { - try { - int temp = Hash256.wrap(hashHex[b]).compareTo(Hash256.wrap(hashHex[b + 1])); - boolean same = Hash256.wrap(hashHex[b]).equals(Hash256.wrap(hashHex[b + 1])); - boolean negative = temp < 0; - System.out.println("Test " + b + " & " + (b + 1) + " >> " + temp); - assertFalse(same); - assertTrue(negative); - } catch (IllegalArgumentException e) { - System.out.println("Test " + b + ": Input Invalid"); - } - } - for (int b = 6; b > 3; b--) { - try { - int temp = Hash256.wrap(hashHex[b]).compareTo(Hash256.wrap(hashHex[b - 1])); - boolean same = Hash256.wrap(hashHex[b]).equals(Hash256.wrap(hashHex[b - 1])); - boolean positive = temp > 0; - System.out.println("Test " + b + " & " + (b - 1) + " >> " + temp); - assertFalse(same); - assertTrue(positive); - } catch (IllegalArgumentException e) { - System.out.println("Test " + b + ": Input Invalid"); - } - } - - System.out.println("\nByte hash test:"); - for (int b = 3; b < 6; b++) { - try { - int temp = Hash256.wrap(hashByte[b]).compareTo(Hash256.wrap(hashByte[b + 1])); - boolean same = Hash256.wrap(hashByte[b]).equals(Hash256.wrap(hashByte[b + 1])); - boolean negative = temp < 0; - System.out.println("Test " + b + " & " + (b + 1) + " >> " + temp); - assertFalse(same); - assertTrue(negative); - } catch (IllegalArgumentException e) { - System.out.println("Test " + b + ": Input Invalid"); - } - } - for (int b = 6; b > 3; b--) { - try { - int temp = Hash256.wrap(hashByte[b]).compareTo(Hash256.wrap(hashByte[b - 1])); - boolean same = Hash256.wrap(hashByte[b]).equals(Hash256.wrap(hashByte[b - 1])); - boolean positive = temp > 0; - System.out.println("Test " + b + " & " + (b - 1) + " >> " + temp); - assertFalse(same); - assertTrue(positive); - } catch (IllegalArgumentException e) { - System.out.println("Test " + b + ": Input Invalid"); - } - } - - System.out.println("\nArray hash test:"); - for (int b = 3; b < 6; b++) { - try { - int temp = Hash256.wrap(hashArray[b]).compareTo(Hash256.wrap(hashArray[b + 1])); - boolean same = Hash256.wrap(hashArray[b]).equals(Hash256.wrap(hashArray[b + 1])); - boolean negative = temp < 0; - System.out.println("Test " + b + " & " + (b + 1) + " >> " + temp); - assertFalse(same); - assertTrue(negative); - } catch (IllegalArgumentException e) { - System.out.println("Test " + b + ": Input Invalid"); - } - } - for (int b = 6; b > 3; b--) { - try { - int temp = Hash256.wrap(hashArray[b]).compareTo(Hash256.wrap(hashArray[b - 1])); - boolean same = Hash256.wrap(hashArray[b]).equals(Hash256.wrap(hashArray[b - 1])); - boolean positive = temp > 0; - System.out.println("Test " + b + " & " + (b - 1) + " >> " + temp); - assertFalse(same); - assertTrue(positive); - } catch (IllegalArgumentException e) { - System.out.println("Test " + b + ": Input Invalid"); - } - } - } -} diff --git a/modAionBase/test/org/aion/base/util/BIUtilTest.java b/modAionBase/test/org/aion/base/util/BIUtilTest.java deleted file mode 100644 index b2628dd668..0000000000 --- a/modAionBase/test/org/aion/base/util/BIUtilTest.java +++ /dev/null @@ -1,166 +0,0 @@ -package org.aion.base.util; - -import static org.aion.base.util.BIUtil.isCovers; -import static org.aion.base.util.BIUtil.isEqual; -import static org.aion.base.util.BIUtil.isLessThan; -import static org.aion.base.util.BIUtil.isMoreThan; -import static org.aion.base.util.BIUtil.isNotCovers; -import static org.aion.base.util.BIUtil.isNotEqual; -import static org.aion.base.util.BIUtil.isPositive; -import static org.aion.base.util.BIUtil.isZero; -import static org.aion.base.util.BIUtil.max; -import static org.aion.base.util.BIUtil.min; -import static org.aion.base.util.BIUtil.sum; -import static org.aion.base.util.BIUtil.toBI; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.math.BigInteger; -import org.junit.Test; - -public class BIUtilTest { - - private final BigInteger[][] bigInt = { - {new BigInteger("-00000000000000000000"), new BigInteger("00000000000000000000")}, - {new BigInteger("-00000000000000000001"), new BigInteger("00000000000000000001")}, - {new BigInteger("-10000000000000000000"), new BigInteger("10000000000000000000")}, - {new BigInteger("-20000000000000000000"), new BigInteger("20000000000000000000")}, - {new BigInteger("-30000000000000000000"), new BigInteger("30000000000000000000")}, - {new BigInteger("-99999999999999999999"), new BigInteger("99999999999999999999")}, - }; - - @Test - public void testIntegrity() { - - // isZero && isPositive - assertTrue(isZero(bigInt[0][0])); - assertTrue(isZero(bigInt[0][1])); - - assertFalse(isPositive(bigInt[0][0])); - assertFalse(isPositive(bigInt[0][1])); - - // isEqual && isNotEqual - assertTrue(isEqual(bigInt[0][0], bigInt[0][1])); - assertFalse(isNotEqual(bigInt[0][0], bigInt[0][1])); - - // isLessThan && isMoreThan - assertFalse(isLessThan(bigInt[0][0], bigInt[0][1])); - assertFalse(isMoreThan(bigInt[0][0], bigInt[0][1])); - - for (int a = 1; a < bigInt.length; a++) { - - assertFalse(isPositive(bigInt[a][0])); - assertTrue(isPositive(bigInt[a][1])); - - assertFalse(isEqual(bigInt[a][0], bigInt[a][1])); - assertTrue(isNotEqual(bigInt[a][0], bigInt[a][1])); - - assertTrue(isLessThan(bigInt[a][0], bigInt[a][1])); - assertFalse(isMoreThan(bigInt[a][0], bigInt[a][1])); - } - - // isCovers && isNotCovers - for (int a = 1; a < bigInt.length; a++) { - assertTrue(isNotCovers(bigInt[a - 1][1], bigInt[a][1])); - } - for (int a = 1; a < bigInt.length; a++) { - assertTrue(isNotCovers(bigInt[a][0], bigInt[a - 1][0])); - } - for (int a = bigInt.length - 1; a > 0; a--) { - assertTrue(isCovers(bigInt[a][1], bigInt[a - 1][1])); - } - - for (int a = bigInt.length - 1; a > 0; a--) { - assertTrue(isCovers(bigInt[a - 1][0], bigInt[a][0])); - } - - // isIn20PercentRange - } - - @Test - public void testType() { - - // toBI(byte), toBI(long) - final long[] testLong = { - 0L, 1L, 1000000000000000000L, 9223372036854775807L, - }; - - final byte[][] testByte = { - ByteUtil.longToBytes(testLong[0]), - ByteUtil.longToBytes(testLong[1]), - ByteUtil.longToBytes(testLong[2]), - ByteUtil.longToBytes(testLong[3]), - }; - - for (int i = 0; i < 4; i++) { - assertEquals(toBI(testLong[i]), toBI(testByte[i])); - } - - // exitLong - } - - @Test - public void testSum() { - - // sum - for (int a = 0; a < bigInt.length; a++) { - assertEquals(new BigInteger("0"), sum(bigInt[a][0], bigInt[a][1])); - } - - for (int b = 0; b < 2; b++) { - for (int a = 0; a < bigInt.length; a++) { - assertEquals(bigInt[a][b], sum(bigInt[0][b], bigInt[a][b])); - } - } - - assertEquals( - new BigInteger("-160000000000000000000"), - sum( - bigInt[0][0], - sum( - bigInt[1][0], - sum( - bigInt[2][0], - sum(bigInt[3][0], sum(bigInt[4][0], bigInt[5][0])))))); - - assertEquals( - new BigInteger("160000000000000000000"), - sum( - bigInt[0][1], - sum( - bigInt[1][1], - sum( - bigInt[2][1], - sum(bigInt[3][1], sum(bigInt[4][1], bigInt[5][1])))))); - } - - @Test - public void testMinMax() { - // min && max - for (int c = 0; c < bigInt.length; c++) { - assertEquals(bigInt[c][0], min(bigInt[c][0], bigInt[c][1])); - assertEquals(bigInt[c][1], max(bigInt[c][0], bigInt[c][1])); - } - - assertEquals( - bigInt[bigInt.length - 1][0], - min( - bigInt[0][0], - min( - bigInt[1][0], - min( - bigInt[2][0], - min(bigInt[3][0], min(bigInt[4][0], bigInt[5][0])))))); - - assertEquals( - bigInt[bigInt.length - 1][1], - max( - bigInt[0][1], - max( - bigInt[1][1], - max( - bigInt[2][1], - max(bigInt[3][1], max(bigInt[4][1], bigInt[5][1])))))); - } -} diff --git a/modAionBase/test/org/aion/base/util/ByteArrayWrapperTest.java b/modAionBase/test/org/aion/base/util/ByteArrayWrapperTest.java deleted file mode 100644 index 6c0c108247..0000000000 --- a/modAionBase/test/org/aion/base/util/ByteArrayWrapperTest.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.aion.base.util; - -import static org.aion.base.util.ByteUtil.hexStringToBytes; -import static org.junit.Assert.assertEquals; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; -import junitparams.JUnitParamsRunner; -import junitparams.Parameters; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(JUnitParamsRunner.class) -public class ByteArrayWrapperTest { - - /** @return input values for {@link #testWrap(String)} */ - @SuppressWarnings("unused") - private Object hexValues() { - - List parameters = new ArrayList<>(); - - parameters.add(""); - parameters.add("eE55fF66eE55fF66eE55fF66eE55fF66"); - parameters.add("aA11bB22cC33dd44aA11bB22cC33dd44aA11bB22cC33dd44aA11bB22cC33dd44"); - parameters.add("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); - parameters.add("0000000000000000000000000000000000000000000000000000000000000000"); - parameters.add("0000000000000000000000000000000000000000000000000000000000000001"); - - return parameters.toArray(); - } - - /** 1. Wrap the input data 2. Assert to see if equal */ - @Test - @Parameters(method = "hexValues") - public void testWrap(String inputString) { - - ByteArrayWrapper tempArray; - byte[] inputByte = hexStringToBytes(inputString); - - try { - tempArray = ByteArrayWrapper.wrap(inputByte); - assertEquals(tempArray.toString(), inputString.toLowerCase()); - assertEquals(tempArray.toBytes(), tempArray.getData()); - System.out.println("Valid " + tempArray); - } catch (NullPointerException e) { - System.out.println("Invalid"); - } - } - - @Test - public void testCollision() { - java.util.HashMap map = new java.util.HashMap<>(); - - for (int i = 0; i < 2000; i++) { - ByteBuffer buffer = ByteBuffer.allocate(20); - buffer.putInt(i); - - map.put(new ByteArrayWrapper(buffer.array()), new Object()); - } - - int cnt1 = 0; - for (ByteArrayWrapper k : map.keySet()) { - if (map.get(k) == null) { - System.out.println("1111 " + k); - cnt1++; - } - } - - int cnt2 = 0; - for (java.util.Map.Entry e : map.entrySet()) { - if (e.getValue() == null) { - System.out.println("2222 " + e); - cnt2++; - } - } - - assertEquals(0, cnt1); - assertEquals(0, cnt2); - } -} diff --git a/modAionBase/test/org/aion/base/util/ByteUtilTest.java b/modAionBase/test/org/aion/base/util/ByteUtilTest.java deleted file mode 100644 index 849a63d422..0000000000 --- a/modAionBase/test/org/aion/base/util/ByteUtilTest.java +++ /dev/null @@ -1,445 +0,0 @@ -package org.aion.base.util; - -import static org.aion.base.util.ByteUtil.and; -import static org.aion.base.util.ByteUtil.appendByte; -import static org.aion.base.util.ByteUtil.bigEndianToShort; -import static org.aion.base.util.ByteUtil.bigIntegerToBytes; -import static org.aion.base.util.ByteUtil.bigIntegerToBytesSigned; -import static org.aion.base.util.ByteUtil.byteArrayToInt; -import static org.aion.base.util.ByteUtil.byteArrayToLong; -import static org.aion.base.util.ByteUtil.bytesToBigInteger; -import static org.aion.base.util.ByteUtil.copyToArray; -import static org.aion.base.util.ByteUtil.encodeValFor32Bits; -import static org.aion.base.util.ByteUtil.firstNonZeroByte; -import static org.aion.base.util.ByteUtil.getBit; -import static org.aion.base.util.ByteUtil.hexStringToBytes; -import static org.aion.base.util.ByteUtil.increment; -import static org.aion.base.util.ByteUtil.intToBytes; -import static org.aion.base.util.ByteUtil.intToBytesBE; -import static org.aion.base.util.ByteUtil.intToBytesLE; -import static org.aion.base.util.ByteUtil.intToBytesNoLeadZeroes; -import static org.aion.base.util.ByteUtil.isNullOrZeroArray; -import static org.aion.base.util.ByteUtil.isSingleZero; -import static org.aion.base.util.ByteUtil.length; -import static org.aion.base.util.ByteUtil.longToBytes; -import static org.aion.base.util.ByteUtil.longToBytesLE; -import static org.aion.base.util.ByteUtil.longToBytesNoLeadZeroes; -import static org.aion.base.util.ByteUtil.numBytes; -import static org.aion.base.util.ByteUtil.oneByteToHexString; -import static org.aion.base.util.ByteUtil.or; -import static org.aion.base.util.ByteUtil.setBit; -import static org.aion.base.util.ByteUtil.shortToBytes; -import static org.aion.base.util.ByteUtil.stripLeadingZeroes; -import static org.aion.base.util.ByteUtil.toByte; -import static org.aion.base.util.ByteUtil.toHexString; -import static org.aion.base.util.ByteUtil.toHexStringWithPrefix; -import static org.aion.base.util.ByteUtil.toLEByteArray; -import static org.aion.base.util.ByteUtil.xor; -import static org.aion.base.util.ByteUtil.xorAlignRight; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; -import junitparams.JUnitParamsRunner; -import junitparams.Parameters; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(JUnitParamsRunner.class) -public class ByteUtilTest { - - private static final Random random = new Random(); - - private final String[] testHex = { - null, // 0 - Null - "", // 1 - Empty - "eF", // 2 - One Byte - "aA11bB22cC33dd44aA11bB22cC33dd44aA11bB22cC33dd44aA11bB22cC33dd44", // 3 - Upper/Lower - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", // 4 - Negative (-1) - "0000000000000000000000000000000000000000000000000000000000000000", // 5 - Zeroes - "0000000000000000000000000000000000000000000000000000000000000001", // 6 - Positive (+1) - }; // 1byte - - private final byte[][] testByte = { - null, - hexStringToBytes(testHex[1]), - hexStringToBytes(testHex[2]), - hexStringToBytes(testHex[3]), - hexStringToBytes(testHex[4]), - hexStringToBytes(testHex[5]), - hexStringToBytes(testHex[6]), - }; - - private final String[][] testNum = { - {null, null}, - {"-00000000000000000000", "00000000000000000000"}, - {"-00000000000000000001", "00000000000000000001"}, - {"-10000000000000000000", "10000000000000000000"}, - {"-20000000000000000000", "20000000000000000000"}, - {"-30000000000000000000", "30000000000000000000"}, - {"-99999999999999999999", "99999999999999999999"}, - }; - - private final BigInteger[][] testBigInt = { - {null, null}, - {new BigInteger(testNum[1][0]), new BigInteger(testNum[1][1])}, - {new BigInteger(testNum[2][0]), new BigInteger(testNum[2][1])}, - {new BigInteger(testNum[3][0]), new BigInteger(testNum[3][1])}, - {new BigInteger(testNum[4][0]), new BigInteger(testNum[4][1])}, - {new BigInteger(testNum[5][0]), new BigInteger(testNum[5][1])}, - {new BigInteger(testNum[6][0]), new BigInteger(testNum[6][1])}, - }; - - /** @return input values for {@link #longTest(long)} */ - @SuppressWarnings("unused") - private Object longValues() { - - List parameters = new ArrayList<>(); - - // longs similar to integer values - parameters.add(0L); - parameters.add(1L); - parameters.add(10L); - parameters.add((long) random.nextInt(Integer.MAX_VALUE)); - parameters.add((long) Integer.MAX_VALUE); - - // additional long values - parameters.add((long) Integer.MAX_VALUE + random.nextInt(Integer.MAX_VALUE)); - parameters.add(10L * (long) Integer.MAX_VALUE); - parameters.add(Long.MAX_VALUE - 1L); - - return parameters.toArray(); - } - - /** @return input values for {@link #intTest(int)} */ - @SuppressWarnings("unused") - private Object intValues() { - - List parameters = new ArrayList<>(); - - // integer values - parameters.add(0); - parameters.add(1); - parameters.add(10); - parameters.add(15); - parameters.add(20); - parameters.add(random.nextInt(Integer.MAX_VALUE)); - parameters.add(Integer.MAX_VALUE); - - return parameters.toArray(); - } - - /** @return input values for {@link #shortTest(short)} */ - @SuppressWarnings("unused") - private Object shortValues() { - - Short[] temp = { - 0, 1, 10, 15, 20, (short) random.nextInt(Integer.MAX_VALUE), (short) Integer.MAX_VALUE - }; - - return temp; - } - - /** - * TEST: BI <--> Bytes (+ve) bigIntegerToBytes(BI) bigIntegerToBytes(BI, num) - * bigIntegerToBytesSigned(BI, num) bytesToBigInteger(byte) {@link #intValues()}. - */ - @Test - public void bigIntegerTest() { - for (int b = 1; b < 2; b++) { - for (int a = 0; a < testBigInt.length; a++) { - try { - byte[] temp1 = bigIntegerToBytes(testBigInt[a][b]); - byte[] temp2 = bigIntegerToBytes(testBigInt[a][b], temp1.length); - byte[] temp3 = bigIntegerToBytesSigned(testBigInt[a][b], temp1.length); - byte[] temp4 = encodeValFor32Bits(testNum[a][b]); - - assertEquals(testBigInt[a][b], bytesToBigInteger(temp1)); - assertEquals(testBigInt[a][b], bytesToBigInteger(temp2)); - assertEquals(testBigInt[a][b], bytesToBigInteger(temp3)); - assertEquals(bytesToBigInteger(temp1), bytesToBigInteger(temp4)); - } catch (NullPointerException e) { - System.out.println(b + " " + a); - System.out.println("\nNull Big Integer Test!"); - } - } - } - } - - // TODO: Object --> Bytes - // encodeValFor32Bits(Object) - // encodeDataList(Object) - @Test - public void objectTest() { - for (int a = 0; a < testNum.length; a++) { - try { - byte[] temp1 = encodeValFor32Bits(testNum[a][1]); - } catch (NullPointerException e) { - System.out.println("\nNull Object Test!"); - } - } - } - - /** TEST: hex <--> Bytes hexStringToBytes(hex) toHexString(byte) toHexStringWithPrefix(byte) */ - @Test - public void hexTest() { - byte[] temp0 = hexStringToBytes(testHex[0]); - assertEquals("", toHexString(temp0)); - assertEquals("0x", toHexStringWithPrefix(temp0)); - - for (int a = 1; a < testHex.length; a++) { - byte[] temp1 = hexStringToBytes(testHex[a]); - assertEquals(testHex[a].toLowerCase(), toHexString(temp1)); - assertEquals("0x" + testHex[a].toLowerCase(), toHexStringWithPrefix(temp1)); - } - } - - /** - * TEST: long <--> Bytes longToBytes(long) longToBytesNoLeadZeroes(long) byteArrayToLong(byte) - * longToBytesLE(long) - */ - @Test - @Parameters(method = "longValues") - public void longTest(long testLong) { - - byte[] temp1 = longToBytes(testLong); - byte[] temp2 = longToBytesNoLeadZeroes(testLong); - byte[] temp3 = longToBytesLE(testLong); - - toLEByteArray(temp3); - - assertEquals(testLong, byteArrayToLong(temp1)); - assertEquals(testLong, byteArrayToLong(temp2)); - assertEquals(testLong, byteArrayToLong(temp3)); - } - - /** - * TEST: short <--> Bytes shortToBytes(short) bigEndianToShort(byte) ~ bigEndianToShort(byte, - * offset) - */ - @Test - @Parameters(method = "shortValues") - public void shortTest(short testShort) { - byte[] temp1 = shortToBytes(testShort); - assertEquals(testShort, bigEndianToShort(temp1)); - } - - /** - * TEST: int <--> Bytes intToBytes(int) intToBytesLE(int) intToBytesBE(int) - * intToBytesNoLeadZeroes(int) byteArrayToInt(byte) ~ intsToBytes(array, BE) ~ - * intsToBytes(array, byte, BE) ~ bytesToInts(byte, BE) ~ bytesToInts(byte, array, BE) - */ - @Test - @Parameters(method = "intValues") - public void intTest(int testInt) { - - byte[] temp1 = intToBytes(testInt); - byte[] temp2 = intToBytesLE(testInt); - byte[] temp3 = intToBytesBE(testInt); - byte[] temp4 = intToBytesNoLeadZeroes(testInt); - - toLEByteArray(temp2); - - assertEquals(testInt, byteArrayToInt(temp1)); - assertEquals(testInt, byteArrayToInt(temp2)); - assertEquals(testInt, byteArrayToInt(temp3)); - assertEquals(testInt, byteArrayToInt(temp4)); - } - - /** - * TEST: Byte validation toByte(byte) toLEByteArray(byte) firstNonZeroByte(byte) numBytes(hex) - * isNullOrZeroArray(byte) isSingleZero(byte) length(byte) stripLeadingZeroes(byte) - * appendByte(byte1, byte2) oneByteToHexString(byte) ~ matchingNibbleLength(byte1, byte2) ~ - * nibblesToPrettyString(byte) ~ difference(byteSet1, byteSet2) - */ - @Test - public void byteTest() { - - // Single 'zero' byte - String singleZero = "0"; - byte[] temp = bigIntegerToBytes(new BigInteger(singleZero)); - assertEquals(-1, firstNonZeroByte(temp)); - assertEquals(1, numBytes(singleZero)); - assertEquals(1, length(temp)); - assertFalse(isNullOrZeroArray(temp)); - assertTrue(isSingleZero(temp)); - - // Null Variable - byte[] temp0 = bigIntegerToBytes(new BigInteger(singleZero)); - assertEquals(-1, firstNonZeroByte(temp0)); - assertTrue(isNullOrZeroArray(testByte[0])); - assertNull(stripLeadingZeroes(testByte[0])); - - // Empty Array - byte[] temp1 = stripLeadingZeroes(testByte[1]); - assertEquals(-1, firstNonZeroByte(temp1)); - assertEquals(-1, firstNonZeroByte(testByte[1])); - assertTrue(isNullOrZeroArray(testByte[1])); - - // Leading Non-zero - byte[] temp2 = stripLeadingZeroes(testByte[2]); - assertEquals(0, firstNonZeroByte(temp2)); - assertEquals(0, firstNonZeroByte(testByte[2])); - assertEquals(0, firstNonZeroByte(testByte[3])); - assertEquals(0, firstNonZeroByte(testByte[4])); - - // Only Zeroes - assertEquals(-1, firstNonZeroByte(testByte[5])); - assertFalse(isNullOrZeroArray(testByte[5])); - assertFalse(isSingleZero(testByte[5])); - - // Leading Zeroes - byte[] temp3 = stripLeadingZeroes(testByte[6]); - assertEquals(0, firstNonZeroByte(temp3)); - assertEquals(31, firstNonZeroByte(testByte[6])); - - // n Byte = { 2n Hex || (256^n) - 1 } - assertEquals(1, numBytes("255")); - assertEquals(2, numBytes("65535")); - assertEquals(3, numBytes("16777215")); - assertEquals(4, numBytes("4294967295")); - assertEquals(5, numBytes("1099511627775")); - - // TFAE (+ve); - // 1) numBytes(number) - // 2) bigInt.length - // 3) hex.length()/2 - for (int a = 1; a < testBigInt.length; a++) { - byte[] temp4 = bigIntegerToBytes(testBigInt[a][1]); - String temp5 = toHexString(temp4); - assertEquals(temp5.length() / 2, temp4.length); - assertEquals(temp5.length() / 2, numBytes(testNum[a][1])); - } - - // Append - for (int a = 0; a < testHex.length; a++) { - byte[] temp6 = hexStringToBytes(testHex[a]); - byte temp7 = toByte(testByte[2]); - byte[] temp8 = appendByte(temp6, temp7); - String temp9 = oneByteToHexString(temp7); - assertEquals(testHex[2].toLowerCase(), temp9); - assertEquals(toHexString(temp6) + temp9, toHexString(temp8)); - } - } - - /** - * TEST: Bit manipulation increment(byte) copyToArray(byte) setBit(byte, pos, val) getBit(byte, - * pos) and(byte1, byte2) or(byte1, byte2) xor(byte1, byte2) xorAlignRight(byte1, byte2) - */ - @Test - public void bitTest() { - - // Increment for all byte size (+ve) - int increment = 123; - boolean max = false; - for (int a = 1; a < testBigInt.length; a++) { - - BigInteger temp1 = testBigInt[a][1]; - byte[] temp2 = bigIntegerToBytes(temp1); - BigInteger capacity = BigInteger.valueOf((long) Math.pow(255, temp2.length)); - - for (int i = 0; i < increment; i++) { - while (!max) { - max = increment(temp2); - } - temp1 = bytesToBigInteger(temp2); - max = false; - } - - BigInteger temp3 = BigInteger.valueOf(increment).mod(capacity); - BigInteger temp4 = testBigInt[a][1].add(temp3); - assertEquals(temp4, temp1); - } - - // Copy array, convert and assert (+ve) - for (int a = 1; a < testBigInt.length; a++) { - byte[] temp5 = copyToArray(testBigInt[a][1]); - BigInteger temp6 = bytesToBigInteger(temp5); - assertEquals(testBigInt[a][1], temp6); - } - - // Set bit, get bit for every bit - int shifts = 8; - for (int c = 0; c < shifts; c++) { - byte[] temp6 = bigIntegerToBytesSigned(testBigInt[1][1], 1); - setBit(temp6, c, 1); - assertEquals(1, getBit(temp6, c)); - assertEquals(BigInteger.valueOf((long) Math.pow(2, c)), bytesToBigInteger(temp6)); - } - - // AND + OR with zero (+ve) - for (int a = 2; a < testBigInt.length; a++) { - byte[] temp8 = bigIntegerToBytes(testBigInt[a][1]); - byte[] temp9 = bigIntegerToBytes(testBigInt[1][1], temp8.length); - byte[] temp10 = or(temp8, temp9); - byte[] temp11 = and(temp8, temp9); - assertEquals(testBigInt[a][1], bytesToBigInteger(temp10)); - assertEquals(testBigInt[1][1], bytesToBigInteger(temp11)); - System.out.println( - testBigInt[a][1] - + " || " - + testBigInt[1][1] - + " --> " - + bytesToBigInteger(temp10)); - System.out.println( - testBigInt[a][1] - + " && " - + testBigInt[1][1] - + " --> " - + bytesToBigInteger(temp11)); - } - - // 2's compliment -ve BI --> +ve BI - for (int a = 1; a < testBigInt.length; a++) { - boolean found = false; - int rightMost = 0; - byte[] temp7 = bigIntegerToBytes(testBigInt[a][0]); - while (!found && rightMost < temp7.length * 8) { - if (getBit(temp7, rightMost) == 1) { - found = true; - } else { - rightMost++; - } - } - if (found) { - for (int b = rightMost + 1; b < temp7.length * 8; b++) { - if (getBit(temp7, b) == 0) { - setBit(temp7, b, 1); - } else if (getBit(temp7, b) == 1) { - setBit(temp7, b, 0); - } - } - } - assertEquals(testBigInt[a][1], bytesToBigInteger(temp7)); - System.out.println(testBigInt[a][0] + " --> " + bytesToBigInteger(temp7)); - } - - // 1's compliment | XOR with "FF" * numBytes - for (int b = 0; b < 2; b++) { - for (int a = 1; a < testBigInt.length; a++) { - byte[] temp12 = bigIntegerToBytes(testBigInt[a][b]); - StringBuilder allForOne = new StringBuilder(); - for (int i = 0; i < temp12.length; i++) { - allForOne.append("FF"); - } - byte[] temp13 = hexStringToBytes(allForOne.toString()); - byte[] temp14 = xor(temp13, temp12); - byte[] temp15 = xorAlignRight(temp13, temp12); - for (int c = 0; c < temp12.length * 8; c++) { - if (getBit(temp12, c) == 0) { - setBit(temp12, c, 1); - } else if (getBit(temp12, c) == 1) { - setBit(temp12, c, 0); - } - } - assertEquals(bytesToBigInteger(temp14), bytesToBigInteger(temp12)); - assertEquals(bytesToBigInteger(temp15), bytesToBigInteger(temp12)); - } - } - } -} diff --git a/modAionImpl/build.gradle b/modAionImpl/build.gradle index 9abcd6b352..35d4e535bf 100644 --- a/modAionImpl/build.gradle +++ b/modAionImpl/build.gradle @@ -11,12 +11,14 @@ sourceSets { } dependencies { - compile project(':modAionBase') + compile project(':aion_vm_api') + compile 'network.aion:util4j:0.4.0' + compile 'network.aion:log4j:0.4.0' + compile 'network.aion:rlp4j:0.4.0' + compile 'network.aion:crypto4j:0.4.0' + compile project(':modAion') - compile project(':modRlp') - compile project(':modCrypto') compile project(':modMcf') - compile project(':modLogger') compile project(':modP2pImpl') compile project(':modP2p') compile project(':modEvtMgr') @@ -24,20 +26,23 @@ dependencies { compile project(':modVM') compile project(':modTxPool') compile project(':aion_fastvm') - compile files('../lib/org-aion-avm-rt.jar') - //compile files('../lib/libJson.jar') compile 'org.json:json:20180813' compile 'info.picocli:picocli:3.6.1' testCompile project(path: ':modTxPoolImpl') testCompile project(path: ':modDbImpl', configuration: 'testClassesOut') - compile group: 'org.ow2.asm', name: 'asm', version: '6.2.1' - compile group: 'org.ow2.asm', name: 'asm-analysis', version: '6.2.1' - compile group: 'org.ow2.asm', name: 'asm-commons', version: '6.2.1' - compile group: 'org.ow2.asm', name: 'asm-tree', version: '6.2.1' - compile group: 'org.ow2.asm', name: 'asm-util', version: '6.2.1' + // compile group: 'org.ow2.asm', name: 'asm', version: '6.2.1' + // compile group: 'org.ow2.asm', name: 'asm-analysis', version: '6.2.1' + // compile group: 'org.ow2.asm', name: 'asm-commons', version: '6.2.1' + // compile group: 'org.ow2.asm', name: 'asm-tree', version: '6.2.1' + // compile group: 'org.ow2.asm', name: 'asm-util', version: '6.2.1' + + testCompile files('../lib/org-aion-avm-rt.jar') + testCompile files('../lib/org-aion-avm-api.jar') + testCompile files('../lib/org-aion-avm-userlib.jar') + testCompile 'network.aion:crypto4j:0.4.0' testCompile 'junit:junit:4.12' testCompile 'pl.pragmatists:JUnitParams:1.1.1' testCompile 'org.hamcrest:hamcrest-all:1.3' diff --git a/modAionImpl/hs_err_pid25106.log b/modAionImpl/hs_err_pid25106.log deleted file mode 100644 index 073edaaa46..0000000000 --- a/modAionImpl/hs_err_pid25106.log +++ /dev/null @@ -1,2402 +0,0 @@ -# -# There is insufficient memory for the Java Runtime Environment to continue. -# Native memory allocation (mmap) failed to map 1207959552 bytes for committing reserved memory. -# Possible reasons: -# The system is out of physical RAM or swap space -# The process is running with CompressedOops enabled, and the Java Heap may be blocking the growth of the native heap -# Possible solutions: -# Reduce memory load on the system -# Increase physical memory or swap space -# Check if swap backing store is full -# Decrease Java heap size (-Xmx/-Xms) -# Decrease number of Java threads -# Decrease Java thread stack sizes (-Xss) -# Set larger code cache with -XX:ReservedCodeCacheSize= -# JVM is running with Zero Based Compressed Oops mode in which the Java heap is -# placed in the first 32GB address space. The Java Heap base address is the -# maximum limit for the native heap growth. Please use -XX:HeapBaseMinAddress -# to set the Java Heap base and to place the Java Heap above 32GB virtual address. -# This output file may be truncated or incomplete. -# -# Out of Memory Error (os_linux.cpp:2709), pid=25106, tid=25115 -# -# JRE version: OpenJDK Runtime Environment (11.0.1+13) (build 11.0.1+13) -# Java VM: OpenJDK 64-Bit Server VM (11.0.1+13, mixed mode, tiered, compressed oops, g1 gc, linux-amd64) -# Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport %p %s %c %d %P" (or dumping to /home/jay/workspace/aion/modAionImpl/core.25106) -# - ---------------- S U M M A R Y ------------ - -Command Line: -Dorg.gradle.native=false -Dfile.encoding=UTF-8 -Duser.country=CA -Duser.language=en -Duser.variant -ea worker.org.gradle.process.internal.worker.GradleWorkerMain 'Gradle Test Executor 9' - -Host: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, 12 cores, 15G, Ubuntu 18.04.1 LTS -Time: Thu Jan 10 17:35:26 2019 EST elapsed time: 114 seconds (0d 0h 1m 54s) - ---------------- T H R E A D --------------- - -Current thread (0x00007fd22c208000): VMThread "VM Thread" [stack: 0x00007fd2042e0000,0x00007fd2043e0000] [id=25115] - -Stack: [0x00007fd2042e0000,0x00007fd2043e0000], sp=0x00007fd2043de040, free space=1016k -Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code) -V [libjvm.so+0xe57157] VMError::report_and_die(int, char const*, char const*, __va_list_tag*, Thread*, unsigned char*, void*, void*, char const*, int, unsigned long)+0x2c7 -V [libjvm.so+0xe57dab] VMError::report_and_die(Thread*, char const*, int, unsigned long, VMErrorType, char const*, __va_list_tag*)+0x2b -V [libjvm.so+0x6ca415] report_vm_out_of_memory(char const*, int, unsigned long, VMErrorType, char const*, ...)+0xd5 -V [libjvm.so+0xc32c08] os::pd_commit_memory_or_exit(char*, unsigned long, unsigned long, bool, char const*)+0x108 -V [libjvm.so+0xc2a63d] os::commit_memory_or_exit(char*, unsigned long, unsigned long, bool, char const*)+0x1d -V [libjvm.so+0x7ddeef] G1PageBasedVirtualSpace::commit_preferred_pages(unsigned long, unsigned long)+0x5f -V [libjvm.so+0x7de15e] G1PageBasedVirtualSpace::commit(unsigned long, unsigned long)+0x5e -V [libjvm.so+0x7e9f30] G1RegionsLargerThanCommitSizeMapper::commit_regions(unsigned int, unsigned long, WorkGang*)+0x40 -V [libjvm.so+0x865589] HeapRegionManager::commit_regions(unsigned int, unsigned long, WorkGang*)+0x89 -V [libjvm.so+0x8661df] HeapRegionManager::make_regions_available(unsigned int, unsigned int, WorkGang*)+0x3f -V [libjvm.so+0x866669] HeapRegionManager::expand_at(unsigned int, unsigned int, WorkGang*) [clone .part.44]+0x119 -V [libjvm.so+0x7a2d0f] G1CollectedHeap::expand(unsigned long, WorkGang*, double*)+0xdf -V [libjvm.so+0x7a7a0a] G1CollectedHeap::do_collection_pause_at_safepoint(double)+0x9ea -V [libjvm.so+0xe6adc1] VM_G1CollectForAllocation::doit()+0x81 -V [libjvm.so+0xe699b8] VM_Operation::evaluate()+0xd8 -V [libjvm.so+0xe671ef] VMThread::evaluate_operation(VM_Operation*) [clone .constprop.54]+0xff -V [libjvm.so+0xe676fe] VMThread::loop()+0x3be -V [libjvm.so+0xe67b2b] VMThread::run()+0x7b -V [libjvm.so+0xc38880] thread_native_entry(Thread*)+0xf0 - -VM_Operation (0x00007fd1fc5f7270): G1CollectForAllocation, mode: safepoint, requested by thread 0x00007fd22c799000 - - ---------------- P R O C E S S --------------- - -Threads class SMR info: -_java_thread_list=0x00007fd1d438c950, length=118, elements={ -0x00007fd22c014000, 0x00007fd22c210000, 0x00007fd22c214000, 0x00007fd22c227000, -0x00007fd22c229000, 0x00007fd22c22b000, 0x00007fd22c22d000, 0x00007fd22c2bb800, -0x00007fd22c2cf800, 0x00007fd22c799000, 0x00007fd22c7ae000, 0x00007fd22c7ae800, -0x00007fd1bdea3000, 0x00007fd1bc447000, 0x00007fd17c001000, 0x00007fd180004800, -0x00007fd1bc52c000, 0x00007fd174001000, 0x00007fd16c001000, 0x00007fd180006800, -0x00007fd17c003000, 0x00007fd16c003800, 0x00007fd174003000, 0x00007fd1bc52b800, -0x00007fd1bc2f1800, 0x00007fd1bc30f000, 0x00007fd1bc411800, 0x00007fd1bc4f2000, -0x00007fd1bc515000, 0x00007fd1bc531800, 0x00007fd1bc57b000, 0x00007fd1bc44e800, -0x00007fd1bc450000, 0x00007fd1bc451000, 0x00007fd1380b8800, 0x00007fd1380ba000, -0x00007fd1380bc000, 0x00007fd1380bd800, 0x00007fd138027000, 0x00007fd138021800, -0x00007fd1380c2000, 0x00007fd1380c4000, 0x00007fd1380d0800, 0x00007fd1380d2000, -0x00007fd1380e1800, 0x00007fd1380dd000, 0x00007fd1380df000, 0x00007fd1380e6800, -0x00007fd1380e8800, 0x00007fd1380ea000, 0x00007fd1380ec000, 0x00007fd1380ee000, -0x00007fd1380f0000, 0x00007fd1380f2000, 0x00007fd1380f4000, 0x00007fd1380f6000, -0x00007fd1380f8000, 0x00007fd1380fa000, 0x00007fd1380fc000, 0x00007fd1380fe000, -0x00007fd138100800, 0x00007fd138102800, 0x00007fd138104800, 0x00007fd138106800, -0x00007fd138108800, 0x00007fd13810a800, 0x00007fd13810c800, 0x00007fd13810e800, -0x00007fd138110800, 0x00007fd138112000, 0x00007fd138114000, 0x00007fd138116000, -0x00007fd138118000, 0x00007fd13811a000, 0x00007fd13811c000, 0x00007fd13811e800, -0x00007fd138120800, 0x00007fd138122800, 0x00007fd138124800, 0x00007fd138126800, -0x00007fd138128800, 0x00007fd13812a800, 0x00007fd13812c800, 0x00007fd13812e800, -0x00007fd138130800, 0x00007fd138132800, 0x00007fd138134800, 0x00007fd138136800, -0x00007fd138138800, 0x00007fd13813a800, 0x00007fd13813c800, 0x00007fd13813e800, -0x00007fd138140800, 0x00007fd138142800, 0x00007fd138144800, 0x00007fd138146800, -0x00007fd138148800, 0x00007fd13814a800, 0x00007fd13814c800, 0x00007fd13814e800, -0x00007fd138150800, 0x00007fd138152800, 0x00007fd138154800, 0x00007fd138156800, -0x00007fd138158800, 0x00007fd13815a800, 0x00007fd13815c800, 0x00007fd13815e000, -0x00007fd138160000, 0x00007fd138162000, 0x00007fd138164000, 0x00007fd138166000, -0x00007fd138171000, 0x00007fd1d0003000, 0x00007fd1d4312000, 0x00007fd1bc0b2800, -0x00007fd1d438a800, 0x00007fd1d438c000 -} - -Java Threads: ( => current thread ) - 0x00007fd22c014000 JavaThread "main" [_thread_blocked, id=25108, stack(0x00007fd23036e000,0x00007fd23046f000)] - 0x00007fd22c210000 JavaThread "Reference Handler" daemon [_thread_blocked, id=25116, stack(0x00007fd2041dd000,0x00007fd2042de000)] - 0x00007fd22c214000 JavaThread "Finalizer" daemon [_thread_blocked, id=25117, stack(0x00007fd2040dc000,0x00007fd2041dd000)] - 0x00007fd22c227000 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=25118, stack(0x00007fd1fd52e000,0x00007fd1fd62f000)] - 0x00007fd22c229000 JavaThread "C2 CompilerThread0" daemon [_thread_blocked, id=25119, stack(0x00007fd1fd42d000,0x00007fd1fd52e000)] - 0x00007fd22c22b000 JavaThread "C1 CompilerThread0" daemon [_thread_blocked, id=25120, stack(0x00007fd1fd32c000,0x00007fd1fd42d000)] - 0x00007fd22c22d000 JavaThread "Sweeper thread" daemon [_thread_blocked, id=25121, stack(0x00007fd1fd22b000,0x00007fd1fd32c000)] - 0x00007fd22c2bb800 JavaThread "Service Thread" daemon [_thread_blocked, id=25122, stack(0x00007fd1fd12a000,0x00007fd1fd22b000)] - 0x00007fd22c2cf800 JavaThread "Common-Cleaner" daemon [_thread_blocked, id=25124, stack(0x00007fd1fcf27000,0x00007fd1fd028000)] - 0x00007fd22c799000 JavaThread "Test worker" [_thread_blocked, id=25130, stack(0x00007fd1fc4fa000,0x00007fd1fc5fb000)] - 0x00007fd22c7ae000 JavaThread "/0:0:0:0:0:0:0:1:33174 to /0:0:0:0:0:0:0:1:36991 workers Thread 2" [_thread_blocked, id=25131, stack(0x00007fd1fc3f9000,0x00007fd1fc4fa000)] - 0x00007fd22c7ae800 JavaThread "/0:0:0:0:0:0:0:1:33174 to /0:0:0:0:0:0:0:1:36991 workers Thread 3" [_thread_in_native, id=25132, stack(0x00007fd1fc2f8000,0x00007fd1fc3f9000)] - 0x00007fd1bdea3000 JavaThread "ForkJoinPool.commonPool-worker-19" daemon [_thread_blocked, id=25210, stack(0x00007fd1baf76000,0x00007fd1bb077000)] - 0x00007fd1bc447000 JavaThread "ForkJoinPool.commonPool-worker-5" daemon [_thread_blocked, id=25211, stack(0x00007fd1b8d4e000,0x00007fd1b8e4f000)] - 0x00007fd17c001000 JavaThread "ForkJoinPool.commonPool-worker-23" daemon [_thread_blocked, id=25212, stack(0x00007fd1b8c4d000,0x00007fd1b8d4e000)] - 0x00007fd180004800 JavaThread "ForkJoinPool.commonPool-worker-9" daemon [_thread_blocked, id=25213, stack(0x00007fd1b8b4c000,0x00007fd1b8c4d000)] - 0x00007fd1bc52c000 JavaThread "ForkJoinPool.commonPool-worker-27" daemon [_thread_blocked, id=25214, stack(0x00007fd1b8a4b000,0x00007fd1b8b4c000)] - 0x00007fd174001000 JavaThread "ForkJoinPool.commonPool-worker-13" daemon [_thread_blocked, id=25215, stack(0x00007fd1b894a000,0x00007fd1b8a4b000)] - 0x00007fd16c001000 JavaThread "ForkJoinPool.commonPool-worker-3" daemon [_thread_blocked, id=25216, stack(0x00007fd1b8849000,0x00007fd1b894a000)] - 0x00007fd180006800 JavaThread "ForkJoinPool.commonPool-worker-17" daemon [_thread_blocked, id=25218, stack(0x00007fd1b8748000,0x00007fd1b8849000)] - 0x00007fd17c003000 JavaThread "ForkJoinPool.commonPool-worker-31" daemon [_thread_blocked, id=25219, stack(0x00007fd1b8647000,0x00007fd1b8748000)] - 0x00007fd16c003800 JavaThread "ForkJoinPool.commonPool-worker-7" daemon [_thread_blocked, id=25221, stack(0x00007fd1b8445000,0x00007fd1b8546000)] - 0x00007fd174003000 JavaThread "ForkJoinPool.commonPool-worker-21" daemon [_thread_blocked, id=25222, stack(0x00007fd1b8344000,0x00007fd1b8445000)] - 0x00007fd1bc52b800 JavaThread "pool-1-thread-1" [_thread_blocked, id=25241, stack(0x00007fd1b8142000,0x00007fd1b8243000)] - 0x00007fd1bc2f1800 JavaThread "process reaper" daemon [_thread_blocked, id=25243, stack(0x00007fd210022000,0x00007fd210044000)] - 0x00007fd1bc30f000 JavaThread "sync-gb" [_thread_blocked, id=25244, stack(0x00007fd1b8041000,0x00007fd1b8142000)] - 0x00007fd1bc411800 JavaThread "sync-ib" [_thread_blocked, id=25245, stack(0x00007fd194db8000,0x00007fd194eb9000)] - 0x00007fd1bc4f2000 JavaThread "sync-gs" [_thread_blocked, id=25246, stack(0x00007fd194cb7000,0x00007fd194db8000)] - 0x00007fd1bc515000 JavaThread "pool-3-thread-1" [_thread_blocked, id=25247, stack(0x00007fd19483a000,0x00007fd19493b000)] - 0x00007fd1bc531800 JavaThread "pool-4-thread-1" [_thread_blocked, id=25248, stack(0x00007fd194739000,0x00007fd19483a000)] - 0x00007fd1bc57b000 JavaThread "sync-gb" [_thread_blocked, id=25250, stack(0x00007fd194bb6000,0x00007fd194cb7000)] - 0x00007fd1bc44e800 JavaThread "sync-ib" [_thread_blocked, id=25251, stack(0x00007fd194ab5000,0x00007fd194bb6000)] - 0x00007fd1bc450000 JavaThread "sync-gs" [_thread_blocked, id=25252, stack(0x00007fd1949b4000,0x00007fd194ab5000)] - 0x00007fd1bc451000 JavaThread "pool-6-thread-1" [_thread_blocked, id=25253, stack(0x00007fd1942b5000,0x00007fd1943b6000)] - 0x00007fd1380b8800 JavaThread "BlkHdr" [_thread_blocked, id=26580, stack(0x00007fd07c873000,0x00007fd07c974000)] - 0x00007fd1380ba000 JavaThread "ConsHdr" [_thread_blocked, id=26581, stack(0x00007fd07c772000,0x00007fd07c873000)] - 0x00007fd1380bc000 JavaThread "MinerHdr" [_thread_blocked, id=26582, stack(0x00007fd07c671000,0x00007fd07c772000)] - 0x00007fd1380bd800 JavaThread "TxHdr" [_thread_blocked, id=26583, stack(0x00007fd07c570000,0x00007fd07c671000)] - 0x00007fd138027000 JavaThread "pool-18-thread-1" [_thread_blocked, id=26584, stack(0x00007fd07c46f000,0x00007fd07c570000)] - 0x00007fd138021800 JavaThread "EpPS" [_thread_blocked, id=26585, stack(0x00007fd07c36e000,0x00007fd07c46f000)] - 0x00007fd1380c2000 JavaThread "sync-gb" [_thread_blocked, id=26587, stack(0x00007fd07ca75000,0x00007fd07cb76000)] - 0x00007fd1380c4000 JavaThread "sync-ib" [_thread_blocked, id=26588, stack(0x00007fd07c974000,0x00007fd07ca75000)] - 0x00007fd1380d0800 JavaThread "sync-gs" [_thread_blocked, id=26589, stack(0x00007fd07c26d000,0x00007fd07c36e000)] - 0x00007fd1380d2000 JavaThread "pool-20-thread-1" [_thread_blocked, id=26590, stack(0x00007fd07c16c000,0x00007fd07c26d000)] - 0x00007fd1380e1800 JavaThread "p2p-in" [_thread_blocked, id=26591, stack(0x00007fd07c06b000,0x00007fd07c16c000)] - 0x00007fd1380dd000 JavaThread "p2p-out-0" [_thread_blocked, id=26592, stack(0x00007fd07bf6a000,0x00007fd07c06b000)] - 0x00007fd1380df000 JavaThread "p2p-out-1" [_thread_blocked, id=26593, stack(0x00007fd07be69000,0x00007fd07bf6a000)] - 0x00007fd1380e6800 JavaThread "p2p-out-2" [_thread_blocked, id=26594, stack(0x00007fd07bd68000,0x00007fd07be69000)] - 0x00007fd1380e8800 JavaThread "p2p-out-3" [_thread_blocked, id=26595, stack(0x00007fd07bc67000,0x00007fd07bd68000)] - 0x00007fd1380ea000 JavaThread "p2p-out-4" [_thread_blocked, id=26596, stack(0x00007fd07bb66000,0x00007fd07bc67000)] - 0x00007fd1380ec000 JavaThread "p2p-out-5" [_thread_blocked, id=26597, stack(0x00007fd07ba65000,0x00007fd07bb66000)] - 0x00007fd1380ee000 JavaThread "p2p-out-6" [_thread_blocked, id=26598, stack(0x00007fd07b964000,0x00007fd07ba65000)] - 0x00007fd1380f0000 JavaThread "p2p-out-7" [_thread_blocked, id=26599, stack(0x00007fd07b863000,0x00007fd07b964000)] - 0x00007fd1380f2000 JavaThread "p2p-out-8" [_thread_blocked, id=26600, stack(0x00007fd07b762000,0x00007fd07b863000)] - 0x00007fd1380f4000 JavaThread "p2p-out-9" [_thread_blocked, id=26601, stack(0x00007fd07b661000,0x00007fd07b762000)] - 0x00007fd1380f6000 JavaThread "p2p-out-10" [_thread_blocked, id=26602, stack(0x00007fd07b560000,0x00007fd07b661000)] - 0x00007fd1380f8000 JavaThread "p2p-out-11" [_thread_blocked, id=26603, stack(0x00007fd07b45f000,0x00007fd07b560000)] - 0x00007fd1380fa000 JavaThread "p2p-out-12" [_thread_blocked, id=26604, stack(0x00007fd07b35e000,0x00007fd07b45f000)] - 0x00007fd1380fc000 JavaThread "p2p-out-13" [_thread_blocked, id=26605, stack(0x00007fd07b25d000,0x00007fd07b35e000)] - 0x00007fd1380fe000 JavaThread "p2p-out-14" [_thread_blocked, id=26606, stack(0x00007fd07b15c000,0x00007fd07b25d000)] - 0x00007fd138100800 JavaThread "p2p-out-15" [_thread_blocked, id=26607, stack(0x00007fd07b05b000,0x00007fd07b15c000)] - 0x00007fd138102800 JavaThread "p2p-out-16" [_thread_blocked, id=26608, stack(0x00007fd07af5a000,0x00007fd07b05b000)] - 0x00007fd138104800 JavaThread "p2p-out-17" [_thread_blocked, id=26609, stack(0x00007fd07ae59000,0x00007fd07af5a000)] - 0x00007fd138106800 JavaThread "p2p-out-18" [_thread_blocked, id=26610, stack(0x00007fd07ad58000,0x00007fd07ae59000)] - 0x00007fd138108800 JavaThread "p2p-out-19" [_thread_blocked, id=26611, stack(0x00007fd07ac57000,0x00007fd07ad58000)] - 0x00007fd13810a800 JavaThread "p2p-out-20" [_thread_blocked, id=26612, stack(0x00007fd07ab56000,0x00007fd07ac57000)] - 0x00007fd13810c800 JavaThread "p2p-out-21" [_thread_blocked, id=26613, stack(0x00007fd07aa55000,0x00007fd07ab56000)] - 0x00007fd13810e800 JavaThread "p2p-out-22" [_thread_blocked, id=26614, stack(0x00007fd07a954000,0x00007fd07aa55000)] - 0x00007fd138110800 JavaThread "p2p-out-23" [_thread_blocked, id=26615, stack(0x00007fd07a853000,0x00007fd07a954000)] - 0x00007fd138112000 JavaThread "p2p-out-24" [_thread_blocked, id=26616, stack(0x00007fd07a752000,0x00007fd07a853000)] - 0x00007fd138114000 JavaThread "p2p-out-25" [_thread_blocked, id=26617, stack(0x00007fd07a651000,0x00007fd07a752000)] - 0x00007fd138116000 JavaThread "p2p-out-26" [_thread_blocked, id=26618, stack(0x00007fd07a550000,0x00007fd07a651000)] - 0x00007fd138118000 JavaThread "p2p-out-27" [_thread_blocked, id=26619, stack(0x00007fd07a44f000,0x00007fd07a550000)] - 0x00007fd13811a000 JavaThread "p2p-out-28" [_thread_blocked, id=26620, stack(0x00007fd07a34e000,0x00007fd07a44f000)] - 0x00007fd13811c000 JavaThread "p2p-out-29" [_thread_blocked, id=26621, stack(0x00007fd07a24d000,0x00007fd07a34e000)] - 0x00007fd13811e800 JavaThread "p2p-out-30" [_thread_blocked, id=26622, stack(0x00007fd07a14c000,0x00007fd07a24d000)] - 0x00007fd138120800 JavaThread "p2p-out-31" [_thread_blocked, id=26623, stack(0x00007fd07a04b000,0x00007fd07a14c000)] - 0x00007fd138122800 JavaThread "p2p-worker-0" [_thread_blocked, id=26624, stack(0x00007fd079f4a000,0x00007fd07a04b000)] - 0x00007fd138124800 JavaThread "p2p-worker-1" [_thread_blocked, id=26625, stack(0x00007fd079e49000,0x00007fd079f4a000)] - 0x00007fd138126800 JavaThread "p2p-worker-2" [_thread_blocked, id=26626, stack(0x00007fd079d48000,0x00007fd079e49000)] - 0x00007fd138128800 JavaThread "p2p-worker-3" [_thread_blocked, id=26627, stack(0x00007fd079c47000,0x00007fd079d48000)] - 0x00007fd13812a800 JavaThread "p2p-worker-4" [_thread_blocked, id=26628, stack(0x00007fd079b46000,0x00007fd079c47000)] - 0x00007fd13812c800 JavaThread "p2p-worker-5" [_thread_blocked, id=26629, stack(0x00007fd079a45000,0x00007fd079b46000)] - 0x00007fd13812e800 JavaThread "p2p-worker-6" [_thread_blocked, id=26630, stack(0x00007fd079944000,0x00007fd079a45000)] - 0x00007fd138130800 JavaThread "p2p-worker-7" [_thread_blocked, id=26631, stack(0x00007fd079843000,0x00007fd079944000)] - 0x00007fd138132800 JavaThread "p2p-worker-8" [_thread_blocked, id=26632, stack(0x00007fd079742000,0x00007fd079843000)] - 0x00007fd138134800 JavaThread "p2p-worker-9" [_thread_blocked, id=26633, stack(0x00007fd079641000,0x00007fd079742000)] - 0x00007fd138136800 JavaThread "p2p-worker-10" [_thread_blocked, id=26634, stack(0x00007fd079540000,0x00007fd079641000)] - 0x00007fd138138800 JavaThread "p2p-worker-11" [_thread_blocked, id=26635, stack(0x00007fd07943f000,0x00007fd079540000)] - 0x00007fd13813a800 JavaThread "p2p-worker-12" [_thread_blocked, id=26636, stack(0x00007fd07933e000,0x00007fd07943f000)] - 0x00007fd13813c800 JavaThread "p2p-worker-13" [_thread_blocked, id=26637, stack(0x00007fd07923d000,0x00007fd07933e000)] - 0x00007fd13813e800 JavaThread "p2p-worker-14" [_thread_blocked, id=26638, stack(0x00007fd07913c000,0x00007fd07923d000)] - 0x00007fd138140800 JavaThread "p2p-worker-15" [_thread_blocked, id=26639, stack(0x00007fd07903b000,0x00007fd07913c000)] - 0x00007fd138142800 JavaThread "p2p-worker-16" [_thread_blocked, id=26640, stack(0x00007fd078f3a000,0x00007fd07903b000)] - 0x00007fd138144800 JavaThread "p2p-worker-17" [_thread_blocked, id=26641, stack(0x00007fd078e39000,0x00007fd078f3a000)] - 0x00007fd138146800 JavaThread "p2p-worker-18" [_thread_blocked, id=26642, stack(0x00007fd078d38000,0x00007fd078e39000)] - 0x00007fd138148800 JavaThread "p2p-worker-19" [_thread_blocked, id=26643, stack(0x00007fd078c37000,0x00007fd078d38000)] - 0x00007fd13814a800 JavaThread "p2p-worker-20" [_thread_blocked, id=26644, stack(0x00007fd078b36000,0x00007fd078c37000)] - 0x00007fd13814c800 JavaThread "p2p-worker-21" [_thread_blocked, id=26645, stack(0x00007fd078a35000,0x00007fd078b36000)] - 0x00007fd13814e800 JavaThread "p2p-worker-22" [_thread_blocked, id=26646, stack(0x00007fd078934000,0x00007fd078a35000)] - 0x00007fd138150800 JavaThread "p2p-worker-23" [_thread_blocked, id=26647, stack(0x00007fd078833000,0x00007fd078934000)] - 0x00007fd138152800 JavaThread "p2p-worker-24" [_thread_blocked, id=26648, stack(0x00007fd078732000,0x00007fd078833000)] - 0x00007fd138154800 JavaThread "p2p-worker-25" [_thread_blocked, id=26649, stack(0x00007fd078631000,0x00007fd078732000)] - 0x00007fd138156800 JavaThread "p2p-worker-26" [_thread_blocked, id=26650, stack(0x00007fd078530000,0x00007fd078631000)] - 0x00007fd138158800 JavaThread "p2p-worker-27" [_thread_blocked, id=26651, stack(0x00007fd07842f000,0x00007fd078530000)] - 0x00007fd13815a800 JavaThread "p2p-worker-28" [_thread_blocked, id=26652, stack(0x00007fd07832e000,0x00007fd07842f000)] - 0x00007fd13815c800 JavaThread "p2p-worker-29" [_thread_blocked, id=26653, stack(0x00007fd07822d000,0x00007fd07832e000)] - 0x00007fd13815e000 JavaThread "p2p-worker-30" [_thread_blocked, id=26654, stack(0x00007fd07812c000,0x00007fd07822d000)] - 0x00007fd138160000 JavaThread "p2p-worker-31" [_thread_blocked, id=26655, stack(0x00007fd07802b000,0x00007fd07812c000)] - 0x00007fd138162000 JavaThread "pool-21-thread-1" [_thread_blocked, id=26656, stack(0x00007fd077f2a000,0x00007fd07802b000)] - 0x00007fd138164000 JavaThread "p2p-clear" [_thread_blocked, id=26657, stack(0x00007fd077e29000,0x00007fd077f2a000)] - 0x00007fd138166000 JavaThread "p2p-tcp" [_thread_blocked, id=26658, stack(0x00007fd077d28000,0x00007fd077e29000)] - 0x00007fd138171000 JavaThread "pool-54-thread-1" [_thread_blocked, id=26659, stack(0x00007fd077c27000,0x00007fd077d28000)] - 0x00007fd1d0003000 JavaThread "pool-21-thread-2" [_thread_blocked, id=28225, stack(0x00007fd077b26000,0x00007fd077c27000)] - 0x00007fd1d4312000 JavaThread "pool-86-thread-1" [_thread_blocked, id=30413, stack(0x00007fd077a25000,0x00007fd077b26000)] - 0x00007fd1bc0b2800 JavaThread "AsyncAppender-Worker-consoleAsyncAppender" daemon [_thread_blocked, id=31459, stack(0x00007fd111adb000,0x00007fd111bdc000)] - 0x00007fd1d438a800 JavaThread "C2 CompilerThread1" daemon [_thread_blocked, id=31462, stack(0x00007fd1941b4000,0x00007fd1942b5000)] - 0x00007fd1d438c000 JavaThread "C2 CompilerThread2" daemon [_thread_blocked, id=31463, stack(0x00007fd1130f1000,0x00007fd1131f2000)] - -Other Threads: -=>0x00007fd22c208000 VMThread "VM Thread" [stack: 0x00007fd2042e0000,0x00007fd2043e0000] [id=25115] - 0x00007fd22c2be000 WatcherThread [stack: 0x00007fd1fd02a000,0x00007fd1fd12a000] [id=25123] - 0x00007fd22c03c000 GCTaskThread "GC Thread#0" [stack: 0x00007fd2139ce000,0x00007fd213ace000] [id=25109] - 0x00007fd1f0001000 GCTaskThread "GC Thread#1" [stack: 0x00007fd1bb685000,0x00007fd1bb785000] [id=25133] - 0x00007fd1f0002800 GCTaskThread "GC Thread#2" [stack: 0x00007fd1bb583000,0x00007fd1bb683000] [id=25134] - 0x00007fd1f0004000 GCTaskThread "GC Thread#3" [stack: 0x00007fd1bb481000,0x00007fd1bb581000] [id=25135] - 0x00007fd1f0005800 GCTaskThread "GC Thread#4" [stack: 0x00007fd1bb37f000,0x00007fd1bb47f000] [id=25136] - 0x00007fd1f0007000 GCTaskThread "GC Thread#5" [stack: 0x00007fd1bb27d000,0x00007fd1bb37d000] [id=25137] - 0x00007fd1f0009000 GCTaskThread "GC Thread#6" [stack: 0x00007fd1bb17b000,0x00007fd1bb27b000] [id=25138] - 0x00007fd1f000a800 GCTaskThread "GC Thread#7" [stack: 0x00007fd1bb079000,0x00007fd1bb179000] [id=25139] - 0x00007fd1f00a9800 GCTaskThread "GC Thread#8" [stack: 0x00007fd1b8f53000,0x00007fd1b9053000] [id=25173] - 0x00007fd1f011b800 GCTaskThread "GC Thread#9" [stack: 0x00007fd1b8e51000,0x00007fd1b8f51000] [id=25174] - 0x00007fd22c09a000 ConcurrentGCThread "G1 Main Marker" [stack: 0x00007fd21167b000,0x00007fd21177b000] [id=25110] - 0x00007fd22c09b800 ConcurrentGCThread "G1 Conc#0" [stack: 0x00007fd211579000,0x00007fd211679000] [id=25111] - 0x00007fd200001000 ConcurrentGCThread "G1 Conc#1" [stack: 0x00007fd1b9357000,0x00007fd1b9457000] [id=25168] - 0x00007fd200002000 ConcurrentGCThread "G1 Conc#2" [stack: 0x00007fd1b9255000,0x00007fd1b9355000] [id=25169] - 0x00007fd22c1a3800 ConcurrentGCThread "G1 Refine#0" [stack: 0x00007fd210a6d000,0x00007fd210b6d000] [id=25112] - 0x00007fd22c1a5800 ConcurrentGCThread "G1 Young RemSet Sampling" [stack: 0x00007fd21096b000,0x00007fd210a6b000] [id=25114] - -Threads with active compile tasks: -C2 CompilerThread05897 ! 4 org.aion.zero.db.AionRepositoryCache::flush (302 bytes) -C2 CompilerThread15862 ! 4 org.aion.zero.db.AionRepositoryCache::updateBatch (211 bytes) -C2 CompilerThread25906 ! 4 org.aion.mcf.db.AbstractRepositoryCache::incrementNonce (56 bytes) - -VM state:at safepoint (normal execution) - -VM Mutex/Monitor currently owned by a thread: ([mutex/lock_event]) -[0x00007fd22c010340] Threads_lock - owner thread: 0x00007fd22c208000 -[0x00007fd22c010a90] Heap_lock - owner thread: 0x00007fd22c799000 - -Heap address: 0x0000000707c00000, size: 3972 MB, Compressed Oops mode: Zero based, Oop shift amount: 3 -Narrow klass base: 0x0000000800000000, Narrow klass shift: 0 -Compressed class space size: 1073741824 Address: 0x0000000800000000 - -Heap: - garbage-first heap total 2297856K, used 373974K [0x0000000707c00000, 0x0000000800000000) - region size 1024K, 4 young (4096K), 4 survivors (4096K) - Metaspace used 27350K, capacity 28431K, committed 28800K, reserved 1075200K - class space used 3379K, capacity 3848K, committed 3968K, reserved 1048576K -Heap Regions: E=young(eden), S=young(survivor), O=old, HS=humongous(starts), HC=humongous(continues), CS=collection set, F=free, A=archive, TAMS=top-at-mark-start (previous, next) -| 0|0x0000000707c00000, 0x0000000707d00000, 0x0000000707d00000|100%| O| |TAMS 0x0000000707d00000, 0x0000000707c00000| Untracked -| 1|0x0000000707d00000, 0x0000000707e00000, 0x0000000707e00000|100%| O| |TAMS 0x0000000707e00000, 0x0000000707d00000| Untracked -| 2|0x0000000707e00000, 0x0000000707f00000, 0x0000000707f00000|100%| O| |TAMS 0x0000000707f00000, 0x0000000707e00000| Untracked -| 3|0x0000000707f00000, 0x0000000708000000, 0x0000000708000000|100%|HS| |TAMS 0x0000000708000000, 0x0000000707f00000| Complete -| 4|0x0000000708000000, 0x0000000708100000, 0x0000000708100000|100%| O| |TAMS 0x0000000708100000, 0x0000000708000000| Untracked -| 5|0x0000000708100000, 0x0000000708200000, 0x0000000708200000|100%| O| |TAMS 0x0000000708200000, 0x0000000708100000| Untracked -| 6|0x0000000708200000, 0x0000000708300000, 0x0000000708300000|100%| O| |TAMS 0x0000000708300000, 0x0000000708200000| Untracked -| 7|0x0000000708300000, 0x0000000708400000, 0x0000000708400000|100%| O| |TAMS 0x0000000708400000, 0x0000000708300000| Untracked -| 8|0x0000000708400000, 0x0000000708500000, 0x0000000708500000|100%| O| |TAMS 0x0000000708500000, 0x0000000708400000| Untracked -| 9|0x0000000708500000, 0x0000000708600000, 0x0000000708600000|100%| O| |TAMS 0x0000000708600000, 0x0000000708500000| Untracked -| 10|0x0000000708600000, 0x0000000708700000, 0x0000000708700000|100%| O| |TAMS 0x0000000708700000, 0x0000000708600000| Untracked -| 11|0x0000000708700000, 0x0000000708800000, 0x0000000708800000|100%| O| |TAMS 0x0000000708800000, 0x0000000708700000| Untracked -| 12|0x0000000708800000, 0x0000000708900000, 0x0000000708900000|100%| O| |TAMS 0x0000000708900000, 0x0000000708800000| Untracked -| 13|0x0000000708900000, 0x0000000708a00000, 0x0000000708a00000|100%|HS| |TAMS 0x0000000708a00000, 0x0000000708900000| Complete -| 14|0x0000000708a00000, 0x0000000708b00000, 0x0000000708b00000|100%| O| |TAMS 0x0000000708b00000, 0x0000000708a00000| Untracked -| 15|0x0000000708b00000, 0x0000000708c00000, 0x0000000708c00000|100%| O| |TAMS 0x0000000708c00000, 0x0000000708b00000| Untracked -| 16|0x0000000708c00000, 0x0000000708d00000, 0x0000000708d00000|100%| O| |TAMS 0x0000000708d00000, 0x0000000708c00000| Untracked -| 17|0x0000000708d00000, 0x0000000708e00000, 0x0000000708e00000|100%| O| |TAMS 0x0000000708e00000, 0x0000000708d00000| Untracked -| 18|0x0000000708e00000, 0x0000000708f00000, 0x0000000708f00000|100%| O| |TAMS 0x0000000708f00000, 0x0000000708e00000| Untracked -| 19|0x0000000708f00000, 0x0000000709000000, 0x0000000709000000|100%| O| |TAMS 0x0000000709000000, 0x0000000708f00000| Untracked -| 20|0x0000000709000000, 0x0000000709100000, 0x0000000709100000|100%| O| |TAMS 0x0000000709100000, 0x0000000709000000| Untracked -| 21|0x0000000709100000, 0x0000000709200000, 0x0000000709200000|100%| O| |TAMS 0x0000000709200000, 0x0000000709100000| Untracked -| 22|0x0000000709200000, 0x0000000709300000, 0x0000000709300000|100%| O| |TAMS 0x0000000709300000, 0x0000000709200000| Untracked -| 23|0x0000000709300000, 0x0000000709400000, 0x0000000709400000|100%| O| |TAMS 0x0000000709400000, 0x0000000709300000| Untracked -| 24|0x0000000709400000, 0x0000000709500000, 0x0000000709500000|100%| O| |TAMS 0x0000000709500000, 0x0000000709400000| Untracked -| 25|0x0000000709500000, 0x0000000709600000, 0x0000000709600000|100%| O| |TAMS 0x0000000709600000, 0x0000000709500000| Untracked -| 26|0x0000000709600000, 0x0000000709700000, 0x0000000709700000|100%| O| |TAMS 0x0000000709700000, 0x0000000709600000| Untracked -| 27|0x0000000709700000, 0x0000000709800000, 0x0000000709800000|100%| O| |TAMS 0x0000000709800000, 0x0000000709700000| Untracked -| 28|0x0000000709800000, 0x0000000709900000, 0x0000000709900000|100%| O| |TAMS 0x0000000709900000, 0x0000000709800000| Untracked -| 29|0x0000000709900000, 0x0000000709a00000, 0x0000000709a00000|100%| O| |TAMS 0x0000000709a00000, 0x0000000709900000| Untracked -| 30|0x0000000709a00000, 0x0000000709b00000, 0x0000000709b00000|100%| O| |TAMS 0x0000000709b00000, 0x0000000709a00000| Untracked -| 31|0x0000000709b00000, 0x0000000709c00000, 0x0000000709c00000|100%| O| |TAMS 0x0000000709c00000, 0x0000000709b00000| Untracked -| 32|0x0000000709c00000, 0x0000000709d00000, 0x0000000709d00000|100%| O| |TAMS 0x0000000709d00000, 0x0000000709c00000| Untracked -| 33|0x0000000709d00000, 0x0000000709e00000, 0x0000000709e00000|100%| O| |TAMS 0x0000000709e00000, 0x0000000709d00000| Untracked -| 34|0x0000000709e00000, 0x0000000709f00000, 0x0000000709f00000|100%| O| |TAMS 0x0000000709f00000, 0x0000000709e00000| Untracked -| 35|0x0000000709f00000, 0x000000070a000000, 0x000000070a000000|100%| O| |TAMS 0x000000070a000000, 0x0000000709f00000| Untracked -| 36|0x000000070a000000, 0x000000070a100000, 0x000000070a100000|100%| O| |TAMS 0x000000070a100000, 0x000000070a000000| Untracked -| 37|0x000000070a100000, 0x000000070a200000, 0x000000070a200000|100%| O| |TAMS 0x000000070a100000, 0x000000070a100000| Untracked -| 38|0x000000070a200000, 0x000000070a300000, 0x000000070a300000|100%| O| |TAMS 0x000000070a200000, 0x000000070a200000| Untracked -| 39|0x000000070a300000, 0x000000070a400000, 0x000000070a400000|100%| O| |TAMS 0x000000070a300000, 0x000000070a300000| Untracked -| 40|0x000000070a400000, 0x000000070a500000, 0x000000070a500000|100%| O| |TAMS 0x000000070a400000, 0x000000070a400000| Untracked -| 41|0x000000070a500000, 0x000000070a600000, 0x000000070a600000|100%| O| |TAMS 0x000000070a500000, 0x000000070a500000| Untracked -| 42|0x000000070a600000, 0x000000070a700000, 0x000000070a700000|100%|HS| |TAMS 0x000000070a600000, 0x000000070a600000| Complete -| 43|0x000000070a700000, 0x000000070a800000, 0x000000070a800000|100%| O| |TAMS 0x000000070a800000, 0x000000070a700000| Untracked -| 44|0x000000070a800000, 0x000000070a900000, 0x000000070a900000|100%|HS| |TAMS 0x000000070a800000, 0x000000070a800000| Complete -| 45|0x000000070a900000, 0x000000070aa00000, 0x000000070aa00000|100%|HS| |TAMS 0x000000070a900000, 0x000000070a900000| Complete -| 46|0x000000070aa00000, 0x000000070ab00000, 0x000000070ab00000|100%| O| |TAMS 0x000000070aa00000, 0x000000070aa00000| Untracked -| 47|0x000000070ab00000, 0x000000070ac00000, 0x000000070ac00000|100%| O| |TAMS 0x000000070ab00000, 0x000000070ab00000| Untracked -| 48|0x000000070ac00000, 0x000000070ad00000, 0x000000070ad00000|100%| O| |TAMS 0x000000070ad00000, 0x000000070ac00000| Untracked -| 49|0x000000070ad00000, 0x000000070ae00000, 0x000000070ae00000|100%| O| |TAMS 0x000000070ae00000, 0x000000070ad00000| Untracked -| 50|0x000000070ae00000, 0x000000070af00000, 0x000000070af00000|100%| O| |TAMS 0x000000070af00000, 0x000000070ae00000| Untracked -| 51|0x000000070af00000, 0x000000070b000000, 0x000000070b000000|100%| O| |TAMS 0x000000070b000000, 0x000000070af00000| Untracked -| 52|0x000000070b000000, 0x000000070b100000, 0x000000070b100000|100%| O| |TAMS 0x000000070b100000, 0x000000070b000000| Untracked -| 53|0x000000070b100000, 0x000000070b200000, 0x000000070b200000|100%| O| |TAMS 0x000000070b200000, 0x000000070b100000| Untracked -| 54|0x000000070b200000, 0x000000070b300000, 0x000000070b300000|100%| O| |TAMS 0x000000070b300000, 0x000000070b200000| Untracked -| 55|0x000000070b300000, 0x000000070b400000, 0x000000070b400000|100%| O| |TAMS 0x000000070b400000, 0x000000070b300000| Untracked -| 56|0x000000070b400000, 0x000000070b500000, 0x000000070b500000|100%| O| |TAMS 0x000000070b500000, 0x000000070b400000| Untracked -| 57|0x000000070b500000, 0x000000070b600000, 0x000000070b600000|100%| O| |TAMS 0x000000070b600000, 0x000000070b500000| Untracked -| 58|0x000000070b600000, 0x000000070b700000, 0x000000070b700000|100%| O| |TAMS 0x000000070b700000, 0x000000070b600000| Untracked -| 59|0x000000070b700000, 0x000000070b800000, 0x000000070b800000|100%| O| |TAMS 0x000000070b800000, 0x000000070b700000| Untracked -| 60|0x000000070b800000, 0x000000070b900000, 0x000000070b900000|100%| O| |TAMS 0x000000070b900000, 0x000000070b800000| Untracked -| 61|0x000000070b900000, 0x000000070ba00000, 0x000000070ba00000|100%| O| |TAMS 0x000000070ba00000, 0x000000070b900000| Untracked -| 62|0x000000070ba00000, 0x000000070bb00000, 0x000000070bb00000|100%| O| |TAMS 0x000000070bb00000, 0x000000070ba00000| Untracked -| 63|0x000000070bb00000, 0x000000070bc00000, 0x000000070bc00000|100%| O| |TAMS 0x000000070bc00000, 0x000000070bb00000| Untracked -| 64|0x000000070bc00000, 0x000000070bd00000, 0x000000070bd00000|100%| O| |TAMS 0x000000070bd00000, 0x000000070bc00000| Untracked -| 65|0x000000070bd00000, 0x000000070be00000, 0x000000070be00000|100%| O| |TAMS 0x000000070be00000, 0x000000070bd00000| Untracked -| 66|0x000000070be00000, 0x000000070bf00000, 0x000000070bf00000|100%| O| |TAMS 0x000000070bf00000, 0x000000070be00000| Untracked -| 67|0x000000070bf00000, 0x000000070c000000, 0x000000070c000000|100%| O| |TAMS 0x000000070c000000, 0x000000070bf00000| Untracked -| 68|0x000000070c000000, 0x000000070c100000, 0x000000070c100000|100%| O| |TAMS 0x000000070c100000, 0x000000070c000000| Untracked -| 69|0x000000070c100000, 0x000000070c200000, 0x000000070c200000|100%| O| |TAMS 0x000000070c200000, 0x000000070c100000| Untracked -| 70|0x000000070c200000, 0x000000070c300000, 0x000000070c300000|100%| O| |TAMS 0x000000070c300000, 0x000000070c200000| Untracked -| 71|0x000000070c300000, 0x000000070c400000, 0x000000070c400000|100%| O| |TAMS 0x000000070c400000, 0x000000070c300000| Untracked -| 72|0x000000070c400000, 0x000000070c500000, 0x000000070c500000|100%| O| |TAMS 0x000000070c500000, 0x000000070c400000| Untracked -| 73|0x000000070c500000, 0x000000070c600000, 0x000000070c600000|100%| O| |TAMS 0x000000070c600000, 0x000000070c500000| Untracked -| 74|0x000000070c600000, 0x000000070c700000, 0x000000070c700000|100%| O| |TAMS 0x000000070c700000, 0x000000070c600000| Untracked -| 75|0x000000070c700000, 0x000000070c800000, 0x000000070c800000|100%| O| |TAMS 0x000000070c800000, 0x000000070c700000| Untracked -| 76|0x000000070c800000, 0x000000070c900000, 0x000000070c900000|100%| O| |TAMS 0x000000070c900000, 0x000000070c800000| Untracked -| 77|0x000000070c900000, 0x000000070ca00000, 0x000000070ca00000|100%| O| |TAMS 0x000000070ca00000, 0x000000070c900000| Untracked -| 78|0x000000070ca00000, 0x000000070cb00000, 0x000000070cb00000|100%| O| |TAMS 0x000000070cb00000, 0x000000070ca00000| Untracked -| 79|0x000000070cb00000, 0x000000070cc00000, 0x000000070cc00000|100%| O| |TAMS 0x000000070cc00000, 0x000000070cb00000| Untracked -| 80|0x000000070cc00000, 0x000000070cd00000, 0x000000070cd00000|100%| O| |TAMS 0x000000070cd00000, 0x000000070cc00000| Untracked -| 81|0x000000070cd00000, 0x000000070ce00000, 0x000000070ce00000|100%| O| |TAMS 0x000000070ce00000, 0x000000070cd00000| Untracked -| 82|0x000000070ce00000, 0x000000070cf00000, 0x000000070cf00000|100%| O| |TAMS 0x000000070cf00000, 0x000000070ce00000| Untracked -| 83|0x000000070cf00000, 0x000000070d000000, 0x000000070d000000|100%| O| |TAMS 0x000000070d000000, 0x000000070cf00000| Untracked -| 84|0x000000070d000000, 0x000000070d100000, 0x000000070d100000|100%| O| |TAMS 0x000000070d100000, 0x000000070d000000| Untracked -| 85|0x000000070d100000, 0x000000070d200000, 0x000000070d200000|100%| O| |TAMS 0x000000070d200000, 0x000000070d100000| Untracked -| 86|0x000000070d200000, 0x000000070d300000, 0x000000070d300000|100%| O| |TAMS 0x000000070d300000, 0x000000070d200000| Untracked -| 87|0x000000070d300000, 0x000000070d400000, 0x000000070d400000|100%| O| |TAMS 0x000000070d400000, 0x000000070d300000| Untracked -| 88|0x000000070d400000, 0x000000070d500000, 0x000000070d500000|100%| O| |TAMS 0x000000070d500000, 0x000000070d400000| Untracked -| 89|0x000000070d500000, 0x000000070d600000, 0x000000070d600000|100%| O| |TAMS 0x000000070d600000, 0x000000070d500000| Untracked -| 90|0x000000070d600000, 0x000000070d700000, 0x000000070d700000|100%| O| |TAMS 0x000000070d700000, 0x000000070d600000| Untracked -| 91|0x000000070d700000, 0x000000070d800000, 0x000000070d800000|100%| O| |TAMS 0x000000070d800000, 0x000000070d700000| Untracked -| 92|0x000000070d800000, 0x000000070d800000, 0x000000070d900000| 0%| F| |TAMS 0x000000070d800000, 0x000000070d800000| Untracked -| 93|0x000000070d900000, 0x000000070da00000, 0x000000070da00000|100%| O| |TAMS 0x000000070da00000, 0x000000070d900000| Untracked -| 94|0x000000070da00000, 0x000000070db00000, 0x000000070db00000|100%| O| |TAMS 0x000000070db00000, 0x000000070da00000| Untracked -| 95|0x000000070db00000, 0x000000070dc00000, 0x000000070dc00000|100%|HS| |TAMS 0x000000070db00000, 0x000000070db00000| Complete -| 96|0x000000070dc00000, 0x000000070dd00000, 0x000000070dd00000|100%|HS| |TAMS 0x000000070dc00000, 0x000000070dc00000| Complete -| 97|0x000000070dd00000, 0x000000070de00000, 0x000000070de00000|100%|HS| |TAMS 0x000000070dd00000, 0x000000070dd00000| Complete -| 98|0x000000070de00000, 0x000000070df00000, 0x000000070df00000|100%| O| |TAMS 0x000000070de00000, 0x000000070de00000| Untracked -| 99|0x000000070df00000, 0x000000070e000000, 0x000000070e000000|100%|HS| |TAMS 0x000000070df00000, 0x000000070df00000| Complete -| 100|0x000000070e000000, 0x000000070e100000, 0x000000070e100000|100%| O| |TAMS 0x000000070e000000, 0x000000070e000000| Untracked -| 101|0x000000070e100000, 0x000000070e200000, 0x000000070e200000|100%| O| |TAMS 0x000000070e100000, 0x000000070e100000| Untracked -| 102|0x000000070e200000, 0x000000070e300000, 0x000000070e300000|100%| O| |TAMS 0x000000070e200000, 0x000000070e200000| Untracked -| 103|0x000000070e300000, 0x000000070e400000, 0x000000070e400000|100%| O| |TAMS 0x000000070e300000, 0x000000070e300000| Untracked -| 104|0x000000070e400000, 0x000000070e500000, 0x000000070e500000|100%| O| |TAMS 0x000000070e400000, 0x000000070e400000| Untracked -| 105|0x000000070e500000, 0x000000070e600000, 0x000000070e600000|100%| O| |TAMS 0x000000070e500000, 0x000000070e500000| Untracked -| 106|0x000000070e600000, 0x000000070e700000, 0x000000070e700000|100%| O| |TAMS 0x000000070e600000, 0x000000070e600000| Untracked -| 107|0x000000070e700000, 0x000000070e800000, 0x000000070e800000|100%| O| |TAMS 0x000000070e700000, 0x000000070e700000| Untracked -| 108|0x000000070e800000, 0x000000070e900000, 0x000000070e900000|100%| O| |TAMS 0x000000070e800000, 0x000000070e800000| Untracked -| 109|0x000000070e900000, 0x000000070ea00000, 0x000000070ea00000|100%| O| |TAMS 0x000000070e900000, 0x000000070e900000| Untracked -| 110|0x000000070ea00000, 0x000000070eb00000, 0x000000070eb00000|100%| O| |TAMS 0x000000070ea00000, 0x000000070ea00000| Untracked -| 111|0x000000070eb00000, 0x000000070ec00000, 0x000000070ec00000|100%|HS| |TAMS 0x000000070eb00000, 0x000000070eb00000| Complete -| 112|0x000000070ec00000, 0x000000070ed00000, 0x000000070ed00000|100%|HS| |TAMS 0x000000070ec00000, 0x000000070ec00000| Complete -| 113|0x000000070ed00000, 0x000000070ee00000, 0x000000070ee00000|100%|HS| |TAMS 0x000000070ed00000, 0x000000070ed00000| Complete -| 114|0x000000070ee00000, 0x000000070ef00000, 0x000000070ef00000|100%| O| |TAMS 0x000000070ee00000, 0x000000070ee00000| Untracked -| 115|0x000000070ef00000, 0x000000070f000000, 0x000000070f000000|100%| O| |TAMS 0x000000070ef00000, 0x000000070ef00000| Untracked -| 116|0x000000070f000000, 0x000000070f100000, 0x000000070f100000|100%| O| |TAMS 0x000000070f100000, 0x000000070f000000| Untracked -| 117|0x000000070f100000, 0x000000070f200000, 0x000000070f200000|100%| O| |TAMS 0x000000070f200000, 0x000000070f100000| Untracked -| 118|0x000000070f200000, 0x000000070f300000, 0x000000070f300000|100%| O| |TAMS 0x000000070f200000, 0x000000070f200000| Untracked -| 119|0x000000070f300000, 0x000000070f400000, 0x000000070f400000|100%| O| |TAMS 0x000000070f300000, 0x000000070f300000| Untracked -| 120|0x000000070f400000, 0x000000070f500000, 0x000000070f500000|100%| O| |TAMS 0x000000070f400000, 0x000000070f400000| Untracked -| 121|0x000000070f500000, 0x000000070f600000, 0x000000070f600000|100%| O| |TAMS 0x000000070f500000, 0x000000070f500000| Untracked -| 122|0x000000070f600000, 0x000000070f700000, 0x000000070f700000|100%| O| |TAMS 0x000000070f600000, 0x000000070f600000| Untracked -| 123|0x000000070f700000, 0x000000070f800000, 0x000000070f800000|100%| O| |TAMS 0x000000070f700000, 0x000000070f700000| Untracked -| 124|0x000000070f800000, 0x000000070f900000, 0x000000070f900000|100%|HS| |TAMS 0x000000070f800000, 0x000000070f800000| Complete -| 125|0x000000070f900000, 0x000000070fa00000, 0x000000070fa00000|100%|HS| |TAMS 0x000000070f900000, 0x000000070f900000| Complete -| 126|0x000000070fa00000, 0x000000070fb00000, 0x000000070fb00000|100%|HS| |TAMS 0x000000070fa00000, 0x000000070fa00000| Complete -| 127|0x000000070fb00000, 0x000000070fc00000, 0x000000070fc00000|100%| O| |TAMS 0x000000070fb00000, 0x000000070fb00000| Untracked -| 128|0x000000070fc00000, 0x000000070fd00000, 0x000000070fd00000|100%| O| |TAMS 0x000000070fc00000, 0x000000070fc00000| Untracked -| 129|0x000000070fd00000, 0x000000070fe00000, 0x000000070fe00000|100%|HS| |TAMS 0x000000070fd00000, 0x000000070fd00000| Complete -| 130|0x000000070fe00000, 0x000000070ff00000, 0x000000070ff00000|100%|HS| |TAMS 0x000000070fe00000, 0x000000070fe00000| Complete -| 131|0x000000070ff00000, 0x0000000710000000, 0x0000000710000000|100%| O| |TAMS 0x000000070ff00000, 0x000000070ff00000| Untracked -| 132|0x0000000710000000, 0x0000000710100000, 0x0000000710100000|100%| O| |TAMS 0x0000000710000000, 0x0000000710000000| Untracked -| 133|0x0000000710100000, 0x0000000710200000, 0x0000000710200000|100%| O| |TAMS 0x0000000710100000, 0x0000000710100000| Untracked -| 134|0x0000000710200000, 0x0000000710300000, 0x0000000710300000|100%| O| |TAMS 0x0000000710200000, 0x0000000710200000| Untracked -| 135|0x0000000710300000, 0x0000000710400000, 0x0000000710400000|100%| O| |TAMS 0x0000000710300000, 0x0000000710300000| Untracked -| 136|0x0000000710400000, 0x0000000710500000, 0x0000000710500000|100%| O| |TAMS 0x0000000710400000, 0x0000000710400000| Untracked -| 137|0x0000000710500000, 0x0000000710600000, 0x0000000710600000|100%|HS| |TAMS 0x0000000710500000, 0x0000000710500000| Complete -| 138|0x0000000710600000, 0x0000000710700000, 0x0000000710700000|100%| O| |TAMS 0x0000000710600000, 0x0000000710600000| Untracked -| 139|0x0000000710700000, 0x0000000710800000, 0x0000000710800000|100%|HS| |TAMS 0x0000000710700000, 0x0000000710700000| Complete -| 140|0x0000000710800000, 0x0000000710900000, 0x0000000710900000|100%| O| |TAMS 0x0000000710800000, 0x0000000710800000| Untracked -| 141|0x0000000710900000, 0x0000000710900000, 0x0000000710a00000| 0%| F| |TAMS 0x0000000710900000, 0x0000000710900000| Untracked -| 142|0x0000000710a00000, 0x0000000710a00000, 0x0000000710b00000| 0%| F| |TAMS 0x0000000710a00000, 0x0000000710a00000| Untracked -| 143|0x0000000710b00000, 0x0000000710c00000, 0x0000000710c00000|100%| O| |TAMS 0x0000000710b00000, 0x0000000710b00000| Untracked -| 144|0x0000000710c00000, 0x0000000710d00000, 0x0000000710d00000|100%| O| |TAMS 0x0000000710c00000, 0x0000000710c00000| Untracked -| 145|0x0000000710d00000, 0x0000000710e00000, 0x0000000710e00000|100%| O| |TAMS 0x0000000710e00000, 0x0000000710d00000| Untracked -| 146|0x0000000710e00000, 0x0000000710f00000, 0x0000000710f00000|100%| O| |TAMS 0x0000000710f00000, 0x0000000710e00000| Untracked -| 147|0x0000000710f00000, 0x0000000711000000, 0x0000000711000000|100%| O| |TAMS 0x0000000711000000, 0x0000000710f00000| Untracked -| 148|0x0000000711000000, 0x0000000711100000, 0x0000000711100000|100%| O| |TAMS 0x0000000711100000, 0x0000000711000000| Untracked -| 149|0x0000000711100000, 0x0000000711200000, 0x0000000711200000|100%| O| |TAMS 0x0000000711200000, 0x0000000711100000| Untracked -| 150|0x0000000711200000, 0x0000000711300000, 0x0000000711300000|100%| O| |TAMS 0x0000000711200000, 0x0000000711200000| Untracked -| 151|0x0000000711300000, 0x0000000711400000, 0x0000000711400000|100%| O| |TAMS 0x0000000711400000, 0x0000000711300000| Untracked -| 152|0x0000000711400000, 0x0000000711500000, 0x0000000711500000|100%| O| |TAMS 0x0000000711400000, 0x0000000711400000| Untracked -| 153|0x0000000711500000, 0x0000000711600000, 0x0000000711600000|100%| O| |TAMS 0x0000000711600000, 0x0000000711500000| Untracked -| 154|0x0000000711600000, 0x0000000711700000, 0x0000000711700000|100%| O| |TAMS 0x0000000711600000, 0x0000000711600000| Untracked -| 155|0x0000000711700000, 0x0000000711800000, 0x0000000711800000|100%| O| |TAMS 0x0000000711700000, 0x0000000711700000| Untracked -| 156|0x0000000711800000, 0x0000000711900000, 0x0000000711900000|100%| O| |TAMS 0x0000000711900000, 0x0000000711800000| Untracked -| 157|0x0000000711900000, 0x0000000711a00000, 0x0000000711a00000|100%| O| |TAMS 0x0000000711900000, 0x0000000711900000| Untracked -| 158|0x0000000711a00000, 0x0000000711b00000, 0x0000000711b00000|100%| O| |TAMS 0x0000000711a00000, 0x0000000711a00000| Untracked -| 159|0x0000000711b00000, 0x0000000711c00000, 0x0000000711c00000|100%| O| |TAMS 0x0000000711b00000, 0x0000000711b00000| Untracked -| 160|0x0000000711c00000, 0x0000000711d00000, 0x0000000711d00000|100%| O| |TAMS 0x0000000711c00000, 0x0000000711c00000| Untracked -| 161|0x0000000711d00000, 0x0000000711e00000, 0x0000000711e00000|100%| O| |TAMS 0x0000000711e00000, 0x0000000711d00000| Untracked -| 162|0x0000000711e00000, 0x0000000711f00000, 0x0000000711f00000|100%| O| |TAMS 0x0000000711e00000, 0x0000000711e00000| Untracked -| 163|0x0000000711f00000, 0x0000000712000000, 0x0000000712000000|100%| O| |TAMS 0x0000000712000000, 0x0000000711f00000| Untracked -| 164|0x0000000712000000, 0x0000000712100000, 0x0000000712100000|100%| O| |TAMS 0x0000000712100000, 0x0000000712000000| Untracked -| 165|0x0000000712100000, 0x0000000712200000, 0x0000000712200000|100%| O| |TAMS 0x0000000712200000, 0x0000000712100000| Untracked -| 166|0x0000000712200000, 0x0000000712300000, 0x0000000712300000|100%| O| |TAMS 0x0000000712300000, 0x0000000712200000| Untracked -| 167|0x0000000712300000, 0x0000000712400000, 0x0000000712400000|100%| O| |TAMS 0x0000000712400000, 0x0000000712300000| Untracked -| 168|0x0000000712400000, 0x0000000712500000, 0x0000000712500000|100%| O| |TAMS 0x0000000712400000, 0x0000000712400000| Untracked -| 169|0x0000000712500000, 0x0000000712600000, 0x0000000712600000|100%| O| |TAMS 0x0000000712500000, 0x0000000712500000| Untracked -| 170|0x0000000712600000, 0x0000000712700000, 0x0000000712700000|100%| O| |TAMS 0x0000000712700000, 0x0000000712600000| Untracked -| 171|0x0000000712700000, 0x0000000712800000, 0x0000000712800000|100%| O| |TAMS 0x0000000712700000, 0x0000000712700000| Untracked -| 172|0x0000000712800000, 0x0000000712900000, 0x0000000712900000|100%| O| |TAMS 0x0000000712800000, 0x0000000712800000| Untracked -| 173|0x0000000712900000, 0x0000000712a00000, 0x0000000712a00000|100%| O| |TAMS 0x0000000712900000, 0x0000000712900000| Untracked -| 174|0x0000000712a00000, 0x0000000712b00000, 0x0000000712b00000|100%| O| |TAMS 0x0000000712b00000, 0x0000000712a00000| Untracked -| 175|0x0000000712b00000, 0x0000000712c00000, 0x0000000712c00000|100%| O| |TAMS 0x0000000712b00000, 0x0000000712b00000| Untracked -| 176|0x0000000712c00000, 0x0000000712d00000, 0x0000000712d00000|100%| O| |TAMS 0x0000000712c00000, 0x0000000712c00000| Untracked -| 177|0x0000000712d00000, 0x0000000712e00000, 0x0000000712e00000|100%| O| |TAMS 0x0000000712d00000, 0x0000000712d00000| Untracked -| 178|0x0000000712e00000, 0x0000000712f00000, 0x0000000712f00000|100%| O| |TAMS 0x0000000712f00000, 0x0000000712e00000| Untracked -| 179|0x0000000712f00000, 0x0000000713000000, 0x0000000713000000|100%| O| |TAMS 0x0000000712f00000, 0x0000000712f00000| Untracked -| 180|0x0000000713000000, 0x0000000713100000, 0x0000000713100000|100%| O| |TAMS 0x0000000713100000, 0x0000000713000000| Untracked -| 181|0x0000000713100000, 0x0000000713200000, 0x0000000713200000|100%| O| |TAMS 0x0000000713100000, 0x0000000713100000| Untracked -| 182|0x0000000713200000, 0x0000000713300000, 0x0000000713300000|100%| O| |TAMS 0x0000000713200000, 0x0000000713200000| Untracked -| 183|0x0000000713300000, 0x0000000713400000, 0x0000000713400000|100%| O| |TAMS 0x0000000713300000, 0x0000000713300000| Untracked -| 184|0x0000000713400000, 0x0000000713500000, 0x0000000713500000|100%|HS| |TAMS 0x0000000713500000, 0x0000000713400000| Complete -| 185|0x0000000713500000, 0x0000000713600000, 0x0000000713600000|100%|HS| |TAMS 0x0000000713600000, 0x0000000713500000| Complete -| 186|0x0000000713600000, 0x0000000713700000, 0x0000000713700000|100%|HS| |TAMS 0x0000000713700000, 0x0000000713600000| Complete -| 187|0x0000000713700000, 0x0000000713800000, 0x0000000713800000|100%|HS| |TAMS 0x0000000713800000, 0x0000000713700000| Complete -| 188|0x0000000713800000, 0x0000000713900000, 0x0000000713900000|100%| O| |TAMS 0x0000000713800000, 0x0000000713800000| Untracked -| 189|0x0000000713900000, 0x0000000713a00000, 0x0000000713a00000|100%| O| |TAMS 0x0000000713900000, 0x0000000713900000| Untracked -| 190|0x0000000713a00000, 0x0000000713a00000, 0x0000000713b00000| 0%| F| |TAMS 0x0000000713a00000, 0x0000000713a00000| Untracked -| 191|0x0000000713b00000, 0x0000000713b00000, 0x0000000713c00000| 0%| F| |TAMS 0x0000000713b00000, 0x0000000713b00000| Untracked -| 192|0x0000000713c00000, 0x0000000713d00000, 0x0000000713d00000|100%| O| |TAMS 0x0000000713d00000, 0x0000000713c00000| Untracked -| 193|0x0000000713d00000, 0x0000000713e00000, 0x0000000713e00000|100%| O| |TAMS 0x0000000713e00000, 0x0000000713d00000| Untracked -| 194|0x0000000713e00000, 0x0000000713f00000, 0x0000000713f00000|100%|HS| |TAMS 0x0000000713f00000, 0x0000000713e00000| Complete -| 195|0x0000000713f00000, 0x0000000714000000, 0x0000000714000000|100%|HS| |TAMS 0x0000000714000000, 0x0000000713f00000| Complete -| 196|0x0000000714000000, 0x0000000714100000, 0x0000000714100000|100%|HS| |TAMS 0x0000000714100000, 0x0000000714000000| Complete -| 197|0x0000000714100000, 0x0000000714200000, 0x0000000714200000|100%|HC| |TAMS 0x0000000714200000, 0x0000000714100000| Complete -| 198|0x0000000714200000, 0x0000000714300000, 0x0000000714300000|100%|HC| |TAMS 0x0000000714300000, 0x0000000714200000| Complete -| 199|0x0000000714300000, 0x0000000714400000, 0x0000000714400000|100%|HC| |TAMS 0x0000000714400000, 0x0000000714300000| Complete -| 200|0x0000000714400000, 0x0000000714500000, 0x0000000714500000|100%|HC| |TAMS 0x0000000714500000, 0x0000000714400000| Complete -| 201|0x0000000714500000, 0x0000000714600000, 0x0000000714600000|100%|HC| |TAMS 0x0000000714600000, 0x0000000714500000| Complete -| 202|0x0000000714600000, 0x0000000714700000, 0x0000000714700000|100%|HC| |TAMS 0x0000000714700000, 0x0000000714600000| Complete -| 203|0x0000000714700000, 0x0000000714800000, 0x0000000714800000|100%|HC| |TAMS 0x0000000714800000, 0x0000000714700000| Complete -| 204|0x0000000714800000, 0x0000000714900000, 0x0000000714900000|100%|HC| |TAMS 0x0000000714900000, 0x0000000714800000| Complete -| 205|0x0000000714900000, 0x0000000714a00000, 0x0000000714a00000|100%|HC| |TAMS 0x0000000714a00000, 0x0000000714900000| Complete -| 206|0x0000000714a00000, 0x0000000714b00000, 0x0000000714b00000|100%|HC| |TAMS 0x0000000714b00000, 0x0000000714a00000| Complete -| 207|0x0000000714b00000, 0x0000000714c00000, 0x0000000714c00000|100%|HC| |TAMS 0x0000000714c00000, 0x0000000714b00000| Complete -| 208|0x0000000714c00000, 0x0000000714d00000, 0x0000000714d00000|100%|HC| |TAMS 0x0000000714d00000, 0x0000000714c00000| Complete -| 209|0x0000000714d00000, 0x0000000714e00000, 0x0000000714e00000|100%|HC| |TAMS 0x0000000714e00000, 0x0000000714d00000| Complete -| 210|0x0000000714e00000, 0x0000000714f00000, 0x0000000714f00000|100%|HC| |TAMS 0x0000000714f00000, 0x0000000714e00000| Complete -| 211|0x0000000714f00000, 0x0000000715000000, 0x0000000715000000|100%|HC| |TAMS 0x0000000715000000, 0x0000000714f00000| Complete -| 212|0x0000000715000000, 0x0000000715100000, 0x0000000715100000|100%|HC| |TAMS 0x0000000715100000, 0x0000000715000000| Complete -| 213|0x0000000715100000, 0x0000000715200000, 0x0000000715200000|100%|HC| |TAMS 0x0000000715200000, 0x0000000715100000| Complete -| 214|0x0000000715200000, 0x0000000715300000, 0x0000000715300000|100%|HC| |TAMS 0x0000000715300000, 0x0000000715200000| Complete -| 215|0x0000000715300000, 0x0000000715400000, 0x0000000715400000|100%|HC| |TAMS 0x0000000715400000, 0x0000000715300000| Complete -| 216|0x0000000715400000, 0x0000000715500000, 0x0000000715500000|100%|HC| |TAMS 0x0000000715500000, 0x0000000715400000| Complete -| 217|0x0000000715500000, 0x0000000715600000, 0x0000000715600000|100%|HC| |TAMS 0x0000000715600000, 0x0000000715500000| Complete -| 218|0x0000000715600000, 0x0000000715700000, 0x0000000715700000|100%|HC| |TAMS 0x0000000715700000, 0x0000000715600000| Complete -| 219|0x0000000715700000, 0x0000000715800000, 0x0000000715800000|100%|HC| |TAMS 0x0000000715800000, 0x0000000715700000| Complete -| 220|0x0000000715800000, 0x0000000715900000, 0x0000000715900000|100%|HC| |TAMS 0x0000000715900000, 0x0000000715800000| Complete -| 221|0x0000000715900000, 0x0000000715a00000, 0x0000000715a00000|100%|HC| |TAMS 0x0000000715a00000, 0x0000000715900000| Complete -| 222|0x0000000715a00000, 0x0000000715b00000, 0x0000000715b00000|100%|HC| |TAMS 0x0000000715b00000, 0x0000000715a00000| Complete -| 223|0x0000000715b00000, 0x0000000715c00000, 0x0000000715c00000|100%|HC| |TAMS 0x0000000715c00000, 0x0000000715b00000| Complete -| 224|0x0000000715c00000, 0x0000000715d00000, 0x0000000715d00000|100%|HC| |TAMS 0x0000000715d00000, 0x0000000715c00000| Complete -| 225|0x0000000715d00000, 0x0000000715e00000, 0x0000000715e00000|100%|HC| |TAMS 0x0000000715e00000, 0x0000000715d00000| Complete -| 226|0x0000000715e00000, 0x0000000715f00000, 0x0000000715f00000|100%|HC| |TAMS 0x0000000715f00000, 0x0000000715e00000| Complete -| 227|0x0000000715f00000, 0x0000000716000000, 0x0000000716000000|100%|HC| |TAMS 0x0000000716000000, 0x0000000715f00000| Complete -| 228|0x0000000716000000, 0x0000000716100000, 0x0000000716100000|100%|HC| |TAMS 0x0000000716100000, 0x0000000716000000| Complete -| 229|0x0000000716100000, 0x0000000716200000, 0x0000000716200000|100%|HC| |TAMS 0x0000000716200000, 0x0000000716100000| Complete -| 230|0x0000000716200000, 0x0000000716300000, 0x0000000716300000|100%|HC| |TAMS 0x0000000716300000, 0x0000000716200000| Complete -| 231|0x0000000716300000, 0x0000000716400000, 0x0000000716400000|100%|HC| |TAMS 0x0000000716400000, 0x0000000716300000| Complete -| 232|0x0000000716400000, 0x0000000716500000, 0x0000000716500000|100%|HC| |TAMS 0x0000000716500000, 0x0000000716400000| Complete -| 233|0x0000000716500000, 0x0000000716600000, 0x0000000716600000|100%|HC| |TAMS 0x0000000716600000, 0x0000000716500000| Complete -| 234|0x0000000716600000, 0x0000000716700000, 0x0000000716700000|100%|HC| |TAMS 0x0000000716700000, 0x0000000716600000| Complete -| 235|0x0000000716700000, 0x0000000716800000, 0x0000000716800000|100%|HC| |TAMS 0x0000000716800000, 0x0000000716700000| Complete -| 236|0x0000000716800000, 0x0000000716900000, 0x0000000716900000|100%|HC| |TAMS 0x0000000716900000, 0x0000000716800000| Complete -| 237|0x0000000716900000, 0x0000000716a00000, 0x0000000716a00000|100%|HC| |TAMS 0x0000000716a00000, 0x0000000716900000| Complete -| 238|0x0000000716a00000, 0x0000000716b00000, 0x0000000716b00000|100%|HC| |TAMS 0x0000000716b00000, 0x0000000716a00000| Complete -| 239|0x0000000716b00000, 0x0000000716c00000, 0x0000000716c00000|100%|HC| |TAMS 0x0000000716c00000, 0x0000000716b00000| Complete -| 240|0x0000000716c00000, 0x0000000716d00000, 0x0000000716d00000|100%|HC| |TAMS 0x0000000716d00000, 0x0000000716c00000| Complete -| 241|0x0000000716d00000, 0x0000000716e00000, 0x0000000716e00000|100%|HC| |TAMS 0x0000000716e00000, 0x0000000716d00000| Complete -| 242|0x0000000716e00000, 0x0000000716f00000, 0x0000000716f00000|100%|HC| |TAMS 0x0000000716f00000, 0x0000000716e00000| Complete -| 243|0x0000000716f00000, 0x0000000717000000, 0x0000000717000000|100%|HC| |TAMS 0x0000000717000000, 0x0000000716f00000| Complete -| 244|0x0000000717000000, 0x0000000717100000, 0x0000000717100000|100%|HC| |TAMS 0x0000000717100000, 0x0000000717000000| Complete -| 245|0x0000000717100000, 0x0000000717200000, 0x0000000717200000|100%|HC| |TAMS 0x0000000717200000, 0x0000000717100000| Complete -| 246|0x0000000717200000, 0x0000000717300000, 0x0000000717300000|100%|HC| |TAMS 0x0000000717300000, 0x0000000717200000| Complete -| 247|0x0000000717300000, 0x0000000717400000, 0x0000000717400000|100%|HC| |TAMS 0x0000000717400000, 0x0000000717300000| Complete -| 248|0x0000000717400000, 0x0000000717500000, 0x0000000717500000|100%|HC| |TAMS 0x0000000717500000, 0x0000000717400000| Complete -| 249|0x0000000717500000, 0x0000000717600000, 0x0000000717600000|100%|HC| |TAMS 0x0000000717600000, 0x0000000717500000| Complete -| 250|0x0000000717600000, 0x0000000717700000, 0x0000000717700000|100%|HC| |TAMS 0x0000000717700000, 0x0000000717600000| Complete -| 251|0x0000000717700000, 0x0000000717800000, 0x0000000717800000|100%|HC| |TAMS 0x0000000717800000, 0x0000000717700000| Complete -| 252|0x0000000717800000, 0x0000000717900000, 0x0000000717900000|100%|HC| |TAMS 0x0000000717900000, 0x0000000717800000| Complete -| 253|0x0000000717900000, 0x0000000717a00000, 0x0000000717a00000|100%|HC| |TAMS 0x0000000717a00000, 0x0000000717900000| Complete -| 254|0x0000000717a00000, 0x0000000717b00000, 0x0000000717b00000|100%|HC| |TAMS 0x0000000717b00000, 0x0000000717a00000| Complete -| 255|0x0000000717b00000, 0x0000000717c00000, 0x0000000717c00000|100%|HC| |TAMS 0x0000000717c00000, 0x0000000717b00000| Complete -| 256|0x0000000717c00000, 0x0000000717d00000, 0x0000000717d00000|100%|HC| |TAMS 0x0000000717d00000, 0x0000000717c00000| Complete -| 257|0x0000000717d00000, 0x0000000717e00000, 0x0000000717e00000|100%|HC| |TAMS 0x0000000717e00000, 0x0000000717d00000| Complete -| 258|0x0000000717e00000, 0x0000000717f00000, 0x0000000717f00000|100%|HC| |TAMS 0x0000000717f00000, 0x0000000717e00000| Complete -| 259|0x0000000717f00000, 0x0000000718000000, 0x0000000718000000|100%|HC| |TAMS 0x0000000718000000, 0x0000000717f00000| Complete -| 260|0x0000000718000000, 0x0000000718100000, 0x0000000718100000|100%|HC| |TAMS 0x0000000718100000, 0x0000000718000000| Complete -| 261|0x0000000718100000, 0x0000000718200000, 0x0000000718200000|100%| O| |TAMS 0x0000000718200000, 0x0000000718100000| Untracked -| 262|0x0000000718200000, 0x0000000718300000, 0x0000000718300000|100%| O| |TAMS 0x0000000718300000, 0x0000000718200000| Untracked -| 263|0x0000000718300000, 0x0000000718400000, 0x0000000718400000|100%| O| |TAMS 0x0000000718400000, 0x0000000718300000| Untracked -| 264|0x0000000718400000, 0x0000000718500000, 0x0000000718500000|100%| O| |TAMS 0x0000000718500000, 0x0000000718400000| Untracked -| 265|0x0000000718500000, 0x0000000718600000, 0x0000000718600000|100%| O| |TAMS 0x0000000718600000, 0x0000000718500000| Untracked -| 266|0x0000000718600000, 0x0000000718700000, 0x0000000718700000|100%| O| |TAMS 0x0000000718700000, 0x0000000718600000| Untracked -| 267|0x0000000718700000, 0x0000000718800000, 0x0000000718800000|100%| O| |TAMS 0x0000000718800000, 0x0000000718700000| Untracked -| 268|0x0000000718800000, 0x0000000718900000, 0x0000000718900000|100%| O| |TAMS 0x0000000718900000, 0x0000000718800000| Untracked -| 269|0x0000000718900000, 0x0000000718a00000, 0x0000000718a00000|100%| O| |TAMS 0x0000000718a00000, 0x0000000718900000| Untracked -| 270|0x0000000718a00000, 0x0000000718b00000, 0x0000000718b00000|100%| O| |TAMS 0x0000000718b00000, 0x0000000718a00000| Untracked -| 271|0x0000000718b00000, 0x0000000718c00000, 0x0000000718c00000|100%| O| |TAMS 0x0000000718c00000, 0x0000000718b00000| Untracked -| 272|0x0000000718c00000, 0x0000000718d00000, 0x0000000718d00000|100%| O| |TAMS 0x0000000718d00000, 0x0000000718c00000| Untracked -| 273|0x0000000718d00000, 0x0000000718e00000, 0x0000000718e00000|100%| O| |TAMS 0x0000000718e00000, 0x0000000718d00000| Untracked -| 274|0x0000000718e00000, 0x0000000718f00000, 0x0000000718f00000|100%| O| |TAMS 0x0000000718f00000, 0x0000000718e00000| Untracked -| 275|0x0000000718f00000, 0x0000000719000000, 0x0000000719000000|100%| O| |TAMS 0x0000000719000000, 0x0000000718f00000| Untracked -| 276|0x0000000719000000, 0x0000000719100000, 0x0000000719100000|100%| O| |TAMS 0x0000000719100000, 0x0000000719000000| Untracked -| 277|0x0000000719100000, 0x0000000719200000, 0x0000000719200000|100%| O| |TAMS 0x0000000719200000, 0x0000000719100000| Untracked -| 278|0x0000000719200000, 0x0000000719300000, 0x0000000719300000|100%| O| |TAMS 0x0000000719300000, 0x0000000719200000| Untracked -| 279|0x0000000719300000, 0x0000000719400000, 0x0000000719400000|100%| O| |TAMS 0x0000000719400000, 0x0000000719300000| Untracked -| 280|0x0000000719400000, 0x0000000719500000, 0x0000000719500000|100%| O| |TAMS 0x0000000719500000, 0x0000000719400000| Untracked -| 281|0x0000000719500000, 0x0000000719600000, 0x0000000719600000|100%| O| |TAMS 0x0000000719600000, 0x0000000719500000| Untracked -| 282|0x0000000719600000, 0x0000000719700000, 0x0000000719700000|100%| O| |TAMS 0x0000000719700000, 0x0000000719600000| Untracked -| 283|0x0000000719700000, 0x0000000719800000, 0x0000000719800000|100%| O| |TAMS 0x0000000719800000, 0x0000000719700000| Untracked -| 284|0x0000000719800000, 0x0000000719900000, 0x0000000719900000|100%| O| |TAMS 0x0000000719900000, 0x0000000719800000| Untracked -| 285|0x0000000719900000, 0x0000000719a00000, 0x0000000719a00000|100%| O| |TAMS 0x0000000719a00000, 0x0000000719900000| Untracked -| 286|0x0000000719a00000, 0x0000000719b00000, 0x0000000719b00000|100%| O| |TAMS 0x0000000719b00000, 0x0000000719a00000| Untracked -| 287|0x0000000719b00000, 0x0000000719c00000, 0x0000000719c00000|100%| O| |TAMS 0x0000000719c00000, 0x0000000719b00000| Untracked -| 288|0x0000000719c00000, 0x0000000719d00000, 0x0000000719d00000|100%| O| |TAMS 0x0000000719d00000, 0x0000000719c00000| Untracked -| 289|0x0000000719d00000, 0x0000000719e00000, 0x0000000719e00000|100%| O| |TAMS 0x0000000719e00000, 0x0000000719d00000| Untracked -| 290|0x0000000719e00000, 0x0000000719f00000, 0x0000000719f00000|100%| O| |TAMS 0x0000000719f00000, 0x0000000719e00000| Untracked -| 291|0x0000000719f00000, 0x000000071a000000, 0x000000071a000000|100%| O| |TAMS 0x000000071a000000, 0x0000000719f00000| Untracked -| 292|0x000000071a000000, 0x000000071a100000, 0x000000071a100000|100%| O| |TAMS 0x000000071a100000, 0x000000071a000000| Untracked -| 293|0x000000071a100000, 0x000000071a200000, 0x000000071a200000|100%| O| |TAMS 0x000000071a200000, 0x000000071a100000| Untracked -| 294|0x000000071a200000, 0x000000071a300000, 0x000000071a300000|100%| O| |TAMS 0x000000071a300000, 0x000000071a200000| Untracked -| 295|0x000000071a300000, 0x000000071a400000, 0x000000071a400000|100%| O| |TAMS 0x000000071a400000, 0x000000071a300000| Untracked -| 296|0x000000071a400000, 0x000000071a500000, 0x000000071a500000|100%| O| |TAMS 0x000000071a500000, 0x000000071a400000| Untracked -| 297|0x000000071a500000, 0x000000071a600000, 0x000000071a600000|100%| O| |TAMS 0x000000071a600000, 0x000000071a500000| Untracked -| 298|0x000000071a600000, 0x000000071a700000, 0x000000071a700000|100%| O| |TAMS 0x000000071a700000, 0x000000071a600000| Untracked -| 299|0x000000071a700000, 0x000000071a800000, 0x000000071a800000|100%| O| |TAMS 0x000000071a800000, 0x000000071a700000| Untracked -| 300|0x000000071a800000, 0x000000071a900000, 0x000000071a900000|100%| O| |TAMS 0x000000071a900000, 0x000000071a800000| Untracked -| 301|0x000000071a900000, 0x000000071aa00000, 0x000000071aa00000|100%|HS| |TAMS 0x000000071aa00000, 0x000000071a900000| Complete -| 302|0x000000071aa00000, 0x000000071ab00000, 0x000000071ab00000|100%| O| |TAMS 0x000000071ab00000, 0x000000071aa00000| Untracked -| 303|0x000000071ab00000, 0x000000071ac00000, 0x000000071ac00000|100%| O| |TAMS 0x000000071ac00000, 0x000000071ab00000| Untracked -| 304|0x000000071ac00000, 0x000000071ad00000, 0x000000071ad00000|100%| O| |TAMS 0x000000071ad00000, 0x000000071ac00000| Untracked -| 305|0x000000071ad00000, 0x000000071ae00000, 0x000000071ae00000|100%| O| |TAMS 0x000000071ae00000, 0x000000071ad00000| Untracked -| 306|0x000000071ae00000, 0x000000071af00000, 0x000000071af00000|100%| O| |TAMS 0x000000071af00000, 0x000000071ae00000| Untracked -| 307|0x000000071af00000, 0x000000071b000000, 0x000000071b000000|100%| O| |TAMS 0x000000071b000000, 0x000000071af00000| Untracked -| 308|0x000000071b000000, 0x000000071b100000, 0x000000071b100000|100%| O| |TAMS 0x000000071b100000, 0x000000071b000000| Untracked -| 309|0x000000071b100000, 0x000000071b200000, 0x000000071b200000|100%| O| |TAMS 0x000000071b200000, 0x000000071b100000| Untracked -| 310|0x000000071b200000, 0x000000071b300000, 0x000000071b300000|100%| O| |TAMS 0x000000071b300000, 0x000000071b200000| Untracked -| 311|0x000000071b300000, 0x000000071b400000, 0x000000071b400000|100%| O| |TAMS 0x000000071b400000, 0x000000071b300000| Untracked -| 312|0x000000071b400000, 0x000000071b500000, 0x000000071b500000|100%| O| |TAMS 0x000000071b500000, 0x000000071b400000| Untracked -| 313|0x000000071b500000, 0x000000071b600000, 0x000000071b600000|100%| O| |TAMS 0x000000071b600000, 0x000000071b500000| Untracked -| 314|0x000000071b600000, 0x000000071b700000, 0x000000071b700000|100%| O| |TAMS 0x000000071b700000, 0x000000071b600000| Untracked -| 315|0x000000071b700000, 0x000000071b800000, 0x000000071b800000|100%| O| |TAMS 0x000000071b800000, 0x000000071b700000| Untracked -| 316|0x000000071b800000, 0x000000071b900000, 0x000000071b900000|100%| O| |TAMS 0x000000071b900000, 0x000000071b800000| Untracked -| 317|0x000000071b900000, 0x000000071ba00000, 0x000000071ba00000|100%| O| |TAMS 0x000000071ba00000, 0x000000071b900000| Untracked -| 318|0x000000071ba00000, 0x000000071bb00000, 0x000000071bb00000|100%| O| |TAMS 0x000000071bb00000, 0x000000071ba00000| Untracked -| 319|0x000000071bb00000, 0x000000071bc00000, 0x000000071bc00000|100%| O| |TAMS 0x000000071bc00000, 0x000000071bb00000| Untracked -| 320|0x000000071bc00000, 0x000000071bd00000, 0x000000071bd00000|100%| O| |TAMS 0x000000071bd00000, 0x000000071bc00000| Untracked -| 321|0x000000071bd00000, 0x000000071be00000, 0x000000071be00000|100%| O| |TAMS 0x000000071be00000, 0x000000071bd00000| Untracked -| 322|0x000000071be00000, 0x000000071bf00000, 0x000000071bf00000|100%| O| |TAMS 0x000000071bf00000, 0x000000071be00000| Untracked -| 323|0x000000071bf00000, 0x000000071c000000, 0x000000071c000000|100%| O| |TAMS 0x000000071c000000, 0x000000071bf00000| Untracked -| 324|0x000000071c000000, 0x000000071c100000, 0x000000071c100000|100%| O| |TAMS 0x000000071c100000, 0x000000071c000000| Untracked -| 325|0x000000071c100000, 0x000000071c200000, 0x000000071c200000|100%| O| |TAMS 0x000000071c200000, 0x000000071c100000| Untracked -| 326|0x000000071c200000, 0x000000071c300000, 0x000000071c300000|100%| O| |TAMS 0x000000071c300000, 0x000000071c200000| Untracked -| 327|0x000000071c300000, 0x000000071c400000, 0x000000071c400000|100%| O| |TAMS 0x000000071c400000, 0x000000071c300000| Untracked -| 328|0x000000071c400000, 0x000000071c500000, 0x000000071c500000|100%| O| |TAMS 0x000000071c500000, 0x000000071c400000| Untracked -| 329|0x000000071c500000, 0x000000071c600000, 0x000000071c600000|100%| O| |TAMS 0x000000071c600000, 0x000000071c500000| Untracked -| 330|0x000000071c600000, 0x000000071c700000, 0x000000071c700000|100%| O| |TAMS 0x000000071c700000, 0x000000071c600000| Untracked -| 331|0x000000071c700000, 0x000000071c800000, 0x000000071c800000|100%| O| |TAMS 0x000000071c800000, 0x000000071c700000| Untracked -| 332|0x000000071c800000, 0x000000071c900000, 0x000000071c900000|100%| O| |TAMS 0x000000071c900000, 0x000000071c800000| Untracked -| 333|0x000000071c900000, 0x000000071ca00000, 0x000000071ca00000|100%| O| |TAMS 0x000000071ca00000, 0x000000071c900000| Untracked -| 334|0x000000071ca00000, 0x000000071cb00000, 0x000000071cb00000|100%| O| |TAMS 0x000000071cb00000, 0x000000071ca00000| Untracked -| 335|0x000000071cb00000, 0x000000071cc00000, 0x000000071cc00000|100%| O| |TAMS 0x000000071cc00000, 0x000000071cb00000| Untracked -| 336|0x000000071cc00000, 0x000000071cd00000, 0x000000071cd00000|100%| O| |TAMS 0x000000071cd00000, 0x000000071cc00000| Untracked -| 337|0x000000071cd00000, 0x000000071ce00000, 0x000000071ce00000|100%| O| |TAMS 0x000000071ce00000, 0x000000071cd00000| Untracked -| 338|0x000000071ce00000, 0x000000071cf00000, 0x000000071cf00000|100%| O| |TAMS 0x000000071cf00000, 0x000000071ce00000| Untracked -| 339|0x000000071cf00000, 0x000000071d000000, 0x000000071d000000|100%| O| |TAMS 0x000000071d000000, 0x000000071cf00000| Untracked -| 340|0x000000071d000000, 0x000000071d000000, 0x000000071d100000| 0%| F| |TAMS 0x000000071d000000, 0x000000071d000000| Untracked -| 341|0x000000071d100000, 0x000000071d200000, 0x000000071d200000|100%| O| |TAMS 0x000000071d200000, 0x000000071d100000| Untracked -| 342|0x000000071d200000, 0x000000071d300000, 0x000000071d300000|100%| O| |TAMS 0x000000071d300000, 0x000000071d200000| Untracked -| 343|0x000000071d300000, 0x000000071d400000, 0x000000071d400000|100%| O| |TAMS 0x000000071d400000, 0x000000071d300000| Untracked -| 344|0x000000071d400000, 0x000000071d400000, 0x000000071d500000| 0%| F| |TAMS 0x000000071d400000, 0x000000071d400000| Untracked -| 345|0x000000071d500000, 0x000000071d600000, 0x000000071d600000|100%| O| |TAMS 0x000000071d600000, 0x000000071d500000| Untracked -| 346|0x000000071d600000, 0x000000071d700000, 0x000000071d700000|100%| O| |TAMS 0x000000071d700000, 0x000000071d600000| Untracked -| 347|0x000000071d700000, 0x000000071d700000, 0x000000071d800000| 0%| F| |TAMS 0x000000071d700000, 0x000000071d700000| Untracked -| 348|0x000000071d800000, 0x000000071d900000, 0x000000071d900000|100%| O| |TAMS 0x000000071d900000, 0x000000071d800000| Untracked -| 349|0x000000071d900000, 0x000000071da00000, 0x000000071da00000|100%| O| |TAMS 0x000000071da00000, 0x000000071d900000| Untracked -| 350|0x000000071da00000, 0x000000071db00000, 0x000000071db00000|100%| O| |TAMS 0x000000071db00000, 0x000000071da00000| Untracked -| 351|0x000000071db00000, 0x000000071dc00000, 0x000000071dc00000|100%| O| |TAMS 0x000000071dc00000, 0x000000071db00000| Untracked -| 352|0x000000071dc00000, 0x000000071dd00000, 0x000000071dd00000|100%| O| |TAMS 0x000000071dd00000, 0x000000071dc00000| Untracked -| 353|0x000000071dd00000, 0x000000071de00000, 0x000000071de00000|100%| O| |TAMS 0x000000071de00000, 0x000000071dd00000| Untracked -| 354|0x000000071de00000, 0x000000071df00000, 0x000000071df00000|100%| O| |TAMS 0x000000071df00000, 0x000000071de00000| Untracked -| 355|0x000000071df00000, 0x000000071df00000, 0x000000071e000000| 0%| F| |TAMS 0x000000071df00000, 0x000000071df00000| Untracked -| 356|0x000000071e000000, 0x000000071e000000, 0x000000071e100000| 0%| F| |TAMS 0x000000071e000000, 0x000000071e000000| Untracked -| 357|0x000000071e100000, 0x000000071e100000, 0x000000071e200000| 0%| F| |TAMS 0x000000071e100000, 0x000000071e100000| Untracked -| 358|0x000000071e200000, 0x000000071e200000, 0x000000071e300000| 0%| F| |TAMS 0x000000071e200000, 0x000000071e200000| Untracked -| 359|0x000000071e300000, 0x000000071e300000, 0x000000071e400000| 0%| F| |TAMS 0x000000071e300000, 0x000000071e300000| Untracked -| 360|0x000000071e400000, 0x000000071e400000, 0x000000071e500000| 0%| F| |TAMS 0x000000071e400000, 0x000000071e400000| Untracked -| 361|0x000000071e500000, 0x000000071e500000, 0x000000071e600000| 0%| F| |TAMS 0x000000071e500000, 0x000000071e500000| Untracked -| 362|0x000000071e600000, 0x000000071e600000, 0x000000071e700000| 0%| F| |TAMS 0x000000071e600000, 0x000000071e600000| Untracked -| 363|0x000000071e700000, 0x000000071e700000, 0x000000071e800000| 0%| F| |TAMS 0x000000071e700000, 0x000000071e700000| Untracked -| 364|0x000000071e800000, 0x000000071e800000, 0x000000071e900000| 0%| F| |TAMS 0x000000071e800000, 0x000000071e800000| Untracked -| 365|0x000000071e900000, 0x000000071e900000, 0x000000071ea00000| 0%| F| |TAMS 0x000000071e900000, 0x000000071e900000| Untracked -| 366|0x000000071ea00000, 0x000000071ea00000, 0x000000071eb00000| 0%| F| |TAMS 0x000000071ea00000, 0x000000071ea00000| Untracked -| 367|0x000000071eb00000, 0x000000071eb00000, 0x000000071ec00000| 0%| F| |TAMS 0x000000071eb00000, 0x000000071eb00000| Untracked -| 368|0x000000071ec00000, 0x000000071ec00000, 0x000000071ed00000| 0%| F| |TAMS 0x000000071ec00000, 0x000000071ec00000| Untracked -| 369|0x000000071ed00000, 0x000000071ed00000, 0x000000071ee00000| 0%| F| |TAMS 0x000000071ed00000, 0x000000071ed00000| Untracked -| 370|0x000000071ee00000, 0x000000071ee00000, 0x000000071ef00000| 0%| F| |TAMS 0x000000071ee00000, 0x000000071ee00000| Untracked -| 371|0x000000071ef00000, 0x000000071ef00000, 0x000000071f000000| 0%| F| |TAMS 0x000000071ef00000, 0x000000071ef00000| Untracked -| 372|0x000000071f000000, 0x000000071f000000, 0x000000071f100000| 0%| F| |TAMS 0x000000071f000000, 0x000000071f000000| Untracked -| 373|0x000000071f100000, 0x000000071f100000, 0x000000071f200000| 0%| F| |TAMS 0x000000071f100000, 0x000000071f100000| Untracked -| 374|0x000000071f200000, 0x000000071f200000, 0x000000071f300000| 0%| F| |TAMS 0x000000071f200000, 0x000000071f200000| Untracked -| 375|0x000000071f300000, 0x000000071f300000, 0x000000071f400000| 0%| F| |TAMS 0x000000071f300000, 0x000000071f300000| Untracked -| 376|0x000000071f400000, 0x000000071f400000, 0x000000071f500000| 0%| F| |TAMS 0x000000071f400000, 0x000000071f400000| Untracked -| 377|0x000000071f500000, 0x000000071f500000, 0x000000071f600000| 0%| F| |TAMS 0x000000071f500000, 0x000000071f500000| Untracked -| 378|0x000000071f600000, 0x000000071f600000, 0x000000071f700000| 0%| F| |TAMS 0x000000071f600000, 0x000000071f600000| Untracked -| 379|0x000000071f700000, 0x000000071f700000, 0x000000071f800000| 0%| F| |TAMS 0x000000071f700000, 0x000000071f700000| Untracked -| 380|0x000000071f800000, 0x000000071f800000, 0x000000071f900000| 0%| F| |TAMS 0x000000071f800000, 0x000000071f800000| Untracked -| 381|0x000000071f900000, 0x000000071f900000, 0x000000071fa00000| 0%| F| |TAMS 0x000000071f900000, 0x000000071f900000| Untracked -| 382|0x000000071fa00000, 0x000000071fa00000, 0x000000071fb00000| 0%| F| |TAMS 0x000000071fa00000, 0x000000071fa00000| Untracked -| 383|0x000000071fb00000, 0x000000071fb00000, 0x000000071fc00000| 0%| F| |TAMS 0x000000071fb00000, 0x000000071fb00000| Untracked -| 384|0x000000071fc00000, 0x000000071fc00000, 0x000000071fd00000| 0%| F| |TAMS 0x000000071fc00000, 0x000000071fc00000| Untracked -| 385|0x000000071fd00000, 0x000000071fd00000, 0x000000071fe00000| 0%| F| |TAMS 0x000000071fd00000, 0x000000071fd00000| Untracked -| 386|0x000000071fe00000, 0x000000071fe00000, 0x000000071ff00000| 0%| F| |TAMS 0x000000071fe00000, 0x000000071fe00000| Untracked -| 387|0x000000071ff00000, 0x000000071ff00000, 0x0000000720000000| 0%| F| |TAMS 0x000000071ff00000, 0x000000071ff00000| Untracked -| 388|0x0000000720000000, 0x0000000720000000, 0x0000000720100000| 0%| F| |TAMS 0x0000000720000000, 0x0000000720000000| Untracked -| 389|0x0000000720100000, 0x0000000720100000, 0x0000000720200000| 0%| F| |TAMS 0x0000000720100000, 0x0000000720100000| Untracked -| 390|0x0000000720200000, 0x0000000720200000, 0x0000000720300000| 0%| F| |TAMS 0x0000000720200000, 0x0000000720200000| Untracked -| 391|0x0000000720300000, 0x0000000720300000, 0x0000000720400000| 0%| F| |TAMS 0x0000000720300000, 0x0000000720300000| Untracked -| 392|0x0000000720400000, 0x0000000720400000, 0x0000000720500000| 0%| F| |TAMS 0x0000000720400000, 0x0000000720400000| Untracked -| 393|0x0000000720500000, 0x0000000720500000, 0x0000000720600000| 0%| F| |TAMS 0x0000000720500000, 0x0000000720500000| Untracked -| 394|0x0000000720600000, 0x0000000720600000, 0x0000000720700000| 0%| F| |TAMS 0x0000000720600000, 0x0000000720600000| Untracked -| 395|0x0000000720700000, 0x0000000720700000, 0x0000000720800000| 0%| F| |TAMS 0x0000000720700000, 0x0000000720700000| Untracked -| 396|0x0000000720800000, 0x0000000720800000, 0x0000000720900000| 0%| F| |TAMS 0x0000000720800000, 0x0000000720800000| Untracked -| 397|0x0000000720900000, 0x0000000720900000, 0x0000000720a00000| 0%| F| |TAMS 0x0000000720900000, 0x0000000720900000| Untracked -| 398|0x0000000720a00000, 0x0000000720a00000, 0x0000000720b00000| 0%| F| |TAMS 0x0000000720a00000, 0x0000000720a00000| Untracked -| 399|0x0000000720b00000, 0x0000000720b00000, 0x0000000720c00000| 0%| F| |TAMS 0x0000000720b00000, 0x0000000720b00000| Untracked -| 400|0x0000000720c00000, 0x0000000720c00000, 0x0000000720d00000| 0%| F| |TAMS 0x0000000720c00000, 0x0000000720c00000| Untracked -| 401|0x0000000720d00000, 0x0000000720d00000, 0x0000000720e00000| 0%| F| |TAMS 0x0000000720d00000, 0x0000000720d00000| Untracked -| 402|0x0000000720e00000, 0x0000000720e00000, 0x0000000720f00000| 0%| F| |TAMS 0x0000000720e00000, 0x0000000720e00000| Untracked -| 403|0x0000000720f00000, 0x0000000720f00000, 0x0000000721000000| 0%| F| |TAMS 0x0000000720f00000, 0x0000000720f00000| Untracked -| 404|0x0000000721000000, 0x0000000721000000, 0x0000000721100000| 0%| F| |TAMS 0x0000000721000000, 0x0000000721000000| Untracked -| 405|0x0000000721100000, 0x0000000721100000, 0x0000000721200000| 0%| F| |TAMS 0x0000000721100000, 0x0000000721100000| Untracked -| 406|0x0000000721200000, 0x0000000721200000, 0x0000000721300000| 0%| F| |TAMS 0x0000000721200000, 0x0000000721200000| Untracked -| 407|0x0000000721300000, 0x0000000721300000, 0x0000000721400000| 0%| F| |TAMS 0x0000000721300000, 0x0000000721300000| Untracked -| 408|0x0000000721400000, 0x0000000721400000, 0x0000000721500000| 0%| F| |TAMS 0x0000000721400000, 0x0000000721400000| Untracked -| 409|0x0000000721500000, 0x0000000721500000, 0x0000000721600000| 0%| F| |TAMS 0x0000000721500000, 0x0000000721500000| Untracked -| 410|0x0000000721600000, 0x0000000721600000, 0x0000000721700000| 0%| F| |TAMS 0x0000000721600000, 0x0000000721600000| Untracked -| 411|0x0000000721700000, 0x0000000721700000, 0x0000000721800000| 0%| F| |TAMS 0x0000000721700000, 0x0000000721700000| Untracked -| 412|0x0000000721800000, 0x0000000721800000, 0x0000000721900000| 0%| F| |TAMS 0x0000000721800000, 0x0000000721800000| Untracked -| 413|0x0000000721900000, 0x0000000721900000, 0x0000000721a00000| 0%| F| |TAMS 0x0000000721900000, 0x0000000721900000| Untracked -| 414|0x0000000721a00000, 0x0000000721a00000, 0x0000000721b00000| 0%| F| |TAMS 0x0000000721a00000, 0x0000000721a00000| Untracked -| 415|0x0000000721b00000, 0x0000000721b00000, 0x0000000721c00000| 0%| F| |TAMS 0x0000000721b00000, 0x0000000721b00000| Untracked -| 416|0x0000000721c00000, 0x0000000721c00000, 0x0000000721d00000| 0%| F| |TAMS 0x0000000721c00000, 0x0000000721c00000| Untracked -| 417|0x0000000721d00000, 0x0000000721d00000, 0x0000000721e00000| 0%| F| |TAMS 0x0000000721d00000, 0x0000000721d00000| Untracked -| 418|0x0000000721e00000, 0x0000000721e00000, 0x0000000721f00000| 0%| F| |TAMS 0x0000000721e00000, 0x0000000721e00000| Untracked -| 419|0x0000000721f00000, 0x0000000721f00000, 0x0000000722000000| 0%| F| |TAMS 0x0000000721f00000, 0x0000000721f00000| Untracked -| 420|0x0000000722000000, 0x0000000722000000, 0x0000000722100000| 0%| F| |TAMS 0x0000000722000000, 0x0000000722000000| Untracked -| 421|0x0000000722100000, 0x0000000722100000, 0x0000000722200000| 0%| F| |TAMS 0x0000000722100000, 0x0000000722100000| Untracked -| 422|0x0000000722200000, 0x0000000722200000, 0x0000000722300000| 0%| F| |TAMS 0x0000000722200000, 0x0000000722200000| Untracked -| 423|0x0000000722300000, 0x0000000722300000, 0x0000000722400000| 0%| F| |TAMS 0x0000000722300000, 0x0000000722300000| Untracked -| 424|0x0000000722400000, 0x0000000722400000, 0x0000000722500000| 0%| F| |TAMS 0x0000000722400000, 0x0000000722400000| Untracked -| 425|0x0000000722500000, 0x0000000722500000, 0x0000000722600000| 0%| F| |TAMS 0x0000000722500000, 0x0000000722500000| Untracked -| 426|0x0000000722600000, 0x0000000722600000, 0x0000000722700000| 0%| F| |TAMS 0x0000000722600000, 0x0000000722600000| Untracked -| 427|0x0000000722700000, 0x0000000722700000, 0x0000000722800000| 0%| F| |TAMS 0x0000000722700000, 0x0000000722700000| Untracked -| 428|0x0000000722800000, 0x0000000722800000, 0x0000000722900000| 0%| F| |TAMS 0x0000000722800000, 0x0000000722800000| Untracked -| 429|0x0000000722900000, 0x0000000722900000, 0x0000000722a00000| 0%| F| |TAMS 0x0000000722900000, 0x0000000722900000| Untracked -| 430|0x0000000722a00000, 0x0000000722a00000, 0x0000000722b00000| 0%| F| |TAMS 0x0000000722a00000, 0x0000000722a00000| Untracked -| 431|0x0000000722b00000, 0x0000000722b00000, 0x0000000722c00000| 0%| F| |TAMS 0x0000000722b00000, 0x0000000722b00000| Untracked -| 432|0x0000000722c00000, 0x0000000722c00000, 0x0000000722d00000| 0%| F| |TAMS 0x0000000722c00000, 0x0000000722c00000| Untracked -| 433|0x0000000722d00000, 0x0000000722d00000, 0x0000000722e00000| 0%| F| |TAMS 0x0000000722d00000, 0x0000000722d00000| Untracked -| 434|0x0000000722e00000, 0x0000000722e00000, 0x0000000722f00000| 0%| F| |TAMS 0x0000000722e00000, 0x0000000722e00000| Untracked -| 435|0x0000000722f00000, 0x0000000722f00000, 0x0000000723000000| 0%| F| |TAMS 0x0000000722f00000, 0x0000000722f00000| Untracked -| 436|0x0000000723000000, 0x0000000723000000, 0x0000000723100000| 0%| F| |TAMS 0x0000000723000000, 0x0000000723000000| Untracked -| 437|0x0000000723100000, 0x0000000723100000, 0x0000000723200000| 0%| F| |TAMS 0x0000000723100000, 0x0000000723100000| Untracked -| 438|0x0000000723200000, 0x0000000723200000, 0x0000000723300000| 0%| F| |TAMS 0x0000000723200000, 0x0000000723200000| Untracked -| 439|0x0000000723300000, 0x0000000723300000, 0x0000000723400000| 0%| F| |TAMS 0x0000000723300000, 0x0000000723300000| Untracked -| 440|0x0000000723400000, 0x0000000723400000, 0x0000000723500000| 0%| F| |TAMS 0x0000000723400000, 0x0000000723400000| Untracked -| 441|0x0000000723500000, 0x0000000723500000, 0x0000000723600000| 0%| F| |TAMS 0x0000000723500000, 0x0000000723500000| Untracked -| 442|0x0000000723600000, 0x0000000723600000, 0x0000000723700000| 0%| F| |TAMS 0x0000000723600000, 0x0000000723600000| Untracked -| 443|0x0000000723700000, 0x0000000723700000, 0x0000000723800000| 0%| F| |TAMS 0x0000000723700000, 0x0000000723700000| Untracked -| 444|0x0000000723800000, 0x0000000723800000, 0x0000000723900000| 0%| F| |TAMS 0x0000000723800000, 0x0000000723800000| Untracked -| 445|0x0000000723900000, 0x0000000723900000, 0x0000000723a00000| 0%| F| |TAMS 0x0000000723900000, 0x0000000723900000| Untracked -| 446|0x0000000723a00000, 0x0000000723b00000, 0x0000000723b00000|100%| O| |TAMS 0x0000000723b00000, 0x0000000723a00000| Untracked -| 447|0x0000000723b00000, 0x0000000723b00000, 0x0000000723c00000| 0%| F| |TAMS 0x0000000723b00000, 0x0000000723b00000| Untracked -| 448|0x0000000723c00000, 0x0000000723c00000, 0x0000000723d00000| 0%| F| |TAMS 0x0000000723c00000, 0x0000000723c00000| Untracked -| 449|0x0000000723d00000, 0x0000000723d00000, 0x0000000723e00000| 0%| F| |TAMS 0x0000000723d00000, 0x0000000723d00000| Untracked -| 450|0x0000000723e00000, 0x0000000723e00000, 0x0000000723f00000| 0%| F| |TAMS 0x0000000723e00000, 0x0000000723e00000| Untracked -| 451|0x0000000723f00000, 0x0000000723f00000, 0x0000000724000000| 0%| F| |TAMS 0x0000000723f00000, 0x0000000723f00000| Untracked -| 452|0x0000000724000000, 0x0000000724000000, 0x0000000724100000| 0%| F| |TAMS 0x0000000724000000, 0x0000000724000000| Untracked -| 453|0x0000000724100000, 0x0000000724100000, 0x0000000724200000| 0%| F| |TAMS 0x0000000724100000, 0x0000000724100000| Untracked -| 454|0x0000000724200000, 0x0000000724200000, 0x0000000724300000| 0%| F| |TAMS 0x0000000724200000, 0x0000000724200000| Untracked -| 455|0x0000000724300000, 0x0000000724300000, 0x0000000724400000| 0%| F| |TAMS 0x0000000724300000, 0x0000000724300000| Untracked -| 456|0x0000000724400000, 0x0000000724400000, 0x0000000724500000| 0%| F| |TAMS 0x0000000724400000, 0x0000000724400000| Untracked -| 457|0x0000000724500000, 0x0000000724500000, 0x0000000724600000| 0%| F| |TAMS 0x0000000724500000, 0x0000000724500000| Untracked -| 458|0x0000000724600000, 0x0000000724600000, 0x0000000724700000| 0%| F| |TAMS 0x0000000724600000, 0x0000000724600000| Untracked -| 459|0x0000000724700000, 0x0000000724700000, 0x0000000724800000| 0%| F| |TAMS 0x0000000724700000, 0x0000000724700000| Untracked -| 460|0x0000000724800000, 0x0000000724800000, 0x0000000724900000| 0%| F| |TAMS 0x0000000724800000, 0x0000000724800000| Untracked -| 461|0x0000000724900000, 0x0000000724900000, 0x0000000724a00000| 0%| F| |TAMS 0x0000000724900000, 0x0000000724900000| Untracked -| 462|0x0000000724a00000, 0x0000000724a00000, 0x0000000724b00000| 0%| F| |TAMS 0x0000000724a00000, 0x0000000724a00000| Untracked -| 463|0x0000000724b00000, 0x0000000724b00000, 0x0000000724c00000| 0%| F| |TAMS 0x0000000724b00000, 0x0000000724b00000| Untracked -| 464|0x0000000724c00000, 0x0000000724c00000, 0x0000000724d00000| 0%| F| |TAMS 0x0000000724c00000, 0x0000000724c00000| Untracked -| 465|0x0000000724d00000, 0x0000000724d00000, 0x0000000724e00000| 0%| F| |TAMS 0x0000000724d00000, 0x0000000724d00000| Untracked -| 466|0x0000000724e00000, 0x0000000724e00000, 0x0000000724f00000| 0%| F| |TAMS 0x0000000724e00000, 0x0000000724e00000| Untracked -| 467|0x0000000724f00000, 0x0000000724f00000, 0x0000000725000000| 0%| F| |TAMS 0x0000000724f00000, 0x0000000724f00000| Untracked -| 468|0x0000000725000000, 0x0000000725000000, 0x0000000725100000| 0%| F| |TAMS 0x0000000725000000, 0x0000000725000000| Untracked -| 469|0x0000000725100000, 0x0000000725100000, 0x0000000725200000| 0%| F| |TAMS 0x0000000725100000, 0x0000000725100000| Untracked -| 470|0x0000000725200000, 0x0000000725200000, 0x0000000725300000| 0%| F| |TAMS 0x0000000725200000, 0x0000000725200000| Untracked -| 471|0x0000000725300000, 0x0000000725300000, 0x0000000725400000| 0%| F| |TAMS 0x0000000725300000, 0x0000000725300000| Untracked -| 472|0x0000000725400000, 0x0000000725400000, 0x0000000725500000| 0%| F| |TAMS 0x0000000725400000, 0x0000000725400000| Untracked -| 473|0x0000000725500000, 0x0000000725500000, 0x0000000725600000| 0%| F| |TAMS 0x0000000725500000, 0x0000000725500000| Untracked -| 474|0x0000000725600000, 0x0000000725600000, 0x0000000725700000| 0%| F| |TAMS 0x0000000725600000, 0x0000000725600000| Untracked -| 475|0x0000000725700000, 0x0000000725700000, 0x0000000725800000| 0%| F| |TAMS 0x0000000725700000, 0x0000000725700000| Untracked -| 476|0x0000000725800000, 0x0000000725800000, 0x0000000725900000| 0%| F| |TAMS 0x0000000725800000, 0x0000000725800000| Untracked -| 477|0x0000000725900000, 0x0000000725900000, 0x0000000725a00000| 0%| F| |TAMS 0x0000000725900000, 0x0000000725900000| Untracked -| 478|0x0000000725a00000, 0x0000000725a00000, 0x0000000725b00000| 0%| F| |TAMS 0x0000000725a00000, 0x0000000725a00000| Untracked -| 479|0x0000000725b00000, 0x0000000725b00000, 0x0000000725c00000| 0%| F| |TAMS 0x0000000725b00000, 0x0000000725b00000| Untracked -| 480|0x0000000725c00000, 0x0000000725c00000, 0x0000000725d00000| 0%| F| |TAMS 0x0000000725c00000, 0x0000000725c00000| Untracked -| 481|0x0000000725d00000, 0x0000000725d00000, 0x0000000725e00000| 0%| F| |TAMS 0x0000000725d00000, 0x0000000725d00000| Untracked -| 482|0x0000000725e00000, 0x0000000725e00000, 0x0000000725f00000| 0%| F| |TAMS 0x0000000725e00000, 0x0000000725e00000| Untracked -| 483|0x0000000725f00000, 0x0000000725f00000, 0x0000000726000000| 0%| F| |TAMS 0x0000000725f00000, 0x0000000725f00000| Untracked -| 484|0x0000000726000000, 0x0000000726000000, 0x0000000726100000| 0%| F| |TAMS 0x0000000726000000, 0x0000000726000000| Untracked -| 485|0x0000000726100000, 0x0000000726100000, 0x0000000726200000| 0%| F| |TAMS 0x0000000726100000, 0x0000000726100000| Untracked -| 486|0x0000000726200000, 0x0000000726200000, 0x0000000726300000| 0%| F| |TAMS 0x0000000726200000, 0x0000000726200000| Untracked -| 487|0x0000000726300000, 0x0000000726300000, 0x0000000726400000| 0%| F| |TAMS 0x0000000726300000, 0x0000000726300000| Untracked -| 488|0x0000000726400000, 0x0000000726400000, 0x0000000726500000| 0%| F| |TAMS 0x0000000726400000, 0x0000000726400000| Untracked -| 489|0x0000000726500000, 0x0000000726500000, 0x0000000726600000| 0%| F| |TAMS 0x0000000726500000, 0x0000000726500000| Untracked -| 490|0x0000000726600000, 0x0000000726600000, 0x0000000726700000| 0%| F| |TAMS 0x0000000726600000, 0x0000000726600000| Untracked -| 491|0x0000000726700000, 0x0000000726700000, 0x0000000726800000| 0%| F| |TAMS 0x0000000726700000, 0x0000000726700000| Untracked -| 492|0x0000000726800000, 0x0000000726800000, 0x0000000726900000| 0%| F| |TAMS 0x0000000726800000, 0x0000000726800000| Untracked -| 493|0x0000000726900000, 0x0000000726900000, 0x0000000726a00000| 0%| F| |TAMS 0x0000000726900000, 0x0000000726900000| Untracked -| 494|0x0000000726a00000, 0x0000000726a00000, 0x0000000726b00000| 0%| F| |TAMS 0x0000000726a00000, 0x0000000726a00000| Untracked -| 495|0x0000000726b00000, 0x0000000726b00000, 0x0000000726c00000| 0%| F| |TAMS 0x0000000726b00000, 0x0000000726b00000| Untracked -| 496|0x0000000726c00000, 0x0000000726c00000, 0x0000000726d00000| 0%| F| |TAMS 0x0000000726c00000, 0x0000000726c00000| Untracked -| 497|0x0000000726d00000, 0x0000000726d00000, 0x0000000726e00000| 0%| F| |TAMS 0x0000000726d00000, 0x0000000726d00000| Untracked -| 498|0x0000000726e00000, 0x0000000726e00000, 0x0000000726f00000| 0%| F| |TAMS 0x0000000726e00000, 0x0000000726e00000| Untracked -| 499|0x0000000726f00000, 0x0000000726f00000, 0x0000000727000000| 0%| F| |TAMS 0x0000000726f00000, 0x0000000726f00000| Untracked -| 500|0x0000000727000000, 0x0000000727000000, 0x0000000727100000| 0%| F| |TAMS 0x0000000727000000, 0x0000000727000000| Untracked -| 501|0x0000000727100000, 0x0000000727100000, 0x0000000727200000| 0%| F| |TAMS 0x0000000727100000, 0x0000000727100000| Untracked -| 502|0x0000000727200000, 0x0000000727200000, 0x0000000727300000| 0%| F| |TAMS 0x0000000727200000, 0x0000000727200000| Untracked -| 503|0x0000000727300000, 0x0000000727300000, 0x0000000727400000| 0%| F| |TAMS 0x0000000727300000, 0x0000000727300000| Untracked -| 504|0x0000000727400000, 0x0000000727400000, 0x0000000727500000| 0%| F| |TAMS 0x0000000727400000, 0x0000000727400000| Untracked -| 505|0x0000000727500000, 0x0000000727500000, 0x0000000727600000| 0%| F| |TAMS 0x0000000727500000, 0x0000000727500000| Untracked -| 506|0x0000000727600000, 0x0000000727600000, 0x0000000727700000| 0%| F| |TAMS 0x0000000727600000, 0x0000000727600000| Untracked -| 507|0x0000000727700000, 0x0000000727700000, 0x0000000727800000| 0%| F| |TAMS 0x0000000727700000, 0x0000000727700000| Untracked -| 508|0x0000000727800000, 0x0000000727800000, 0x0000000727900000| 0%| F| |TAMS 0x0000000727800000, 0x0000000727800000| Untracked -| 509|0x0000000727900000, 0x0000000727900000, 0x0000000727a00000| 0%| F| |TAMS 0x0000000727900000, 0x0000000727900000| Untracked -| 510|0x0000000727a00000, 0x0000000727a00000, 0x0000000727b00000| 0%| F| |TAMS 0x0000000727a00000, 0x0000000727a00000| Untracked -| 511|0x0000000727b00000, 0x0000000727b00000, 0x0000000727c00000| 0%| F| |TAMS 0x0000000727b00000, 0x0000000727b00000| Untracked -| 512|0x0000000727c00000, 0x0000000727c00000, 0x0000000727d00000| 0%| F| |TAMS 0x0000000727c00000, 0x0000000727c00000| Untracked -| 513|0x0000000727d00000, 0x0000000727d00000, 0x0000000727e00000| 0%| F| |TAMS 0x0000000727d00000, 0x0000000727d00000| Untracked -| 514|0x0000000727e00000, 0x0000000727e00000, 0x0000000727f00000| 0%| F| |TAMS 0x0000000727e00000, 0x0000000727e00000| Untracked -| 515|0x0000000727f00000, 0x0000000727f00000, 0x0000000728000000| 0%| F| |TAMS 0x0000000727f00000, 0x0000000727f00000| Untracked -| 516|0x0000000728000000, 0x0000000728000000, 0x0000000728100000| 0%| F| |TAMS 0x0000000728000000, 0x0000000728000000| Untracked -| 517|0x0000000728100000, 0x0000000728100000, 0x0000000728200000| 0%| F| |TAMS 0x0000000728100000, 0x0000000728100000| Untracked -| 518|0x0000000728200000, 0x0000000728200000, 0x0000000728300000| 0%| F| |TAMS 0x0000000728200000, 0x0000000728200000| Untracked -| 519|0x0000000728300000, 0x0000000728300000, 0x0000000728400000| 0%| F| |TAMS 0x0000000728300000, 0x0000000728300000| Untracked -| 520|0x0000000728400000, 0x0000000728400000, 0x0000000728500000| 0%| F| |TAMS 0x0000000728400000, 0x0000000728400000| Untracked -| 521|0x0000000728500000, 0x0000000728500000, 0x0000000728600000| 0%| F| |TAMS 0x0000000728500000, 0x0000000728500000| Untracked -| 522|0x0000000728600000, 0x0000000728600000, 0x0000000728700000| 0%| F| |TAMS 0x0000000728600000, 0x0000000728600000| Untracked -| 523|0x0000000728700000, 0x0000000728700000, 0x0000000728800000| 0%| F| |TAMS 0x0000000728700000, 0x0000000728700000| Untracked -| 524|0x0000000728800000, 0x0000000728800000, 0x0000000728900000| 0%| F| |TAMS 0x0000000728800000, 0x0000000728800000| Untracked -| 525|0x0000000728900000, 0x0000000728900000, 0x0000000728a00000| 0%| F| |TAMS 0x0000000728900000, 0x0000000728900000| Untracked -| 526|0x0000000728a00000, 0x0000000728a00000, 0x0000000728b00000| 0%| F| |TAMS 0x0000000728a00000, 0x0000000728a00000| Untracked -| 527|0x0000000728b00000, 0x0000000728b00000, 0x0000000728c00000| 0%| F| |TAMS 0x0000000728b00000, 0x0000000728b00000| Untracked -| 528|0x0000000728c00000, 0x0000000728c00000, 0x0000000728d00000| 0%| F| |TAMS 0x0000000728c00000, 0x0000000728c00000| Untracked -| 529|0x0000000728d00000, 0x0000000728d00000, 0x0000000728e00000| 0%| F| |TAMS 0x0000000728d00000, 0x0000000728d00000| Untracked -| 530|0x0000000728e00000, 0x0000000728e00000, 0x0000000728f00000| 0%| F| |TAMS 0x0000000728e00000, 0x0000000728e00000| Untracked -| 531|0x0000000728f00000, 0x0000000729000000, 0x0000000729000000|100%| O| |TAMS 0x0000000729000000, 0x0000000728f00000| Untracked -| 532|0x0000000729000000, 0x0000000729100000, 0x0000000729100000|100%| O| |TAMS 0x0000000729100000, 0x0000000729000000| Untracked -| 533|0x0000000729100000, 0x0000000729200000, 0x0000000729200000|100%| O| |TAMS 0x0000000729200000, 0x0000000729100000| Untracked -| 534|0x0000000729200000, 0x0000000729300000, 0x0000000729300000|100%| O| |TAMS 0x0000000729300000, 0x0000000729200000| Untracked -| 535|0x0000000729300000, 0x0000000729400000, 0x0000000729400000|100%| O| |TAMS 0x0000000729400000, 0x0000000729300000| Untracked -| 536|0x0000000729400000, 0x0000000729500000, 0x0000000729500000|100%| O| |TAMS 0x0000000729500000, 0x0000000729400000| Untracked -| 537|0x0000000729500000, 0x0000000729500000, 0x0000000729600000| 0%| F| |TAMS 0x0000000729500000, 0x0000000729500000| Untracked -| 538|0x0000000729600000, 0x0000000729600000, 0x0000000729700000| 0%| F| |TAMS 0x0000000729600000, 0x0000000729600000| Untracked -| 539|0x0000000729700000, 0x0000000729700000, 0x0000000729800000| 0%| F| |TAMS 0x0000000729700000, 0x0000000729700000| Untracked -| 540|0x0000000729800000, 0x0000000729800000, 0x0000000729900000| 0%| F| |TAMS 0x0000000729800000, 0x0000000729800000| Untracked -| 541|0x0000000729900000, 0x0000000729900000, 0x0000000729a00000| 0%| F| |TAMS 0x0000000729900000, 0x0000000729900000| Untracked -| 542|0x0000000729a00000, 0x0000000729a00000, 0x0000000729b00000| 0%| F| |TAMS 0x0000000729a00000, 0x0000000729a00000| Untracked -| 543|0x0000000729b00000, 0x0000000729b00000, 0x0000000729c00000| 0%| F| |TAMS 0x0000000729b00000, 0x0000000729b00000| Untracked -| 544|0x0000000729c00000, 0x0000000729c00000, 0x0000000729d00000| 0%| F| |TAMS 0x0000000729c00000, 0x0000000729c00000| Untracked -| 545|0x0000000729d00000, 0x0000000729d00000, 0x0000000729e00000| 0%| F| |TAMS 0x0000000729d00000, 0x0000000729d00000| Untracked -| 546|0x0000000729e00000, 0x0000000729e00000, 0x0000000729f00000| 0%| F| |TAMS 0x0000000729e00000, 0x0000000729e00000| Untracked -| 547|0x0000000729f00000, 0x0000000729f00000, 0x000000072a000000| 0%| F| |TAMS 0x0000000729f00000, 0x0000000729f00000| Untracked -| 548|0x000000072a000000, 0x000000072a000000, 0x000000072a100000| 0%| F| |TAMS 0x000000072a000000, 0x000000072a000000| Untracked -| 549|0x000000072a100000, 0x000000072a100000, 0x000000072a200000| 0%| F| |TAMS 0x000000072a100000, 0x000000072a100000| Untracked -| 550|0x000000072a200000, 0x000000072a200000, 0x000000072a300000| 0%| F| |TAMS 0x000000072a200000, 0x000000072a200000| Untracked -| 551|0x000000072a300000, 0x000000072a300000, 0x000000072a400000| 0%| F| |TAMS 0x000000072a300000, 0x000000072a300000| Untracked -| 552|0x000000072a400000, 0x000000072a400000, 0x000000072a500000| 0%| F| |TAMS 0x000000072a400000, 0x000000072a400000| Untracked -| 553|0x000000072a500000, 0x000000072a500000, 0x000000072a600000| 0%| F| |TAMS 0x000000072a500000, 0x000000072a500000| Untracked -| 554|0x000000072a600000, 0x000000072a600000, 0x000000072a700000| 0%| F| |TAMS 0x000000072a600000, 0x000000072a600000| Untracked -| 555|0x000000072a700000, 0x000000072a700000, 0x000000072a800000| 0%| F| |TAMS 0x000000072a700000, 0x000000072a700000| Untracked -| 556|0x000000072a800000, 0x000000072a800000, 0x000000072a900000| 0%| F| |TAMS 0x000000072a800000, 0x000000072a800000| Untracked -| 557|0x000000072a900000, 0x000000072a900000, 0x000000072aa00000| 0%| F| |TAMS 0x000000072a900000, 0x000000072a900000| Untracked -| 558|0x000000072aa00000, 0x000000072aa00000, 0x000000072ab00000| 0%| F| |TAMS 0x000000072aa00000, 0x000000072aa00000| Untracked -| 559|0x000000072ab00000, 0x000000072ab00000, 0x000000072ac00000| 0%| F| |TAMS 0x000000072ab00000, 0x000000072ab00000| Untracked -| 560|0x000000072ac00000, 0x000000072ac00000, 0x000000072ad00000| 0%| F| |TAMS 0x000000072ac00000, 0x000000072ac00000| Untracked -| 561|0x000000072ad00000, 0x000000072ad00000, 0x000000072ae00000| 0%| F| |TAMS 0x000000072ad00000, 0x000000072ad00000| Untracked -| 562|0x000000072ae00000, 0x000000072ae00000, 0x000000072af00000| 0%| F| |TAMS 0x000000072ae00000, 0x000000072ae00000| Untracked -| 563|0x000000072af00000, 0x000000072af00000, 0x000000072b000000| 0%| F| |TAMS 0x000000072af00000, 0x000000072af00000| Untracked -| 564|0x000000072b000000, 0x000000072b000000, 0x000000072b100000| 0%| F| |TAMS 0x000000072b000000, 0x000000072b000000| Untracked -| 565|0x000000072b100000, 0x000000072b100000, 0x000000072b200000| 0%| F| |TAMS 0x000000072b100000, 0x000000072b100000| Untracked -| 566|0x000000072b200000, 0x000000072b200000, 0x000000072b300000| 0%| F| |TAMS 0x000000072b200000, 0x000000072b200000| Untracked -| 567|0x000000072b300000, 0x000000072b300000, 0x000000072b400000| 0%| F| |TAMS 0x000000072b300000, 0x000000072b300000| Untracked -| 568|0x000000072b400000, 0x000000072b400000, 0x000000072b500000| 0%| F| |TAMS 0x000000072b400000, 0x000000072b400000| Untracked -| 569|0x000000072b500000, 0x000000072b500000, 0x000000072b600000| 0%| F| |TAMS 0x000000072b500000, 0x000000072b500000| Untracked -| 570|0x000000072b600000, 0x000000072b600000, 0x000000072b700000| 0%| F| |TAMS 0x000000072b600000, 0x000000072b600000| Untracked -| 571|0x000000072b700000, 0x000000072b700000, 0x000000072b800000| 0%| F| |TAMS 0x000000072b700000, 0x000000072b700000| Untracked -| 572|0x000000072b800000, 0x000000072b800000, 0x000000072b900000| 0%| F| |TAMS 0x000000072b800000, 0x000000072b800000| Untracked -| 573|0x000000072b900000, 0x000000072b900000, 0x000000072ba00000| 0%| F| |TAMS 0x000000072b900000, 0x000000072b900000| Untracked -| 574|0x000000072ba00000, 0x000000072ba00000, 0x000000072bb00000| 0%| F| |TAMS 0x000000072ba00000, 0x000000072ba00000| Untracked -| 575|0x000000072bb00000, 0x000000072bb00000, 0x000000072bc00000| 0%| F| |TAMS 0x000000072bb00000, 0x000000072bb00000| Untracked -| 576|0x000000072bc00000, 0x000000072bc00000, 0x000000072bd00000| 0%| F| |TAMS 0x000000072bc00000, 0x000000072bc00000| Untracked -| 577|0x000000072bd00000, 0x000000072bd00000, 0x000000072be00000| 0%| F| |TAMS 0x000000072bd00000, 0x000000072bd00000| Untracked -| 578|0x000000072be00000, 0x000000072be00000, 0x000000072bf00000| 0%| F| |TAMS 0x000000072be00000, 0x000000072be00000| Untracked -| 579|0x000000072bf00000, 0x000000072bf00000, 0x000000072c000000| 0%| F| |TAMS 0x000000072bf00000, 0x000000072bf00000| Untracked -| 580|0x000000072c000000, 0x000000072c000000, 0x000000072c100000| 0%| F| |TAMS 0x000000072c000000, 0x000000072c000000| Untracked -| 581|0x000000072c100000, 0x000000072c100000, 0x000000072c200000| 0%| F| |TAMS 0x000000072c100000, 0x000000072c100000| Untracked -| 582|0x000000072c200000, 0x000000072c200000, 0x000000072c300000| 0%| F| |TAMS 0x000000072c200000, 0x000000072c200000| Untracked -| 583|0x000000072c300000, 0x000000072c300000, 0x000000072c400000| 0%| F| |TAMS 0x000000072c300000, 0x000000072c300000| Untracked -| 584|0x000000072c400000, 0x000000072c400000, 0x000000072c500000| 0%| F| |TAMS 0x000000072c400000, 0x000000072c400000| Untracked -| 585|0x000000072c500000, 0x000000072c500000, 0x000000072c600000| 0%| F| |TAMS 0x000000072c500000, 0x000000072c500000| Untracked -| 586|0x000000072c600000, 0x000000072c600000, 0x000000072c700000| 0%| F| |TAMS 0x000000072c600000, 0x000000072c600000| Untracked -| 587|0x000000072c700000, 0x000000072c700000, 0x000000072c800000| 0%| F| |TAMS 0x000000072c700000, 0x000000072c700000| Untracked -| 588|0x000000072c800000, 0x000000072c800000, 0x000000072c900000| 0%| F| |TAMS 0x000000072c800000, 0x000000072c800000| Untracked -| 589|0x000000072c900000, 0x000000072c900000, 0x000000072ca00000| 0%| F| |TAMS 0x000000072c900000, 0x000000072c900000| Untracked -| 590|0x000000072ca00000, 0x000000072ca00000, 0x000000072cb00000| 0%| F| |TAMS 0x000000072ca00000, 0x000000072ca00000| Untracked -| 591|0x000000072cb00000, 0x000000072cb00000, 0x000000072cc00000| 0%| F| |TAMS 0x000000072cb00000, 0x000000072cb00000| Untracked -| 592|0x000000072cc00000, 0x000000072cc00000, 0x000000072cd00000| 0%| F| |TAMS 0x000000072cc00000, 0x000000072cc00000| Untracked -| 593|0x000000072cd00000, 0x000000072cd00000, 0x000000072ce00000| 0%| F| |TAMS 0x000000072cd00000, 0x000000072cd00000| Untracked -| 594|0x000000072ce00000, 0x000000072ce00000, 0x000000072cf00000| 0%| F| |TAMS 0x000000072ce00000, 0x000000072ce00000| Untracked -| 595|0x000000072cf00000, 0x000000072cf00000, 0x000000072d000000| 0%| F| |TAMS 0x000000072cf00000, 0x000000072cf00000| Untracked -| 596|0x000000072d000000, 0x000000072d000000, 0x000000072d100000| 0%| F| |TAMS 0x000000072d000000, 0x000000072d000000| Untracked -| 597|0x000000072d100000, 0x000000072d100000, 0x000000072d200000| 0%| F| |TAMS 0x000000072d100000, 0x000000072d100000| Untracked -| 598|0x000000072d200000, 0x000000072d200000, 0x000000072d300000| 0%| F| |TAMS 0x000000072d200000, 0x000000072d200000| Untracked -| 599|0x000000072d300000, 0x000000072d300000, 0x000000072d400000| 0%| F| |TAMS 0x000000072d300000, 0x000000072d300000| Untracked -| 600|0x000000072d400000, 0x000000072d400000, 0x000000072d500000| 0%| F| |TAMS 0x000000072d400000, 0x000000072d400000| Untracked -| 601|0x000000072d500000, 0x000000072d500000, 0x000000072d600000| 0%| F| |TAMS 0x000000072d500000, 0x000000072d500000| Untracked -| 602|0x000000072d600000, 0x000000072d600000, 0x000000072d700000| 0%| F| |TAMS 0x000000072d600000, 0x000000072d600000| Untracked -| 603|0x000000072d700000, 0x000000072d700000, 0x000000072d800000| 0%| F| |TAMS 0x000000072d700000, 0x000000072d700000| Untracked -| 604|0x000000072d800000, 0x000000072d800000, 0x000000072d900000| 0%| F| |TAMS 0x000000072d800000, 0x000000072d800000| Untracked -| 605|0x000000072d900000, 0x000000072d900000, 0x000000072da00000| 0%| F| |TAMS 0x000000072d900000, 0x000000072d900000| Untracked -| 606|0x000000072da00000, 0x000000072da00000, 0x000000072db00000| 0%| F| |TAMS 0x000000072da00000, 0x000000072da00000| Untracked -| 607|0x000000072db00000, 0x000000072db00000, 0x000000072dc00000| 0%| F| |TAMS 0x000000072db00000, 0x000000072db00000| Untracked -| 608|0x000000072dc00000, 0x000000072dc00000, 0x000000072dd00000| 0%| F| |TAMS 0x000000072dc00000, 0x000000072dc00000| Untracked -| 609|0x000000072dd00000, 0x000000072dd00000, 0x000000072de00000| 0%| F| |TAMS 0x000000072dd00000, 0x000000072dd00000| Untracked -| 610|0x000000072de00000, 0x000000072de00000, 0x000000072df00000| 0%| F| |TAMS 0x000000072de00000, 0x000000072de00000| Untracked -| 611|0x000000072df00000, 0x000000072df00000, 0x000000072e000000| 0%| F| |TAMS 0x000000072df00000, 0x000000072df00000| Untracked -| 612|0x000000072e000000, 0x000000072e000000, 0x000000072e100000| 0%| F| |TAMS 0x000000072e000000, 0x000000072e000000| Untracked -| 613|0x000000072e100000, 0x000000072e100000, 0x000000072e200000| 0%| F| |TAMS 0x000000072e100000, 0x000000072e100000| Untracked -| 614|0x000000072e200000, 0x000000072e200000, 0x000000072e300000| 0%| F| |TAMS 0x000000072e200000, 0x000000072e200000| Untracked -| 615|0x000000072e300000, 0x000000072e300000, 0x000000072e400000| 0%| F| |TAMS 0x000000072e300000, 0x000000072e300000| Untracked -| 616|0x000000072e400000, 0x000000072e400000, 0x000000072e500000| 0%| F| |TAMS 0x000000072e400000, 0x000000072e400000| Untracked -| 617|0x000000072e500000, 0x000000072e500000, 0x000000072e600000| 0%| F| |TAMS 0x000000072e500000, 0x000000072e500000| Untracked -| 618|0x000000072e600000, 0x000000072e600000, 0x000000072e700000| 0%| F| |TAMS 0x000000072e600000, 0x000000072e600000| Untracked -| 619|0x000000072e700000, 0x000000072e700000, 0x000000072e800000| 0%| F| |TAMS 0x000000072e700000, 0x000000072e700000| Untracked -| 620|0x000000072e800000, 0x000000072e800000, 0x000000072e900000| 0%| F| |TAMS 0x000000072e800000, 0x000000072e800000| Untracked -| 621|0x000000072e900000, 0x000000072e900000, 0x000000072ea00000| 0%| F| |TAMS 0x000000072e900000, 0x000000072e900000| Untracked -| 622|0x000000072ea00000, 0x000000072ea00000, 0x000000072eb00000| 0%| F| |TAMS 0x000000072ea00000, 0x000000072ea00000| Untracked -| 623|0x000000072eb00000, 0x000000072eb00000, 0x000000072ec00000| 0%| F| |TAMS 0x000000072eb00000, 0x000000072eb00000| Untracked -| 624|0x000000072ec00000, 0x000000072ec00000, 0x000000072ed00000| 0%| F| |TAMS 0x000000072ec00000, 0x000000072ec00000| Untracked -| 625|0x000000072ed00000, 0x000000072ed00000, 0x000000072ee00000| 0%| F| |TAMS 0x000000072ed00000, 0x000000072ed00000| Untracked -| 626|0x000000072ee00000, 0x000000072ee00000, 0x000000072ef00000| 0%| F| |TAMS 0x000000072ee00000, 0x000000072ee00000| Untracked -| 627|0x000000072ef00000, 0x000000072ef00000, 0x000000072f000000| 0%| F| |TAMS 0x000000072ef00000, 0x000000072ef00000| Untracked -| 628|0x000000072f000000, 0x000000072f000000, 0x000000072f100000| 0%| F| |TAMS 0x000000072f000000, 0x000000072f000000| Untracked -| 629|0x000000072f100000, 0x000000072f100000, 0x000000072f200000| 0%| F| |TAMS 0x000000072f100000, 0x000000072f100000| Untracked -| 630|0x000000072f200000, 0x000000072f200000, 0x000000072f300000| 0%| F| |TAMS 0x000000072f200000, 0x000000072f200000| Untracked -| 631|0x000000072f300000, 0x000000072f300000, 0x000000072f400000| 0%| F| |TAMS 0x000000072f300000, 0x000000072f300000| Untracked -| 632|0x000000072f400000, 0x000000072f400000, 0x000000072f500000| 0%| F| |TAMS 0x000000072f400000, 0x000000072f400000| Untracked -| 633|0x000000072f500000, 0x000000072f500000, 0x000000072f600000| 0%| F| |TAMS 0x000000072f500000, 0x000000072f500000| Untracked -| 634|0x000000072f600000, 0x000000072f600000, 0x000000072f700000| 0%| F| |TAMS 0x000000072f600000, 0x000000072f600000| Untracked -| 635|0x000000072f700000, 0x000000072f700000, 0x000000072f800000| 0%| F| |TAMS 0x000000072f700000, 0x000000072f700000| Untracked -| 636|0x000000072f800000, 0x000000072f800000, 0x000000072f900000| 0%| F| |TAMS 0x000000072f800000, 0x000000072f800000| Untracked -| 637|0x000000072f900000, 0x000000072f900000, 0x000000072fa00000| 0%| F| |TAMS 0x000000072f900000, 0x000000072f900000| Untracked -| 638|0x000000072fa00000, 0x000000072fa00000, 0x000000072fb00000| 0%| F| |TAMS 0x000000072fa00000, 0x000000072fa00000| Untracked -| 639|0x000000072fb00000, 0x000000072fb00000, 0x000000072fc00000| 0%| F| |TAMS 0x000000072fb00000, 0x000000072fb00000| Untracked -| 640|0x000000072fc00000, 0x000000072fc00000, 0x000000072fd00000| 0%| F| |TAMS 0x000000072fc00000, 0x000000072fc00000| Untracked -| 641|0x000000072fd00000, 0x000000072fd00000, 0x000000072fe00000| 0%| F| |TAMS 0x000000072fd00000, 0x000000072fd00000| Untracked -| 642|0x000000072fe00000, 0x000000072fe00000, 0x000000072ff00000| 0%| F| |TAMS 0x000000072fe00000, 0x000000072fe00000| Untracked -| 643|0x000000072ff00000, 0x000000072ff00000, 0x0000000730000000| 0%| F| |TAMS 0x000000072ff00000, 0x000000072ff00000| Untracked -| 644|0x0000000730000000, 0x0000000730000000, 0x0000000730100000| 0%| F| |TAMS 0x0000000730000000, 0x0000000730000000| Untracked -| 645|0x0000000730100000, 0x0000000730100000, 0x0000000730200000| 0%| F| |TAMS 0x0000000730100000, 0x0000000730100000| Untracked -| 646|0x0000000730200000, 0x0000000730200000, 0x0000000730300000| 0%| F| |TAMS 0x0000000730200000, 0x0000000730200000| Untracked -| 647|0x0000000730300000, 0x0000000730300000, 0x0000000730400000| 0%| F| |TAMS 0x0000000730300000, 0x0000000730300000| Untracked -| 648|0x0000000730400000, 0x0000000730400000, 0x0000000730500000| 0%| F| |TAMS 0x0000000730400000, 0x0000000730400000| Untracked -| 649|0x0000000730500000, 0x0000000730500000, 0x0000000730600000| 0%| F| |TAMS 0x0000000730500000, 0x0000000730500000| Untracked -| 650|0x0000000730600000, 0x0000000730600000, 0x0000000730700000| 0%| F| |TAMS 0x0000000730600000, 0x0000000730600000| Untracked -| 651|0x0000000730700000, 0x0000000730700000, 0x0000000730800000| 0%| F| |TAMS 0x0000000730700000, 0x0000000730700000| Untracked -| 652|0x0000000730800000, 0x0000000730800000, 0x0000000730900000| 0%| F| |TAMS 0x0000000730800000, 0x0000000730800000| Untracked -| 653|0x0000000730900000, 0x0000000730900000, 0x0000000730a00000| 0%| F| |TAMS 0x0000000730900000, 0x0000000730900000| Untracked -| 654|0x0000000730a00000, 0x0000000730a00000, 0x0000000730b00000| 0%| F| |TAMS 0x0000000730a00000, 0x0000000730a00000| Untracked -| 655|0x0000000730b00000, 0x0000000730b00000, 0x0000000730c00000| 0%| F| |TAMS 0x0000000730b00000, 0x0000000730b00000| Untracked -| 656|0x0000000730c00000, 0x0000000730c00000, 0x0000000730d00000| 0%| F| |TAMS 0x0000000730c00000, 0x0000000730c00000| Untracked -| 657|0x0000000730d00000, 0x0000000730d00000, 0x0000000730e00000| 0%| F| |TAMS 0x0000000730d00000, 0x0000000730d00000| Untracked -| 658|0x0000000730e00000, 0x0000000730e00000, 0x0000000730f00000| 0%| F| |TAMS 0x0000000730e00000, 0x0000000730e00000| Untracked -| 659|0x0000000730f00000, 0x0000000730f00000, 0x0000000731000000| 0%| F| |TAMS 0x0000000730f00000, 0x0000000730f00000| Untracked -| 660|0x0000000731000000, 0x0000000731000000, 0x0000000731100000| 0%| F| |TAMS 0x0000000731000000, 0x0000000731000000| Untracked -| 661|0x0000000731100000, 0x0000000731100000, 0x0000000731200000| 0%| F| |TAMS 0x0000000731100000, 0x0000000731100000| Untracked -| 662|0x0000000731200000, 0x0000000731200000, 0x0000000731300000| 0%| F| |TAMS 0x0000000731200000, 0x0000000731200000| Untracked -| 663|0x0000000731300000, 0x0000000731300000, 0x0000000731400000| 0%| F| |TAMS 0x0000000731300000, 0x0000000731300000| Untracked -| 664|0x0000000731400000, 0x0000000731400000, 0x0000000731500000| 0%| F| |TAMS 0x0000000731400000, 0x0000000731400000| Untracked -| 665|0x0000000731500000, 0x0000000731500000, 0x0000000731600000| 0%| F| |TAMS 0x0000000731500000, 0x0000000731500000| Untracked -| 666|0x0000000731600000, 0x0000000731600000, 0x0000000731700000| 0%| F| |TAMS 0x0000000731600000, 0x0000000731600000| Untracked -| 667|0x0000000731700000, 0x0000000731700000, 0x0000000731800000| 0%| F| |TAMS 0x0000000731700000, 0x0000000731700000| Untracked -| 668|0x0000000731800000, 0x0000000731800000, 0x0000000731900000| 0%| F| |TAMS 0x0000000731800000, 0x0000000731800000| Untracked -| 669|0x0000000731900000, 0x0000000731900000, 0x0000000731a00000| 0%| F| |TAMS 0x0000000731900000, 0x0000000731900000| Untracked -| 670|0x0000000731a00000, 0x0000000731a00000, 0x0000000731b00000| 0%| F| |TAMS 0x0000000731a00000, 0x0000000731a00000| Untracked -| 671|0x0000000731b00000, 0x0000000731b00000, 0x0000000731c00000| 0%| F| |TAMS 0x0000000731b00000, 0x0000000731b00000| Untracked -| 672|0x0000000731c00000, 0x0000000731c00000, 0x0000000731d00000| 0%| F| |TAMS 0x0000000731c00000, 0x0000000731c00000| Untracked -| 673|0x0000000731d00000, 0x0000000731d00000, 0x0000000731e00000| 0%| F| |TAMS 0x0000000731d00000, 0x0000000731d00000| Untracked -| 674|0x0000000731e00000, 0x0000000731e00000, 0x0000000731f00000| 0%| F| |TAMS 0x0000000731e00000, 0x0000000731e00000| Untracked -| 675|0x0000000731f00000, 0x0000000731f00000, 0x0000000732000000| 0%| F| |TAMS 0x0000000731f00000, 0x0000000731f00000| Untracked -| 676|0x0000000732000000, 0x0000000732000000, 0x0000000732100000| 0%| F| |TAMS 0x0000000732000000, 0x0000000732000000| Untracked -| 677|0x0000000732100000, 0x0000000732100000, 0x0000000732200000| 0%| F| |TAMS 0x0000000732100000, 0x0000000732100000| Untracked -| 678|0x0000000732200000, 0x0000000732200000, 0x0000000732300000| 0%| F| |TAMS 0x0000000732200000, 0x0000000732200000| Untracked -| 679|0x0000000732300000, 0x0000000732300000, 0x0000000732400000| 0%| F| |TAMS 0x0000000732300000, 0x0000000732300000| Untracked -| 680|0x0000000732400000, 0x0000000732400000, 0x0000000732500000| 0%| F| |TAMS 0x0000000732400000, 0x0000000732400000| Untracked -| 681|0x0000000732500000, 0x0000000732500000, 0x0000000732600000| 0%| F| |TAMS 0x0000000732500000, 0x0000000732500000| Untracked -| 682|0x0000000732600000, 0x0000000732600000, 0x0000000732700000| 0%| F| |TAMS 0x0000000732600000, 0x0000000732600000| Untracked -| 683|0x0000000732700000, 0x0000000732700000, 0x0000000732800000| 0%| F| |TAMS 0x0000000732700000, 0x0000000732700000| Untracked -| 684|0x0000000732800000, 0x0000000732800000, 0x0000000732900000| 0%| F| |TAMS 0x0000000732800000, 0x0000000732800000| Untracked -| 685|0x0000000732900000, 0x0000000732900000, 0x0000000732a00000| 0%| F| |TAMS 0x0000000732900000, 0x0000000732900000| Untracked -| 686|0x0000000732a00000, 0x0000000732a00000, 0x0000000732b00000| 0%| F| |TAMS 0x0000000732a00000, 0x0000000732a00000| Untracked -| 687|0x0000000732b00000, 0x0000000732b00000, 0x0000000732c00000| 0%| F| |TAMS 0x0000000732b00000, 0x0000000732b00000| Untracked -| 688|0x0000000732c00000, 0x0000000732c00000, 0x0000000732d00000| 0%| F| |TAMS 0x0000000732c00000, 0x0000000732c00000| Untracked -| 689|0x0000000732d00000, 0x0000000732d00000, 0x0000000732e00000| 0%| F| |TAMS 0x0000000732d00000, 0x0000000732d00000| Untracked -| 690|0x0000000732e00000, 0x0000000732e00000, 0x0000000732f00000| 0%| F| |TAMS 0x0000000732e00000, 0x0000000732e00000| Untracked -| 691|0x0000000732f00000, 0x0000000732f00000, 0x0000000733000000| 0%| F| |TAMS 0x0000000732f00000, 0x0000000732f00000| Untracked -| 692|0x0000000733000000, 0x0000000733000000, 0x0000000733100000| 0%| F| |TAMS 0x0000000733000000, 0x0000000733000000| Untracked -| 693|0x0000000733100000, 0x0000000733100000, 0x0000000733200000| 0%| F| |TAMS 0x0000000733100000, 0x0000000733100000| Untracked -| 694|0x0000000733200000, 0x0000000733200000, 0x0000000733300000| 0%| F| |TAMS 0x0000000733200000, 0x0000000733200000| Untracked -| 695|0x0000000733300000, 0x0000000733300000, 0x0000000733400000| 0%| F| |TAMS 0x0000000733300000, 0x0000000733300000| Untracked -| 696|0x0000000733400000, 0x0000000733400000, 0x0000000733500000| 0%| F| |TAMS 0x0000000733400000, 0x0000000733400000| Untracked -| 697|0x0000000733500000, 0x0000000733500000, 0x0000000733600000| 0%| F| |TAMS 0x0000000733500000, 0x0000000733500000| Untracked -| 698|0x0000000733600000, 0x0000000733600000, 0x0000000733700000| 0%| F| |TAMS 0x0000000733600000, 0x0000000733600000| Untracked -| 699|0x0000000733700000, 0x0000000733700000, 0x0000000733800000| 0%| F| |TAMS 0x0000000733700000, 0x0000000733700000| Untracked -| 700|0x0000000733800000, 0x0000000733800000, 0x0000000733900000| 0%| F| |TAMS 0x0000000733800000, 0x0000000733800000| Untracked -| 701|0x0000000733900000, 0x0000000733900000, 0x0000000733a00000| 0%| F| |TAMS 0x0000000733900000, 0x0000000733900000| Untracked -| 702|0x0000000733a00000, 0x0000000733a00000, 0x0000000733b00000| 0%| F| |TAMS 0x0000000733a00000, 0x0000000733a00000| Untracked -| 703|0x0000000733b00000, 0x0000000733b00000, 0x0000000733c00000| 0%| F| |TAMS 0x0000000733b00000, 0x0000000733b00000| Untracked -| 704|0x0000000733c00000, 0x0000000733c00000, 0x0000000733d00000| 0%| F| |TAMS 0x0000000733c00000, 0x0000000733c00000| Untracked -| 705|0x0000000733d00000, 0x0000000733d00000, 0x0000000733e00000| 0%| F| |TAMS 0x0000000733d00000, 0x0000000733d00000| Untracked -| 706|0x0000000733e00000, 0x0000000733e00000, 0x0000000733f00000| 0%| F| |TAMS 0x0000000733e00000, 0x0000000733e00000| Untracked -| 707|0x0000000733f00000, 0x0000000733f00000, 0x0000000734000000| 0%| F| |TAMS 0x0000000733f00000, 0x0000000733f00000| Untracked -| 708|0x0000000734000000, 0x0000000734000000, 0x0000000734100000| 0%| F| |TAMS 0x0000000734000000, 0x0000000734000000| Untracked -| 709|0x0000000734100000, 0x0000000734100000, 0x0000000734200000| 0%| F| |TAMS 0x0000000734100000, 0x0000000734100000| Untracked -| 710|0x0000000734200000, 0x0000000734200000, 0x0000000734300000| 0%| F| |TAMS 0x0000000734200000, 0x0000000734200000| Untracked -| 711|0x0000000734300000, 0x0000000734300000, 0x0000000734400000| 0%| F| |TAMS 0x0000000734300000, 0x0000000734300000| Untracked -| 712|0x0000000734400000, 0x0000000734400000, 0x0000000734500000| 0%| F| |TAMS 0x0000000734400000, 0x0000000734400000| Untracked -| 713|0x0000000734500000, 0x0000000734500000, 0x0000000734600000| 0%| F| |TAMS 0x0000000734500000, 0x0000000734500000| Untracked -| 714|0x0000000734600000, 0x0000000734600000, 0x0000000734700000| 0%| F| |TAMS 0x0000000734600000, 0x0000000734600000| Untracked -| 715|0x0000000734700000, 0x0000000734700000, 0x0000000734800000| 0%| F| |TAMS 0x0000000734700000, 0x0000000734700000| Untracked -| 716|0x0000000734800000, 0x0000000734800000, 0x0000000734900000| 0%| F| |TAMS 0x0000000734800000, 0x0000000734800000| Untracked -| 717|0x0000000734900000, 0x0000000734900000, 0x0000000734a00000| 0%| F| |TAMS 0x0000000734900000, 0x0000000734900000| Untracked -| 718|0x0000000734a00000, 0x0000000734a00000, 0x0000000734b00000| 0%| F| |TAMS 0x0000000734a00000, 0x0000000734a00000| Untracked -| 719|0x0000000734b00000, 0x0000000734b00000, 0x0000000734c00000| 0%| F| |TAMS 0x0000000734b00000, 0x0000000734b00000| Untracked -| 720|0x0000000734c00000, 0x0000000734c00000, 0x0000000734d00000| 0%| F| |TAMS 0x0000000734c00000, 0x0000000734c00000| Untracked -| 721|0x0000000734d00000, 0x0000000734d00000, 0x0000000734e00000| 0%| F| |TAMS 0x0000000734d00000, 0x0000000734d00000| Untracked -| 722|0x0000000734e00000, 0x0000000734e00000, 0x0000000734f00000| 0%| F| |TAMS 0x0000000734e00000, 0x0000000734e00000| Untracked -| 723|0x0000000734f00000, 0x0000000734f00000, 0x0000000735000000| 0%| F| |TAMS 0x0000000734f00000, 0x0000000734f00000| Untracked -| 724|0x0000000735000000, 0x0000000735000000, 0x0000000735100000| 0%| F| |TAMS 0x0000000735000000, 0x0000000735000000| Untracked -| 725|0x0000000735100000, 0x0000000735100000, 0x0000000735200000| 0%| F| |TAMS 0x0000000735100000, 0x0000000735100000| Untracked -| 726|0x0000000735200000, 0x0000000735200000, 0x0000000735300000| 0%| F| |TAMS 0x0000000735200000, 0x0000000735200000| Untracked -| 727|0x0000000735300000, 0x0000000735300000, 0x0000000735400000| 0%| F| |TAMS 0x0000000735300000, 0x0000000735300000| Untracked -| 728|0x0000000735400000, 0x0000000735400000, 0x0000000735500000| 0%| F| |TAMS 0x0000000735400000, 0x0000000735400000| Untracked -| 729|0x0000000735500000, 0x0000000735500000, 0x0000000735600000| 0%| F| |TAMS 0x0000000735500000, 0x0000000735500000| Untracked -| 730|0x0000000735600000, 0x0000000735600000, 0x0000000735700000| 0%| F| |TAMS 0x0000000735600000, 0x0000000735600000| Untracked -| 731|0x0000000735700000, 0x0000000735700000, 0x0000000735800000| 0%| F| |TAMS 0x0000000735700000, 0x0000000735700000| Untracked -| 732|0x0000000735800000, 0x0000000735800000, 0x0000000735900000| 0%| F| |TAMS 0x0000000735800000, 0x0000000735800000| Untracked -| 733|0x0000000735900000, 0x0000000735900000, 0x0000000735a00000| 0%| F| |TAMS 0x0000000735900000, 0x0000000735900000| Untracked -| 734|0x0000000735a00000, 0x0000000735a00000, 0x0000000735b00000| 0%| F| |TAMS 0x0000000735a00000, 0x0000000735a00000| Untracked -| 735|0x0000000735b00000, 0x0000000735b00000, 0x0000000735c00000| 0%| F| |TAMS 0x0000000735b00000, 0x0000000735b00000| Untracked -| 736|0x0000000735c00000, 0x0000000735c00000, 0x0000000735d00000| 0%| F| |TAMS 0x0000000735c00000, 0x0000000735c00000| Untracked -| 737|0x0000000735d00000, 0x0000000735d00000, 0x0000000735e00000| 0%| F| |TAMS 0x0000000735d00000, 0x0000000735d00000| Untracked -| 738|0x0000000735e00000, 0x0000000735e00000, 0x0000000735f00000| 0%| F| |TAMS 0x0000000735e00000, 0x0000000735e00000| Untracked -| 739|0x0000000735f00000, 0x0000000735f00000, 0x0000000736000000| 0%| F| |TAMS 0x0000000735f00000, 0x0000000735f00000| Untracked -| 740|0x0000000736000000, 0x0000000736000000, 0x0000000736100000| 0%| F| |TAMS 0x0000000736000000, 0x0000000736000000| Untracked -| 741|0x0000000736100000, 0x0000000736100000, 0x0000000736200000| 0%| F| |TAMS 0x0000000736100000, 0x0000000736100000| Untracked -| 742|0x0000000736200000, 0x0000000736200000, 0x0000000736300000| 0%| F| |TAMS 0x0000000736200000, 0x0000000736200000| Untracked -| 743|0x0000000736300000, 0x0000000736300000, 0x0000000736400000| 0%| F| |TAMS 0x0000000736300000, 0x0000000736300000| Untracked -| 744|0x0000000736400000, 0x0000000736400000, 0x0000000736500000| 0%| F| |TAMS 0x0000000736400000, 0x0000000736400000| Untracked -| 745|0x0000000736500000, 0x0000000736500000, 0x0000000736600000| 0%| F| |TAMS 0x0000000736500000, 0x0000000736500000| Untracked -| 746|0x0000000736600000, 0x0000000736600000, 0x0000000736700000| 0%| F| |TAMS 0x0000000736600000, 0x0000000736600000| Untracked -| 747|0x0000000736700000, 0x0000000736700000, 0x0000000736800000| 0%| F| |TAMS 0x0000000736700000, 0x0000000736700000| Untracked -| 748|0x0000000736800000, 0x0000000736800000, 0x0000000736900000| 0%| F| |TAMS 0x0000000736800000, 0x0000000736800000| Untracked -| 749|0x0000000736900000, 0x0000000736900000, 0x0000000736a00000| 0%| F| |TAMS 0x0000000736900000, 0x0000000736900000| Untracked -| 750|0x0000000736a00000, 0x0000000736a00000, 0x0000000736b00000| 0%| F| |TAMS 0x0000000736a00000, 0x0000000736a00000| Untracked -| 751|0x0000000736b00000, 0x0000000736b00000, 0x0000000736c00000| 0%| F| |TAMS 0x0000000736b00000, 0x0000000736b00000| Untracked -| 752|0x0000000736c00000, 0x0000000736c00000, 0x0000000736d00000| 0%| F| |TAMS 0x0000000736c00000, 0x0000000736c00000| Untracked -| 753|0x0000000736d00000, 0x0000000736d00000, 0x0000000736e00000| 0%| F| |TAMS 0x0000000736d00000, 0x0000000736d00000| Untracked -| 754|0x0000000736e00000, 0x0000000736e35a18, 0x0000000736f00000| 20%| S|CS|TAMS 0x0000000736e00000, 0x0000000736e00000| Complete -| 755|0x0000000736f00000, 0x0000000737000000, 0x0000000737000000|100%| S|CS|TAMS 0x0000000736f00000, 0x0000000736f00000| Complete -| 756|0x0000000737000000, 0x0000000737100000, 0x0000000737100000|100%| S|CS|TAMS 0x0000000737000000, 0x0000000737000000| Complete -| 757|0x0000000737100000, 0x0000000737200000, 0x0000000737200000|100%| S|CS|TAMS 0x0000000737100000, 0x0000000737100000| Complete -| 758|0x0000000737200000, 0x0000000737200000, 0x0000000737300000| 0%| F| |TAMS 0x0000000737200000, 0x0000000737200000| Untracked -| 759|0x0000000737300000, 0x0000000737300000, 0x0000000737400000| 0%| F| |TAMS 0x0000000737300000, 0x0000000737300000| Untracked -| 760|0x0000000737400000, 0x0000000737400000, 0x0000000737500000| 0%| F| |TAMS 0x0000000737400000, 0x0000000737400000| Untracked -| 761|0x0000000737500000, 0x0000000737500000, 0x0000000737600000| 0%| F| |TAMS 0x0000000737500000, 0x0000000737500000| Untracked -| 762|0x0000000737600000, 0x0000000737600000, 0x0000000737700000| 0%| F| |TAMS 0x0000000737600000, 0x0000000737600000| Untracked -| 763|0x0000000737700000, 0x0000000737700000, 0x0000000737800000| 0%| F| |TAMS 0x0000000737700000, 0x0000000737700000| Untracked -| 764|0x0000000737800000, 0x0000000737800000, 0x0000000737900000| 0%| F| |TAMS 0x0000000737800000, 0x0000000737800000| Untracked -| 765|0x0000000737900000, 0x0000000737900000, 0x0000000737a00000| 0%| F| |TAMS 0x0000000737900000, 0x0000000737900000| Untracked -| 766|0x0000000737a00000, 0x0000000737a00000, 0x0000000737b00000| 0%| F| |TAMS 0x0000000737a00000, 0x0000000737a00000| Untracked -| 767|0x0000000737b00000, 0x0000000737b00000, 0x0000000737c00000| 0%| F| |TAMS 0x0000000737b00000, 0x0000000737b00000| Untracked -| 768|0x0000000737c00000, 0x0000000737c00000, 0x0000000737d00000| 0%| F| |TAMS 0x0000000737c00000, 0x0000000737c00000| Untracked -| 769|0x0000000737d00000, 0x0000000737d00000, 0x0000000737e00000| 0%| F| |TAMS 0x0000000737d00000, 0x0000000737d00000| Untracked -| 770|0x0000000737e00000, 0x0000000737e00000, 0x0000000737f00000| 0%| F| |TAMS 0x0000000737e00000, 0x0000000737e00000| Untracked -| 771|0x0000000737f00000, 0x0000000737f00000, 0x0000000738000000| 0%| F| |TAMS 0x0000000737f00000, 0x0000000737f00000| Untracked -| 772|0x0000000738000000, 0x0000000738000000, 0x0000000738100000| 0%| F| |TAMS 0x0000000738000000, 0x0000000738000000| Untracked -| 773|0x0000000738100000, 0x0000000738100000, 0x0000000738200000| 0%| F| |TAMS 0x0000000738100000, 0x0000000738100000| Untracked -| 774|0x0000000738200000, 0x0000000738200000, 0x0000000738300000| 0%| F| |TAMS 0x0000000738200000, 0x0000000738200000| Untracked -| 775|0x0000000738300000, 0x0000000738300000, 0x0000000738400000| 0%| F| |TAMS 0x0000000738300000, 0x0000000738300000| Untracked -| 776|0x0000000738400000, 0x0000000738400000, 0x0000000738500000| 0%| F| |TAMS 0x0000000738400000, 0x0000000738400000| Untracked -| 777|0x0000000738500000, 0x0000000738500000, 0x0000000738600000| 0%| F| |TAMS 0x0000000738500000, 0x0000000738500000| Untracked -| 778|0x0000000738600000, 0x0000000738600000, 0x0000000738700000| 0%| F| |TAMS 0x0000000738600000, 0x0000000738600000| Untracked -| 779|0x0000000738700000, 0x0000000738700000, 0x0000000738800000| 0%| F| |TAMS 0x0000000738700000, 0x0000000738700000| Untracked -| 780|0x0000000738800000, 0x0000000738800000, 0x0000000738900000| 0%| F| |TAMS 0x0000000738800000, 0x0000000738800000| Untracked -| 781|0x0000000738900000, 0x0000000738900000, 0x0000000738a00000| 0%| F| |TAMS 0x0000000738900000, 0x0000000738900000| Untracked -| 782|0x0000000738a00000, 0x0000000738b00000, 0x0000000738b00000|100%| O| |TAMS 0x0000000738b00000, 0x0000000738a00000| Untracked -| 783|0x0000000738b00000, 0x0000000738b00000, 0x0000000738c00000| 0%| F| |TAMS 0x0000000738b00000, 0x0000000738b00000| Untracked -| 784|0x0000000738c00000, 0x0000000738c00000, 0x0000000738d00000| 0%| F| |TAMS 0x0000000738c00000, 0x0000000738c00000| Untracked -| 785|0x0000000738d00000, 0x0000000738d00000, 0x0000000738e00000| 0%| F| |TAMS 0x0000000738d00000, 0x0000000738d00000| Untracked -| 786|0x0000000738e00000, 0x0000000738e00000, 0x0000000738f00000| 0%| F| |TAMS 0x0000000738e00000, 0x0000000738e00000| Untracked -| 787|0x0000000738f00000, 0x0000000738f00000, 0x0000000739000000| 0%| F| |TAMS 0x0000000738f00000, 0x0000000738f00000| Untracked -| 788|0x0000000739000000, 0x0000000739000000, 0x0000000739100000| 0%| F| |TAMS 0x0000000739000000, 0x0000000739000000| Untracked -| 789|0x0000000739100000, 0x0000000739100000, 0x0000000739200000| 0%| F| |TAMS 0x0000000739100000, 0x0000000739100000| Untracked -| 790|0x0000000739200000, 0x0000000739200000, 0x0000000739300000| 0%| F| |TAMS 0x0000000739200000, 0x0000000739200000| Untracked -| 791|0x0000000739300000, 0x0000000739300000, 0x0000000739400000| 0%| F| |TAMS 0x0000000739300000, 0x0000000739300000| Untracked -| 792|0x0000000739400000, 0x0000000739400000, 0x0000000739500000| 0%| F| |TAMS 0x0000000739400000, 0x0000000739400000| Untracked -| 793|0x0000000739500000, 0x0000000739500000, 0x0000000739600000| 0%| F| |TAMS 0x0000000739500000, 0x0000000739500000| Untracked -| 794|0x0000000739600000, 0x0000000739600000, 0x0000000739700000| 0%| F| |TAMS 0x0000000739600000, 0x0000000739600000| Untracked -| 795|0x0000000739700000, 0x0000000739700000, 0x0000000739800000| 0%| F| |TAMS 0x0000000739700000, 0x0000000739700000| Untracked -| 796|0x0000000739800000, 0x0000000739800000, 0x0000000739900000| 0%| F| |TAMS 0x0000000739800000, 0x0000000739800000| Untracked -| 797|0x0000000739900000, 0x0000000739900000, 0x0000000739a00000| 0%| F| |TAMS 0x0000000739900000, 0x0000000739900000| Untracked -| 798|0x0000000739a00000, 0x0000000739a00000, 0x0000000739b00000| 0%| F| |TAMS 0x0000000739a00000, 0x0000000739a00000| Untracked -| 799|0x0000000739b00000, 0x0000000739b00000, 0x0000000739c00000| 0%| F| |TAMS 0x0000000739b00000, 0x0000000739b00000| Untracked -| 800|0x0000000739c00000, 0x0000000739c00000, 0x0000000739d00000| 0%| F| |TAMS 0x0000000739c00000, 0x0000000739c00000| Untracked -| 801|0x0000000739d00000, 0x0000000739d00000, 0x0000000739e00000| 0%| F| |TAMS 0x0000000739d00000, 0x0000000739d00000| Untracked -| 802|0x0000000739e00000, 0x0000000739e00000, 0x0000000739f00000| 0%| F| |TAMS 0x0000000739e00000, 0x0000000739e00000| Untracked -| 803|0x0000000739f00000, 0x0000000739f00000, 0x000000073a000000| 0%| F| |TAMS 0x0000000739f00000, 0x0000000739f00000| Untracked -| 804|0x000000073a000000, 0x000000073a000000, 0x000000073a100000| 0%| F| |TAMS 0x000000073a000000, 0x000000073a000000| Untracked -| 805|0x000000073a100000, 0x000000073a100000, 0x000000073a200000| 0%| F| |TAMS 0x000000073a100000, 0x000000073a100000| Untracked -| 806|0x000000073a200000, 0x000000073a200000, 0x000000073a300000| 0%| F| |TAMS 0x000000073a200000, 0x000000073a200000| Untracked -| 807|0x000000073a300000, 0x000000073a300000, 0x000000073a400000| 0%| F| |TAMS 0x000000073a300000, 0x000000073a300000| Untracked -| 808|0x000000073a400000, 0x000000073a400000, 0x000000073a500000| 0%| F| |TAMS 0x000000073a400000, 0x000000073a400000| Untracked -| 809|0x000000073a500000, 0x000000073a500000, 0x000000073a600000| 0%| F| |TAMS 0x000000073a500000, 0x000000073a500000| Untracked -| 810|0x000000073a600000, 0x000000073a600000, 0x000000073a700000| 0%| F| |TAMS 0x000000073a600000, 0x000000073a600000| Untracked -| 811|0x000000073a700000, 0x000000073a700000, 0x000000073a800000| 0%| F| |TAMS 0x000000073a700000, 0x000000073a700000| Untracked -| 812|0x000000073a800000, 0x000000073a800000, 0x000000073a900000| 0%| F| |TAMS 0x000000073a800000, 0x000000073a800000| Untracked -| 813|0x000000073a900000, 0x000000073a900000, 0x000000073aa00000| 0%| F| |TAMS 0x000000073a900000, 0x000000073a900000| Untracked -| 814|0x000000073aa00000, 0x000000073aa00000, 0x000000073ab00000| 0%| F| |TAMS 0x000000073aa00000, 0x000000073aa00000| Untracked -| 815|0x000000073ab00000, 0x000000073ab00000, 0x000000073ac00000| 0%| F| |TAMS 0x000000073ab00000, 0x000000073ab00000| Untracked -| 816|0x000000073ac00000, 0x000000073ac00000, 0x000000073ad00000| 0%| F| |TAMS 0x000000073ac00000, 0x000000073ac00000| Untracked -| 817|0x000000073ad00000, 0x000000073ad00000, 0x000000073ae00000| 0%| F| |TAMS 0x000000073ad00000, 0x000000073ad00000| Untracked -| 818|0x000000073ae00000, 0x000000073ae00000, 0x000000073af00000| 0%| F| |TAMS 0x000000073ae00000, 0x000000073ae00000| Untracked -| 819|0x000000073af00000, 0x000000073af00000, 0x000000073b000000| 0%| F| |TAMS 0x000000073af00000, 0x000000073af00000| Untracked -| 820|0x000000073b000000, 0x000000073b000000, 0x000000073b100000| 0%| F| |TAMS 0x000000073b000000, 0x000000073b000000| Untracked -| 821|0x000000073b100000, 0x000000073b100000, 0x000000073b200000| 0%| F| |TAMS 0x000000073b100000, 0x000000073b100000| Untracked -| 822|0x000000073b200000, 0x000000073b200000, 0x000000073b300000| 0%| F| |TAMS 0x000000073b200000, 0x000000073b200000| Untracked -| 823|0x000000073b300000, 0x000000073b300000, 0x000000073b400000| 0%| F| |TAMS 0x000000073b300000, 0x000000073b300000| Untracked -| 824|0x000000073b400000, 0x000000073b400000, 0x000000073b500000| 0%| F| |TAMS 0x000000073b400000, 0x000000073b400000| Untracked -| 825|0x000000073b500000, 0x000000073b600000, 0x000000073b600000|100%| O| |TAMS 0x000000073b600000, 0x000000073b500000| Untracked -| 826|0x000000073b600000, 0x000000073b600000, 0x000000073b700000| 0%| F| |TAMS 0x000000073b600000, 0x000000073b600000| Untracked -| 827|0x000000073b700000, 0x000000073b700000, 0x000000073b800000| 0%| F| |TAMS 0x000000073b700000, 0x000000073b700000| Untracked -| 828|0x000000073b800000, 0x000000073b800000, 0x000000073b900000| 0%| F| |TAMS 0x000000073b800000, 0x000000073b800000| Untracked -| 829|0x000000073b900000, 0x000000073b900000, 0x000000073ba00000| 0%| F| |TAMS 0x000000073b900000, 0x000000073b900000| Untracked -| 830|0x000000073ba00000, 0x000000073ba00000, 0x000000073bb00000| 0%| F| |TAMS 0x000000073ba00000, 0x000000073ba00000| Untracked -| 831|0x000000073bb00000, 0x000000073bb00000, 0x000000073bc00000| 0%| F| |TAMS 0x000000073bb00000, 0x000000073bb00000| Untracked -| 832|0x000000073bc00000, 0x000000073bc00000, 0x000000073bd00000| 0%| F| |TAMS 0x000000073bc00000, 0x000000073bc00000| Untracked -| 833|0x000000073bd00000, 0x000000073bd00000, 0x000000073be00000| 0%| F| |TAMS 0x000000073bd00000, 0x000000073bd00000| Untracked -| 834|0x000000073be00000, 0x000000073be00000, 0x000000073bf00000| 0%| F| |TAMS 0x000000073be00000, 0x000000073be00000| Untracked -| 835|0x000000073bf00000, 0x000000073bf00000, 0x000000073c000000| 0%| F| |TAMS 0x000000073bf00000, 0x000000073bf00000| Untracked -| 836|0x000000073c000000, 0x000000073c000000, 0x000000073c100000| 0%| F| |TAMS 0x000000073c000000, 0x000000073c000000| Untracked -| 837|0x000000073c100000, 0x000000073c100000, 0x000000073c200000| 0%| F| |TAMS 0x000000073c100000, 0x000000073c100000| Untracked -| 838|0x000000073c200000, 0x000000073c200000, 0x000000073c300000| 0%| F| |TAMS 0x000000073c200000, 0x000000073c200000| Untracked -| 839|0x000000073c300000, 0x000000073c300000, 0x000000073c400000| 0%| F| |TAMS 0x000000073c300000, 0x000000073c300000| Untracked -| 840|0x000000073c400000, 0x000000073c400000, 0x000000073c500000| 0%| F| |TAMS 0x000000073c400000, 0x000000073c400000| Untracked -| 841|0x000000073c500000, 0x000000073c500000, 0x000000073c600000| 0%| F| |TAMS 0x000000073c500000, 0x000000073c500000| Untracked -| 842|0x000000073c600000, 0x000000073c600000, 0x000000073c700000| 0%| F| |TAMS 0x000000073c600000, 0x000000073c600000| Untracked -| 843|0x000000073c700000, 0x000000073c700000, 0x000000073c800000| 0%| F| |TAMS 0x000000073c700000, 0x000000073c700000| Untracked -| 844|0x000000073c800000, 0x000000073c800000, 0x000000073c900000| 0%| F| |TAMS 0x000000073c800000, 0x000000073c800000| Untracked -| 845|0x000000073c900000, 0x000000073c900000, 0x000000073ca00000| 0%| F| |TAMS 0x000000073c900000, 0x000000073c900000| Untracked -| 846|0x000000073ca00000, 0x000000073ca00000, 0x000000073cb00000| 0%| F| |TAMS 0x000000073ca00000, 0x000000073ca00000| Untracked -| 847|0x000000073cb00000, 0x000000073cb00000, 0x000000073cc00000| 0%| F| |TAMS 0x000000073cb00000, 0x000000073cb00000| Untracked -| 848|0x000000073cc00000, 0x000000073cd00000, 0x000000073cd00000|100%| O| |TAMS 0x000000073cd00000, 0x000000073cc00000| Untracked -| 849|0x000000073cd00000, 0x000000073ce00000, 0x000000073ce00000|100%| O| |TAMS 0x000000073ce00000, 0x000000073cd00000| Untracked -| 850|0x000000073ce00000, 0x000000073cf00000, 0x000000073cf00000|100%| O| |TAMS 0x000000073cf00000, 0x000000073ce00000| Untracked -| 851|0x000000073cf00000, 0x000000073d000000, 0x000000073d000000|100%| O| |TAMS 0x000000073d000000, 0x000000073cf00000| Untracked -| 852|0x000000073d000000, 0x000000073d000000, 0x000000073d100000| 0%| F| |TAMS 0x000000073d000000, 0x000000073d000000| Untracked -| 853|0x000000073d100000, 0x000000073d100000, 0x000000073d200000| 0%| F| |TAMS 0x000000073d100000, 0x000000073d100000| Untracked -| 854|0x000000073d200000, 0x000000073d200000, 0x000000073d300000| 0%| F| |TAMS 0x000000073d200000, 0x000000073d200000| Untracked -| 855|0x000000073d300000, 0x000000073d300000, 0x000000073d400000| 0%| F| |TAMS 0x000000073d300000, 0x000000073d300000| Untracked -| 856|0x000000073d400000, 0x000000073d400000, 0x000000073d500000| 0%| F| |TAMS 0x000000073d400000, 0x000000073d400000| Untracked -| 857|0x000000073d500000, 0x000000073d500000, 0x000000073d600000| 0%| F| |TAMS 0x000000073d500000, 0x000000073d500000| Untracked -| 858|0x000000073d600000, 0x000000073d600000, 0x000000073d700000| 0%| F| |TAMS 0x000000073d600000, 0x000000073d600000| Untracked -| 859|0x000000073d700000, 0x000000073d700000, 0x000000073d800000| 0%| F| |TAMS 0x000000073d700000, 0x000000073d700000| Untracked -| 860|0x000000073d800000, 0x000000073d800000, 0x000000073d900000| 0%| F| |TAMS 0x000000073d800000, 0x000000073d800000| Untracked -| 861|0x000000073d900000, 0x000000073d900000, 0x000000073da00000| 0%| F| |TAMS 0x000000073d900000, 0x000000073d900000| Untracked -| 862|0x000000073da00000, 0x000000073da00000, 0x000000073db00000| 0%| F| |TAMS 0x000000073da00000, 0x000000073da00000| Untracked -| 863|0x000000073db00000, 0x000000073db00000, 0x000000073dc00000| 0%| F| |TAMS 0x000000073db00000, 0x000000073db00000| Untracked -| 864|0x000000073dc00000, 0x000000073dc00000, 0x000000073dd00000| 0%| F| |TAMS 0x000000073dc00000, 0x000000073dc00000| Untracked -| 865|0x000000073dd00000, 0x000000073dd00000, 0x000000073de00000| 0%| F| |TAMS 0x000000073dd00000, 0x000000073dd00000| Untracked -| 866|0x000000073de00000, 0x000000073de00000, 0x000000073df00000| 0%| F| |TAMS 0x000000073de00000, 0x000000073de00000| Untracked -| 867|0x000000073df00000, 0x000000073df00000, 0x000000073e000000| 0%| F| |TAMS 0x000000073df00000, 0x000000073df00000| Untracked -| 868|0x000000073e000000, 0x000000073e000000, 0x000000073e100000| 0%| F| |TAMS 0x000000073e000000, 0x000000073e000000| Untracked -| 869|0x000000073e100000, 0x000000073e100000, 0x000000073e200000| 0%| F| |TAMS 0x000000073e100000, 0x000000073e100000| Untracked -| 870|0x000000073e200000, 0x000000073e200000, 0x000000073e300000| 0%| F| |TAMS 0x000000073e200000, 0x000000073e200000| Untracked -| 871|0x000000073e300000, 0x000000073e300000, 0x000000073e400000| 0%| F| |TAMS 0x000000073e300000, 0x000000073e300000| Untracked -| 872|0x000000073e400000, 0x000000073e400000, 0x000000073e500000| 0%| F| |TAMS 0x000000073e400000, 0x000000073e400000| Untracked -| 873|0x000000073e500000, 0x000000073e500000, 0x000000073e600000| 0%| F| |TAMS 0x000000073e500000, 0x000000073e500000| Untracked -| 874|0x000000073e600000, 0x000000073e600000, 0x000000073e700000| 0%| F| |TAMS 0x000000073e600000, 0x000000073e600000| Untracked -| 875|0x000000073e700000, 0x000000073e700000, 0x000000073e800000| 0%| F| |TAMS 0x000000073e700000, 0x000000073e700000| Untracked -| 876|0x000000073e800000, 0x000000073e800000, 0x000000073e900000| 0%| F| |TAMS 0x000000073e800000, 0x000000073e800000| Untracked -| 877|0x000000073e900000, 0x000000073e900000, 0x000000073ea00000| 0%| F| |TAMS 0x000000073e900000, 0x000000073e900000| Untracked -| 878|0x000000073ea00000, 0x000000073ea00000, 0x000000073eb00000| 0%| F| |TAMS 0x000000073ea00000, 0x000000073ea00000| Untracked -| 879|0x000000073eb00000, 0x000000073eb00000, 0x000000073ec00000| 0%| F| |TAMS 0x000000073eb00000, 0x000000073eb00000| Untracked -| 880|0x000000073ec00000, 0x000000073ec00000, 0x000000073ed00000| 0%| F| |TAMS 0x000000073ec00000, 0x000000073ec00000| Untracked -| 881|0x000000073ed00000, 0x000000073ed00000, 0x000000073ee00000| 0%| F| |TAMS 0x000000073ed00000, 0x000000073ed00000| Untracked -| 882|0x000000073ee00000, 0x000000073ee00000, 0x000000073ef00000| 0%| F| |TAMS 0x000000073ee00000, 0x000000073ee00000| Untracked -| 883|0x000000073ef00000, 0x000000073ef00000, 0x000000073f000000| 0%| F| |TAMS 0x000000073ef00000, 0x000000073ef00000| Untracked -| 884|0x000000073f000000, 0x000000073f000000, 0x000000073f100000| 0%| F| |TAMS 0x000000073f000000, 0x000000073f000000| Untracked -| 885|0x000000073f100000, 0x000000073f100000, 0x000000073f200000| 0%| F| |TAMS 0x000000073f100000, 0x000000073f100000| Untracked -| 886|0x000000073f200000, 0x000000073f200000, 0x000000073f300000| 0%| F| |TAMS 0x000000073f200000, 0x000000073f200000| Untracked -| 887|0x000000073f300000, 0x000000073f300000, 0x000000073f400000| 0%| F| |TAMS 0x000000073f300000, 0x000000073f300000| Untracked -| 888|0x000000073f400000, 0x000000073f400000, 0x000000073f500000| 0%| F| |TAMS 0x000000073f400000, 0x000000073f400000| Untracked -| 889|0x000000073f500000, 0x000000073f500000, 0x000000073f600000| 0%| F| |TAMS 0x000000073f500000, 0x000000073f500000| Untracked -| 890|0x000000073f600000, 0x000000073f600000, 0x000000073f700000| 0%| F| |TAMS 0x000000073f600000, 0x000000073f600000| Untracked -| 891|0x000000073f700000, 0x000000073f700000, 0x000000073f800000| 0%| F| |TAMS 0x000000073f700000, 0x000000073f700000| Untracked -| 892|0x000000073f800000, 0x000000073f800000, 0x000000073f900000| 0%| F| |TAMS 0x000000073f800000, 0x000000073f800000| Untracked -| 893|0x000000073f900000, 0x000000073f900000, 0x000000073fa00000| 0%| F| |TAMS 0x000000073f900000, 0x000000073f900000| Untracked -| 894|0x000000073fa00000, 0x000000073fa00000, 0x000000073fb00000| 0%| F| |TAMS 0x000000073fa00000, 0x000000073fa00000| Untracked -| 895|0x000000073fb00000, 0x000000073fb00000, 0x000000073fc00000| 0%| F| |TAMS 0x000000073fb00000, 0x000000073fb00000| Untracked -| 896|0x000000073fc00000, 0x000000073fc00000, 0x000000073fd00000| 0%| F| |TAMS 0x000000073fc00000, 0x000000073fc00000| Untracked -| 897|0x000000073fd00000, 0x000000073fd00000, 0x000000073fe00000| 0%| F| |TAMS 0x000000073fd00000, 0x000000073fd00000| Untracked -| 898|0x000000073fe00000, 0x000000073fe00000, 0x000000073ff00000| 0%| F| |TAMS 0x000000073fe00000, 0x000000073fe00000| Untracked -| 899|0x000000073ff00000, 0x000000073ff00000, 0x0000000740000000| 0%| F| |TAMS 0x000000073ff00000, 0x000000073ff00000| Untracked -| 900|0x0000000740000000, 0x0000000740000000, 0x0000000740100000| 0%| F| |TAMS 0x0000000740000000, 0x0000000740000000| Untracked -| 901|0x0000000740100000, 0x0000000740100000, 0x0000000740200000| 0%| F| |TAMS 0x0000000740100000, 0x0000000740100000| Untracked -| 902|0x0000000740200000, 0x0000000740200000, 0x0000000740300000| 0%| F| |TAMS 0x0000000740200000, 0x0000000740200000| Untracked -| 903|0x0000000740300000, 0x0000000740300000, 0x0000000740400000| 0%| F| |TAMS 0x0000000740300000, 0x0000000740300000| Untracked -| 904|0x0000000740400000, 0x0000000740400000, 0x0000000740500000| 0%| F| |TAMS 0x0000000740400000, 0x0000000740400000| Untracked -| 905|0x0000000740500000, 0x0000000740500000, 0x0000000740600000| 0%| F| |TAMS 0x0000000740500000, 0x0000000740500000| Untracked -| 906|0x0000000740600000, 0x0000000740600000, 0x0000000740700000| 0%| F| |TAMS 0x0000000740600000, 0x0000000740600000| Untracked -| 907|0x0000000740700000, 0x0000000740700000, 0x0000000740800000| 0%| F| |TAMS 0x0000000740700000, 0x0000000740700000| Untracked -| 908|0x0000000740800000, 0x0000000740800000, 0x0000000740900000| 0%| F| |TAMS 0x0000000740800000, 0x0000000740800000| Untracked -| 909|0x0000000740900000, 0x0000000740900000, 0x0000000740a00000| 0%| F| |TAMS 0x0000000740900000, 0x0000000740900000| Untracked -| 910|0x0000000740a00000, 0x0000000740a00000, 0x0000000740b00000| 0%| F| |TAMS 0x0000000740a00000, 0x0000000740a00000| Untracked -| 911|0x0000000740b00000, 0x0000000740b00000, 0x0000000740c00000| 0%| F| |TAMS 0x0000000740b00000, 0x0000000740b00000| Untracked -| 912|0x0000000740c00000, 0x0000000740c00000, 0x0000000740d00000| 0%| F| |TAMS 0x0000000740c00000, 0x0000000740c00000| Untracked -| 913|0x0000000740d00000, 0x0000000740d00000, 0x0000000740e00000| 0%| F| |TAMS 0x0000000740d00000, 0x0000000740d00000| Untracked -| 914|0x0000000740e00000, 0x0000000740e00000, 0x0000000740f00000| 0%| F| |TAMS 0x0000000740e00000, 0x0000000740e00000| Untracked -| 915|0x0000000740f00000, 0x0000000740f00000, 0x0000000741000000| 0%| F| |TAMS 0x0000000740f00000, 0x0000000740f00000| Untracked -| 916|0x0000000741000000, 0x0000000741000000, 0x0000000741100000| 0%| F| |TAMS 0x0000000741000000, 0x0000000741000000| Untracked -| 917|0x0000000741100000, 0x0000000741100000, 0x0000000741200000| 0%| F| |TAMS 0x0000000741100000, 0x0000000741100000| Untracked -| 918|0x0000000741200000, 0x0000000741200000, 0x0000000741300000| 0%| F| |TAMS 0x0000000741200000, 0x0000000741200000| Untracked -| 919|0x0000000741300000, 0x0000000741300000, 0x0000000741400000| 0%| F| |TAMS 0x0000000741300000, 0x0000000741300000| Untracked -| 920|0x0000000741400000, 0x0000000741400000, 0x0000000741500000| 0%| F| |TAMS 0x0000000741400000, 0x0000000741400000| Untracked -| 921|0x0000000741500000, 0x0000000741500000, 0x0000000741600000| 0%| F| |TAMS 0x0000000741500000, 0x0000000741500000| Untracked -| 922|0x0000000741600000, 0x0000000741600000, 0x0000000741700000| 0%| F| |TAMS 0x0000000741600000, 0x0000000741600000| Untracked -| 923|0x0000000741700000, 0x0000000741700000, 0x0000000741800000| 0%| F| |TAMS 0x0000000741700000, 0x0000000741700000| Untracked -| 924|0x0000000741800000, 0x0000000741800000, 0x0000000741900000| 0%| F| |TAMS 0x0000000741800000, 0x0000000741800000| Untracked -| 925|0x0000000741900000, 0x0000000741900000, 0x0000000741a00000| 0%| F| |TAMS 0x0000000741900000, 0x0000000741900000| Untracked -| 926|0x0000000741a00000, 0x0000000741a00000, 0x0000000741b00000| 0%| F| |TAMS 0x0000000741a00000, 0x0000000741a00000| Untracked -| 927|0x0000000741b00000, 0x0000000741b00000, 0x0000000741c00000| 0%| F| |TAMS 0x0000000741b00000, 0x0000000741b00000| Untracked -| 928|0x0000000741c00000, 0x0000000741c00000, 0x0000000741d00000| 0%| F| |TAMS 0x0000000741c00000, 0x0000000741c00000| Untracked -| 929|0x0000000741d00000, 0x0000000741d00000, 0x0000000741e00000| 0%| F| |TAMS 0x0000000741d00000, 0x0000000741d00000| Untracked -| 930|0x0000000741e00000, 0x0000000741e00000, 0x0000000741f00000| 0%| F| |TAMS 0x0000000741e00000, 0x0000000741e00000| Untracked -| 931|0x0000000741f00000, 0x0000000741f00000, 0x0000000742000000| 0%| F| |TAMS 0x0000000741f00000, 0x0000000741f00000| Untracked -| 932|0x0000000742000000, 0x0000000742000000, 0x0000000742100000| 0%| F| |TAMS 0x0000000742000000, 0x0000000742000000| Untracked -| 933|0x0000000742100000, 0x0000000742100000, 0x0000000742200000| 0%| F| |TAMS 0x0000000742100000, 0x0000000742100000| Untracked -| 934|0x0000000742200000, 0x0000000742200000, 0x0000000742300000| 0%| F| |TAMS 0x0000000742200000, 0x0000000742200000| Untracked -| 935|0x0000000742300000, 0x0000000742300000, 0x0000000742400000| 0%| F| |TAMS 0x0000000742300000, 0x0000000742300000| Untracked -| 936|0x0000000742400000, 0x0000000742400000, 0x0000000742500000| 0%| F| |TAMS 0x0000000742400000, 0x0000000742400000| Untracked -| 937|0x0000000742500000, 0x0000000742500000, 0x0000000742600000| 0%| F| |TAMS 0x0000000742500000, 0x0000000742500000| Untracked -| 938|0x0000000742600000, 0x0000000742600000, 0x0000000742700000| 0%| F| |TAMS 0x0000000742600000, 0x0000000742600000| Untracked -| 939|0x0000000742700000, 0x0000000742700000, 0x0000000742800000| 0%| F| |TAMS 0x0000000742700000, 0x0000000742700000| Untracked -| 940|0x0000000742800000, 0x0000000742800000, 0x0000000742900000| 0%| F| |TAMS 0x0000000742800000, 0x0000000742800000| Untracked -| 941|0x0000000742900000, 0x0000000742900000, 0x0000000742a00000| 0%| F| |TAMS 0x0000000742900000, 0x0000000742900000| Untracked -| 942|0x0000000742a00000, 0x0000000742a00000, 0x0000000742b00000| 0%| F| |TAMS 0x0000000742a00000, 0x0000000742a00000| Untracked -| 943|0x0000000742b00000, 0x0000000742b00000, 0x0000000742c00000| 0%| F| |TAMS 0x0000000742b00000, 0x0000000742b00000| Untracked -| 944|0x0000000742c00000, 0x0000000742c00000, 0x0000000742d00000| 0%| F| |TAMS 0x0000000742c00000, 0x0000000742c00000| Untracked -| 945|0x0000000742d00000, 0x0000000742d00000, 0x0000000742e00000| 0%| F| |TAMS 0x0000000742d00000, 0x0000000742d00000| Untracked -| 946|0x0000000742e00000, 0x0000000742e00000, 0x0000000742f00000| 0%| F| |TAMS 0x0000000742e00000, 0x0000000742e00000| Untracked -| 947|0x0000000742f00000, 0x0000000742f00000, 0x0000000743000000| 0%| F| |TAMS 0x0000000742f00000, 0x0000000742f00000| Untracked -| 948|0x0000000743000000, 0x0000000743000000, 0x0000000743100000| 0%| F| |TAMS 0x0000000743000000, 0x0000000743000000| Untracked -| 949|0x0000000743100000, 0x0000000743100000, 0x0000000743200000| 0%| F| |TAMS 0x0000000743100000, 0x0000000743100000| Untracked -| 950|0x0000000743200000, 0x0000000743200000, 0x0000000743300000| 0%| F| |TAMS 0x0000000743200000, 0x0000000743200000| Untracked -| 951|0x0000000743300000, 0x0000000743300000, 0x0000000743400000| 0%| F| |TAMS 0x0000000743300000, 0x0000000743300000| Untracked -| 952|0x0000000743400000, 0x0000000743400000, 0x0000000743500000| 0%| F| |TAMS 0x0000000743400000, 0x0000000743400000| Untracked -| 953|0x0000000743500000, 0x0000000743500000, 0x0000000743600000| 0%| F| |TAMS 0x0000000743500000, 0x0000000743500000| Untracked -| 954|0x0000000743600000, 0x0000000743600000, 0x0000000743700000| 0%| F| |TAMS 0x0000000743600000, 0x0000000743600000| Untracked -| 955|0x0000000743700000, 0x0000000743700000, 0x0000000743800000| 0%| F| |TAMS 0x0000000743700000, 0x0000000743700000| Untracked -| 956|0x0000000743800000, 0x0000000743800000, 0x0000000743900000| 0%| F| |TAMS 0x0000000743800000, 0x0000000743800000| Untracked -| 957|0x0000000743900000, 0x0000000743900000, 0x0000000743a00000| 0%| F| |TAMS 0x0000000743900000, 0x0000000743900000| Untracked -| 958|0x0000000743a00000, 0x0000000743a00000, 0x0000000743b00000| 0%| F| |TAMS 0x0000000743a00000, 0x0000000743a00000| Untracked -| 959|0x0000000743b00000, 0x0000000743b00000, 0x0000000743c00000| 0%| F| |TAMS 0x0000000743b00000, 0x0000000743b00000| Untracked -| 960|0x0000000743c00000, 0x0000000743c00000, 0x0000000743d00000| 0%| F| |TAMS 0x0000000743c00000, 0x0000000743c00000| Untracked -| 961|0x0000000743d00000, 0x0000000743d00000, 0x0000000743e00000| 0%| F| |TAMS 0x0000000743d00000, 0x0000000743d00000| Untracked -| 962|0x0000000743e00000, 0x0000000743e00000, 0x0000000743f00000| 0%| F| |TAMS 0x0000000743e00000, 0x0000000743e00000| Untracked -| 963|0x0000000743f00000, 0x0000000743f00000, 0x0000000744000000| 0%| F| |TAMS 0x0000000743f00000, 0x0000000743f00000| Untracked -| 964|0x0000000744000000, 0x0000000744000000, 0x0000000744100000| 0%| F| |TAMS 0x0000000744000000, 0x0000000744000000| Untracked -| 965|0x0000000744100000, 0x0000000744100000, 0x0000000744200000| 0%| F| |TAMS 0x0000000744100000, 0x0000000744100000| Untracked -| 966|0x0000000744200000, 0x0000000744200000, 0x0000000744300000| 0%| F| |TAMS 0x0000000744200000, 0x0000000744200000| Untracked -| 967|0x0000000744300000, 0x0000000744300000, 0x0000000744400000| 0%| F| |TAMS 0x0000000744300000, 0x0000000744300000| Untracked -| 968|0x0000000744400000, 0x0000000744400000, 0x0000000744500000| 0%| F| |TAMS 0x0000000744400000, 0x0000000744400000| Untracked -| 969|0x0000000744500000, 0x0000000744500000, 0x0000000744600000| 0%| F| |TAMS 0x0000000744500000, 0x0000000744500000| Untracked -| 970|0x0000000744600000, 0x0000000744600000, 0x0000000744700000| 0%| F| |TAMS 0x0000000744600000, 0x0000000744600000| Untracked -| 971|0x0000000744700000, 0x0000000744700000, 0x0000000744800000| 0%| F| |TAMS 0x0000000744700000, 0x0000000744700000| Untracked -| 972|0x0000000744800000, 0x0000000744800000, 0x0000000744900000| 0%| F| |TAMS 0x0000000744800000, 0x0000000744800000| Untracked -| 973|0x0000000744900000, 0x0000000744900000, 0x0000000744a00000| 0%| F| |TAMS 0x0000000744900000, 0x0000000744900000| Untracked -| 974|0x0000000744a00000, 0x0000000744a00000, 0x0000000744b00000| 0%| F| |TAMS 0x0000000744a00000, 0x0000000744a00000| Untracked -| 975|0x0000000744b00000, 0x0000000744b00000, 0x0000000744c00000| 0%| F| |TAMS 0x0000000744b00000, 0x0000000744b00000| Untracked -| 976|0x0000000744c00000, 0x0000000744c00000, 0x0000000744d00000| 0%| F| |TAMS 0x0000000744c00000, 0x0000000744c00000| Untracked -| 977|0x0000000744d00000, 0x0000000744d00000, 0x0000000744e00000| 0%| F| |TAMS 0x0000000744d00000, 0x0000000744d00000| Untracked -| 978|0x0000000744e00000, 0x0000000744e00000, 0x0000000744f00000| 0%| F| |TAMS 0x0000000744e00000, 0x0000000744e00000| Untracked -| 979|0x0000000744f00000, 0x0000000744f00000, 0x0000000745000000| 0%| F| |TAMS 0x0000000744f00000, 0x0000000744f00000| Untracked -| 980|0x0000000745000000, 0x0000000745000000, 0x0000000745100000| 0%| F| |TAMS 0x0000000745000000, 0x0000000745000000| Untracked -| 981|0x0000000745100000, 0x0000000745100000, 0x0000000745200000| 0%| F| |TAMS 0x0000000745100000, 0x0000000745100000| Untracked -| 982|0x0000000745200000, 0x0000000745200000, 0x0000000745300000| 0%| F| |TAMS 0x0000000745200000, 0x0000000745200000| Untracked -| 983|0x0000000745300000, 0x0000000745300000, 0x0000000745400000| 0%| F| |TAMS 0x0000000745300000, 0x0000000745300000| Untracked -| 984|0x0000000745400000, 0x0000000745400000, 0x0000000745500000| 0%| F| |TAMS 0x0000000745400000, 0x0000000745400000| Untracked -| 985|0x0000000745500000, 0x0000000745500000, 0x0000000745600000| 0%| F| |TAMS 0x0000000745500000, 0x0000000745500000| Untracked -| 986|0x0000000745600000, 0x0000000745600000, 0x0000000745700000| 0%| F| |TAMS 0x0000000745600000, 0x0000000745600000| Untracked -| 987|0x0000000745700000, 0x0000000745700000, 0x0000000745800000| 0%| F| |TAMS 0x0000000745700000, 0x0000000745700000| Untracked -| 988|0x0000000745800000, 0x0000000745800000, 0x0000000745900000| 0%| F| |TAMS 0x0000000745800000, 0x0000000745800000| Untracked -| 989|0x0000000745900000, 0x0000000745900000, 0x0000000745a00000| 0%| F| |TAMS 0x0000000745900000, 0x0000000745900000| Untracked -| 990|0x0000000745a00000, 0x0000000745a00000, 0x0000000745b00000| 0%| F| |TAMS 0x0000000745a00000, 0x0000000745a00000| Untracked -| 991|0x0000000745b00000, 0x0000000745b00000, 0x0000000745c00000| 0%| F| |TAMS 0x0000000745b00000, 0x0000000745b00000| Untracked -| 992|0x0000000745c00000, 0x0000000745c00000, 0x0000000745d00000| 0%| F| |TAMS 0x0000000745c00000, 0x0000000745c00000| Untracked -| 993|0x0000000745d00000, 0x0000000745d00000, 0x0000000745e00000| 0%| F| |TAMS 0x0000000745d00000, 0x0000000745d00000| Untracked -| 994|0x0000000745e00000, 0x0000000745e00000, 0x0000000745f00000| 0%| F| |TAMS 0x0000000745e00000, 0x0000000745e00000| Untracked -| 995|0x0000000745f00000, 0x0000000745f00000, 0x0000000746000000| 0%| F| |TAMS 0x0000000745f00000, 0x0000000745f00000| Untracked -| 996|0x0000000746000000, 0x0000000746000000, 0x0000000746100000| 0%| F| |TAMS 0x0000000746000000, 0x0000000746000000| Untracked -| 997|0x0000000746100000, 0x0000000746100000, 0x0000000746200000| 0%| F| |TAMS 0x0000000746100000, 0x0000000746100000| Untracked -| 998|0x0000000746200000, 0x0000000746200000, 0x0000000746300000| 0%| F| |TAMS 0x0000000746200000, 0x0000000746200000| Untracked -| 999|0x0000000746300000, 0x0000000746300000, 0x0000000746400000| 0%| F| |TAMS 0x0000000746300000, 0x0000000746300000| Untracked -|1000|0x0000000746400000, 0x0000000746400000, 0x0000000746500000| 0%| F| |TAMS 0x0000000746400000, 0x0000000746400000| Untracked -|1001|0x0000000746500000, 0x0000000746500000, 0x0000000746600000| 0%| F| |TAMS 0x0000000746500000, 0x0000000746500000| Untracked -|1002|0x0000000746600000, 0x0000000746600000, 0x0000000746700000| 0%| F| |TAMS 0x0000000746600000, 0x0000000746600000| Untracked -|1003|0x0000000746700000, 0x0000000746700000, 0x0000000746800000| 0%| F| |TAMS 0x0000000746700000, 0x0000000746700000| Untracked -|1004|0x0000000746800000, 0x0000000746800000, 0x0000000746900000| 0%| F| |TAMS 0x0000000746800000, 0x0000000746800000| Untracked -|1005|0x0000000746900000, 0x0000000746900000, 0x0000000746a00000| 0%| F| |TAMS 0x0000000746900000, 0x0000000746900000| Untracked -|1006|0x0000000746a00000, 0x0000000746a00000, 0x0000000746b00000| 0%| F| |TAMS 0x0000000746a00000, 0x0000000746a00000| Untracked -|1007|0x0000000746b00000, 0x0000000746b00000, 0x0000000746c00000| 0%| F| |TAMS 0x0000000746b00000, 0x0000000746b00000| Untracked -|1008|0x0000000746c00000, 0x0000000746c00000, 0x0000000746d00000| 0%| F| |TAMS 0x0000000746c00000, 0x0000000746c00000| Untracked -|1009|0x0000000746d00000, 0x0000000746d00000, 0x0000000746e00000| 0%| F| |TAMS 0x0000000746d00000, 0x0000000746d00000| Untracked -|1010|0x0000000746e00000, 0x0000000746e00000, 0x0000000746f00000| 0%| F| |TAMS 0x0000000746e00000, 0x0000000746e00000| Untracked -|1011|0x0000000746f00000, 0x0000000746f00000, 0x0000000747000000| 0%| F| |TAMS 0x0000000746f00000, 0x0000000746f00000| Untracked -|1012|0x0000000747000000, 0x0000000747000000, 0x0000000747100000| 0%| F| |TAMS 0x0000000747000000, 0x0000000747000000| Untracked -|1013|0x0000000747100000, 0x0000000747100000, 0x0000000747200000| 0%| F| |TAMS 0x0000000747100000, 0x0000000747100000| Untracked -|1014|0x0000000747200000, 0x0000000747200000, 0x0000000747300000| 0%| F| |TAMS 0x0000000747200000, 0x0000000747200000| Untracked -|1015|0x0000000747300000, 0x0000000747300000, 0x0000000747400000| 0%| F| |TAMS 0x0000000747300000, 0x0000000747300000| Untracked -|1016|0x0000000747400000, 0x0000000747400000, 0x0000000747500000| 0%| F| |TAMS 0x0000000747400000, 0x0000000747400000| Untracked -|1017|0x0000000747500000, 0x0000000747500000, 0x0000000747600000| 0%| F| |TAMS 0x0000000747500000, 0x0000000747500000| Untracked -|1018|0x0000000747600000, 0x0000000747600000, 0x0000000747700000| 0%| F| |TAMS 0x0000000747600000, 0x0000000747600000| Untracked -|1019|0x0000000747700000, 0x0000000747700000, 0x0000000747800000| 0%| F| |TAMS 0x0000000747700000, 0x0000000747700000| Untracked -|1020|0x0000000747800000, 0x0000000747800000, 0x0000000747900000| 0%| F| |TAMS 0x0000000747800000, 0x0000000747800000| Untracked -|1021|0x0000000747900000, 0x0000000747900000, 0x0000000747a00000| 0%| F| |TAMS 0x0000000747900000, 0x0000000747900000| Untracked -|1022|0x0000000747a00000, 0x0000000747a00000, 0x0000000747b00000| 0%| F| |TAMS 0x0000000747a00000, 0x0000000747a00000| Untracked -|1023|0x0000000747b00000, 0x0000000747b00000, 0x0000000747c00000| 0%| F| |TAMS 0x0000000747b00000, 0x0000000747b00000| Untracked -|1024|0x0000000747c00000, 0x0000000747c00000, 0x0000000747d00000| 0%| F| |TAMS 0x0000000747c00000, 0x0000000747c00000| Untracked -|1025|0x0000000747d00000, 0x0000000747d00000, 0x0000000747e00000| 0%| F| |TAMS 0x0000000747d00000, 0x0000000747d00000| Untracked -|1026|0x0000000747e00000, 0x0000000747e00000, 0x0000000747f00000| 0%| F| |TAMS 0x0000000747e00000, 0x0000000747e00000| Untracked -|1027|0x0000000747f00000, 0x0000000747f00000, 0x0000000748000000| 0%| F| |TAMS 0x0000000747f00000, 0x0000000747f00000| Untracked -|1028|0x0000000748000000, 0x0000000748000000, 0x0000000748100000| 0%| F| |TAMS 0x0000000748000000, 0x0000000748000000| Untracked -|1029|0x0000000748100000, 0x0000000748100000, 0x0000000748200000| 0%| F| |TAMS 0x0000000748100000, 0x0000000748100000| Untracked -|1030|0x0000000748200000, 0x0000000748200000, 0x0000000748300000| 0%| F| |TAMS 0x0000000748200000, 0x0000000748200000| Untracked -|1031|0x0000000748300000, 0x0000000748300000, 0x0000000748400000| 0%| F| |TAMS 0x0000000748300000, 0x0000000748300000| Untracked -|1032|0x0000000748400000, 0x0000000748400000, 0x0000000748500000| 0%| F| |TAMS 0x0000000748400000, 0x0000000748400000| Untracked -|1033|0x0000000748500000, 0x0000000748500000, 0x0000000748600000| 0%| F| |TAMS 0x0000000748500000, 0x0000000748500000| Untracked -|1034|0x0000000748600000, 0x0000000748600000, 0x0000000748700000| 0%| F| |TAMS 0x0000000748600000, 0x0000000748600000| Untracked -|1035|0x0000000748700000, 0x0000000748700000, 0x0000000748800000| 0%| F| |TAMS 0x0000000748700000, 0x0000000748700000| Untracked -|1036|0x0000000748800000, 0x0000000748800000, 0x0000000748900000| 0%| F| |TAMS 0x0000000748800000, 0x0000000748800000| Untracked -|1037|0x0000000748900000, 0x0000000748900000, 0x0000000748a00000| 0%| F| |TAMS 0x0000000748900000, 0x0000000748900000| Untracked -|1038|0x0000000748a00000, 0x0000000748a00000, 0x0000000748b00000| 0%| F| |TAMS 0x0000000748a00000, 0x0000000748a00000| Untracked -|1039|0x0000000748b00000, 0x0000000748b00000, 0x0000000748c00000| 0%| F| |TAMS 0x0000000748b00000, 0x0000000748b00000| Untracked -|1040|0x0000000748c00000, 0x0000000748c00000, 0x0000000748d00000| 0%| F| |TAMS 0x0000000748c00000, 0x0000000748c00000| Untracked -|1041|0x0000000748d00000, 0x0000000748d00000, 0x0000000748e00000| 0%| F| |TAMS 0x0000000748d00000, 0x0000000748d00000| Untracked -|1042|0x0000000748e00000, 0x0000000748e00000, 0x0000000748f00000| 0%| F| |TAMS 0x0000000748e00000, 0x0000000748e00000| Untracked -|1043|0x0000000748f00000, 0x0000000748f00000, 0x0000000749000000| 0%| F| |TAMS 0x0000000748f00000, 0x0000000748f00000| Untracked -|1044|0x0000000749000000, 0x0000000749000000, 0x0000000749100000| 0%| F| |TAMS 0x0000000749000000, 0x0000000749000000| Untracked -|1045|0x0000000749100000, 0x0000000749100000, 0x0000000749200000| 0%| F| |TAMS 0x0000000749100000, 0x0000000749100000| Untracked -|1046|0x0000000749200000, 0x0000000749200000, 0x0000000749300000| 0%| F| |TAMS 0x0000000749200000, 0x0000000749200000| Untracked -|1047|0x0000000749300000, 0x0000000749300000, 0x0000000749400000| 0%| F| |TAMS 0x0000000749300000, 0x0000000749300000| Untracked -|1048|0x0000000749400000, 0x0000000749400000, 0x0000000749500000| 0%| F| |TAMS 0x0000000749400000, 0x0000000749400000| Untracked -|1049|0x0000000749500000, 0x0000000749500000, 0x0000000749600000| 0%| F| |TAMS 0x0000000749500000, 0x0000000749500000| Untracked -|1050|0x0000000749600000, 0x0000000749600000, 0x0000000749700000| 0%| F| |TAMS 0x0000000749600000, 0x0000000749600000| Untracked -|1051|0x0000000749700000, 0x0000000749700000, 0x0000000749800000| 0%| F| |TAMS 0x0000000749700000, 0x0000000749700000| Untracked -|1052|0x0000000749800000, 0x0000000749800000, 0x0000000749900000| 0%| F| |TAMS 0x0000000749800000, 0x0000000749800000| Untracked -|1053|0x0000000749900000, 0x0000000749900000, 0x0000000749a00000| 0%| F| |TAMS 0x0000000749900000, 0x0000000749900000| Untracked -|1054|0x0000000749a00000, 0x0000000749a00000, 0x0000000749b00000| 0%| F| |TAMS 0x0000000749a00000, 0x0000000749a00000| Untracked -|1055|0x0000000749b00000, 0x0000000749b00000, 0x0000000749c00000| 0%| F| |TAMS 0x0000000749b00000, 0x0000000749b00000| Untracked -|1056|0x0000000749c00000, 0x0000000749c00000, 0x0000000749d00000| 0%| F| |TAMS 0x0000000749c00000, 0x0000000749c00000| Untracked -|1057|0x0000000749d00000, 0x0000000749d00000, 0x0000000749e00000| 0%| F| |TAMS 0x0000000749d00000, 0x0000000749d00000| Untracked -|1058|0x0000000749e00000, 0x0000000749e00000, 0x0000000749f00000| 0%| F| |TAMS 0x0000000749e00000, 0x0000000749e00000| Untracked -|1059|0x0000000749f00000, 0x0000000749f00000, 0x000000074a000000| 0%| F| |TAMS 0x0000000749f00000, 0x0000000749f00000| Untracked -|1060|0x000000074a000000, 0x000000074a000000, 0x000000074a100000| 0%| F| |TAMS 0x000000074a000000, 0x000000074a000000| Untracked -|1061|0x000000074a100000, 0x000000074a100000, 0x000000074a200000| 0%| F| |TAMS 0x000000074a100000, 0x000000074a100000| Untracked -|1062|0x000000074a200000, 0x000000074a200000, 0x000000074a300000| 0%| F| |TAMS 0x000000074a200000, 0x000000074a200000| Untracked -|1063|0x000000074a300000, 0x000000074a300000, 0x000000074a400000| 0%| F| |TAMS 0x000000074a300000, 0x000000074a300000| Untracked -|1064|0x000000074a400000, 0x000000074a400000, 0x000000074a500000| 0%| F| |TAMS 0x000000074a400000, 0x000000074a400000| Untracked -|1065|0x000000074a500000, 0x000000074a500000, 0x000000074a600000| 0%| F| |TAMS 0x000000074a500000, 0x000000074a500000| Untracked -|1066|0x000000074a600000, 0x000000074a600000, 0x000000074a700000| 0%| F| |TAMS 0x000000074a600000, 0x000000074a600000| Untracked -|1067|0x000000074a700000, 0x000000074a700000, 0x000000074a800000| 0%| F| |TAMS 0x000000074a700000, 0x000000074a700000| Untracked -|1068|0x000000074a800000, 0x000000074a800000, 0x000000074a900000| 0%| F| |TAMS 0x000000074a800000, 0x000000074a800000| Untracked -|1069|0x000000074a900000, 0x000000074a900000, 0x000000074aa00000| 0%| F| |TAMS 0x000000074a900000, 0x000000074a900000| Untracked -|1070|0x000000074aa00000, 0x000000074aa00000, 0x000000074ab00000| 0%| F| |TAMS 0x000000074aa00000, 0x000000074aa00000| Untracked -|1071|0x000000074ab00000, 0x000000074ab00000, 0x000000074ac00000| 0%| F| |TAMS 0x000000074ab00000, 0x000000074ab00000| Untracked -|1072|0x000000074ac00000, 0x000000074ac00000, 0x000000074ad00000| 0%| F| |TAMS 0x000000074ac00000, 0x000000074ac00000| Untracked -|1073|0x000000074ad00000, 0x000000074ad00000, 0x000000074ae00000| 0%| F| |TAMS 0x000000074ad00000, 0x000000074ad00000| Untracked -|1074|0x000000074ae00000, 0x000000074ae00000, 0x000000074af00000| 0%| F| |TAMS 0x000000074ae00000, 0x000000074ae00000| Untracked -|1075|0x000000074af00000, 0x000000074af00000, 0x000000074b000000| 0%| F| |TAMS 0x000000074af00000, 0x000000074af00000| Untracked -|1076|0x000000074b000000, 0x000000074b000000, 0x000000074b100000| 0%| F| |TAMS 0x000000074b000000, 0x000000074b000000| Untracked -|1077|0x000000074b100000, 0x000000074b100000, 0x000000074b200000| 0%| F| |TAMS 0x000000074b100000, 0x000000074b100000| Untracked -|1078|0x000000074b200000, 0x000000074b200000, 0x000000074b300000| 0%| F| |TAMS 0x000000074b200000, 0x000000074b200000| Untracked -|1079|0x000000074b300000, 0x000000074b300000, 0x000000074b400000| 0%| F| |TAMS 0x000000074b300000, 0x000000074b300000| Untracked -|1080|0x000000074b400000, 0x000000074b400000, 0x000000074b500000| 0%| F| |TAMS 0x000000074b400000, 0x000000074b400000| Untracked -|1081|0x000000074b500000, 0x000000074b500000, 0x000000074b600000| 0%| F| |TAMS 0x000000074b500000, 0x000000074b500000| Untracked -|1082|0x000000074b600000, 0x000000074b600000, 0x000000074b700000| 0%| F| |TAMS 0x000000074b600000, 0x000000074b600000| Untracked -|1083|0x000000074b700000, 0x000000074b700000, 0x000000074b800000| 0%| F| |TAMS 0x000000074b700000, 0x000000074b700000| Untracked -|1084|0x000000074b800000, 0x000000074b800000, 0x000000074b900000| 0%| F| |TAMS 0x000000074b800000, 0x000000074b800000| Untracked -|1085|0x000000074b900000, 0x000000074b900000, 0x000000074ba00000| 0%| F| |TAMS 0x000000074b900000, 0x000000074b900000| Untracked -|1086|0x000000074ba00000, 0x000000074ba00000, 0x000000074bb00000| 0%| F| |TAMS 0x000000074ba00000, 0x000000074ba00000| Untracked -|1087|0x000000074bb00000, 0x000000074bb00000, 0x000000074bc00000| 0%| F| |TAMS 0x000000074bb00000, 0x000000074bb00000| Untracked -|1088|0x000000074bc00000, 0x000000074bc00000, 0x000000074bd00000| 0%| F| |TAMS 0x000000074bc00000, 0x000000074bc00000| Untracked -|1089|0x000000074bd00000, 0x000000074bd00000, 0x000000074be00000| 0%| F| |TAMS 0x000000074bd00000, 0x000000074bd00000| Untracked -|1090|0x000000074be00000, 0x000000074bf00000, 0x000000074bf00000|100%| O| |TAMS 0x000000074bf00000, 0x000000074be00000| Untracked -|1091|0x000000074bf00000, 0x000000074c000000, 0x000000074c000000|100%| O| |TAMS 0x000000074c000000, 0x000000074bf00000| Untracked - -Card table byte_map: [0x00007fd21203e000,0x00007fd212800000] _byte_map_base: 0x00007fd20e800000 - -Marking Bits (Prev, Next): (CMBitMap*) 0x00007fd22c089808, (CMBitMap*) 0x00007fd22c089840 - Prev Bits: [0x00007fd2081f0000, 0x00007fd20c000000) - Next Bits: [0x00007fd2043e0000, 0x00007fd2081f0000) - -Polling page: 0x00007fd232b53000 - -Metaspace: - -Usage: - Non-class: 24.01 MB capacity, 23.41 MB ( 98%) used, 489.45 KB ( 2%) free+waste, 122.12 KB ( <1%) overhead. - Class: 3.76 MB capacity, 3.30 MB ( 88%) used, 408.13 KB ( 11%) free+waste, 60.69 KB ( 2%) overhead. - Both: 27.76 MB capacity, 26.71 MB ( 96%) used, 897.59 KB ( 3%) free+waste, 182.81 KB ( <1%) overhead. - -Virtual space: - Non-class space: 26.00 MB reserved, 24.25 MB ( 93%) committed - Class space: 1.00 GB reserved, 3.88 MB ( <1%) committed - Both: 1.03 GB reserved, 28.12 MB ( 3%) committed - -Chunk freelists: - Non-Class: 10.62 KB - Class: 0 bytes - Both: 10.62 KB - -CodeHeap 'non-profiled nmethods': size=120032Kb used=6100Kb max_used=6100Kb free=113931Kb - bounds [0x00007fd21b681000, 0x00007fd21bc81000, 0x00007fd222bb9000] -CodeHeap 'profiled nmethods': size=120028Kb used=9888Kb max_used=9888Kb free=110139Kb - bounds [0x00007fd21414a000, 0x00007fd214b0a000, 0x00007fd21b681000] -CodeHeap 'non-nmethods': size=5700Kb used=1225Kb max_used=1309Kb free=4474Kb - bounds [0x00007fd213bb9000, 0x00007fd213e29000, 0x00007fd21414a000] - total_blobs=8720 nmethods=4919 adapters=512 - compilation: enabled - stopped_count=0, restarted_count=0 - full_count=0 - -Compilation events (10 events): -Event: 114.540 Thread 0x00007fd22c22b000 5904 3 org.aion.base.type.Address:: (58 bytes) -Event: 114.541 Thread 0x00007fd22c22b000 nmethod 5904 0x00007fd214b02d90 code [0x00007fd214b02fa0, 0x00007fd214b03508] -Event: 114.557 Thread 0x00007fd22c22b000 5907 2 org.aion.zero.impl.AionBlockchainImpl::skipTryToConnect (34 bytes) -Event: 114.558 Thread 0x00007fd22c22b000 nmethod 5907 0x00007fd214b03710 code [0x00007fd214b038c0, 0x00007fd214b03a70] -Event: 114.596 Thread 0x00007fd22c229000 nmethod 5891 0x00007fd21bc66590 code [0x00007fd21bc669e0, 0x00007fd21bc6b178] -Event: 114.596 Thread 0x00007fd22c229000 5897 ! 4 org.aion.zero.db.AionRepositoryCache::flush (302 bytes) -Event: 114.611 Thread 0x00007fd1d438c000 nmethod 5890 0x00007fd21bc6e790 code [0x00007fd21bc6edc0, 0x00007fd21bc746c0] -Event: 114.612 Thread 0x00007fd1d438c000 5906 ! 4 org.aion.mcf.db.AbstractRepositoryCache::incrementNonce (56 bytes) -Event: 114.625 Thread 0x00007fd22c22b000 5910 2 java.math.BigInteger::signInt (13 bytes) -Event: 114.625 Thread 0x00007fd22c22b000 nmethod 5910 0x00007fd2144ed010 code [0x00007fd2144ed1c0, 0x00007fd2144ed330] - -GC Heap History (10 events): -Event: 112.683 GC heap after -{Heap after GC invocations=340 (full 0): - garbage-first heap total 1000448K, used 296580K [0x0000000707c00000, 0x0000000800000000) - region size 1024K, 1 young (1024K), 1 survivors (1024K) - Metaspace used 26933K, capacity 27998K, committed 28160K, reserved 1073152K - class space used 3341K, capacity 3797K, committed 3840K, reserved 1048576K -} -Event: 113.232 GC heap before -{Heap before GC invocations=340 (full 0): - garbage-first heap total 1000448K, used 989828K [0x0000000707c00000, 0x0000000800000000) - region size 1024K, 586 young (600064K), 1 survivors (1024K) - Metaspace used 27125K, capacity 28205K, committed 28416K, reserved 1073152K - class space used 3357K, capacity 3838K, committed 3840K, reserved 1048576K -} -Event: 113.332 GC heap after -{Heap after GC invocations=341 (full 0): - garbage-first heap total 1118208K, used 462645K [0x0000000707c00000, 0x0000000800000000) - region size 1024K, 74 young (75776K), 74 survivors (75776K) - Metaspace used 27125K, capacity 28205K, committed 28416K, reserved 1073152K - class space used 3357K, capacity 3838K, committed 3840K, reserved 1048576K -} -Event: 113.707 GC heap before -{Heap before GC invocations=341 (full 0): - garbage-first heap total 1118208K, used 739125K [0x0000000707c00000, 0x0000000800000000) - region size 1024K, 234 young (239616K), 74 survivors (75776K) - Metaspace used 27167K, capacity 28223K, committed 28544K, reserved 1073152K - class space used 3360K, capacity 3844K, committed 3968K, reserved 1048576K -} -Event: 113.776 GC heap after -{Heap after GC invocations=342 (full 0): - garbage-first heap total 1118208K, used 576512K [0x0000000707c00000, 0x0000000800000000) - region size 1024K, 59 young (60416K), 59 survivors (60416K) - Metaspace used 27167K, capacity 28223K, committed 28544K, reserved 1073152K - class space used 3360K, capacity 3844K, committed 3968K, reserved 1048576K -} -Event: 114.172 GC heap before -{Heap before GC invocations=343 (full 0): - garbage-first heap total 1118208K, used 647168K [0x0000000707c00000, 0x0000000800000000) - region size 1024K, 279 young (285696K), 59 survivors (60416K) - Metaspace used 27306K, capacity 28358K, committed 28544K, reserved 1073152K - class space used 3377K, capacity 3845K, committed 3968K, reserved 1048576K -} -Event: 114.197 GC heap after -{Heap after GC invocations=344 (full 0): - garbage-first heap total 1118208K, used 379904K [0x0000000707c00000, 0x0000000800000000) - region size 1024K, 35 young (35840K), 35 survivors (35840K) - Metaspace used 27306K, capacity 28358K, committed 28544K, reserved 1073152K - class space used 3377K, capacity 3845K, committed 3968K, reserved 1048576K -} -Event: 114.221 GC heap before -{Heap before GC invocations=344 (full 0): - garbage-first heap total 1118208K, used 399360K [0x0000000707c00000, 0x0000000800000000) - region size 1024K, 54 young (55296K), 35 survivors (35840K) - Metaspace used 27321K, capacity 28361K, committed 28544K, reserved 1073152K - class space used 3378K, capacity 3846K, committed 3968K, reserved 1048576K -} -Event: 114.238 GC heap after -{Heap after GC invocations=345 (full 0): - garbage-first heap total 1118208K, used 375808K [0x0000000707c00000, 0x0000000800000000) - region size 1024K, 5 young (5120K), 5 survivors (5120K) - Metaspace used 27321K, capacity 28361K, committed 28544K, reserved 1073152K - class space used 3378K, capacity 3846K, committed 3968K, reserved 1048576K -} -Event: 114.653 GC heap before -{Heap before GC invocations=345 (full 0): - garbage-first heap total 1118208K, used 704512K [0x0000000707c00000, 0x0000000800000000) - region size 1024K, 326 young (333824K), 5 survivors (5120K) - Metaspace used 27350K, capacity 28431K, committed 28800K, reserved 1075200K - class space used 3379K, capacity 3848K, committed 3968K, reserved 1048576K -} - -Deoptimization events (10 events): -Event: 113.994 Thread 0x00007fd22c799000 Uncommon trap: reason=bimorphic_or_optimized_type_check action=maybe_recompile pc=0x00007fd21b7f975c method=java.util.AbstractList.listIterator()Ljava/util/ListIterator; @ 2 c2 -Event: 113.995 Thread 0x00007fd22c799000 Uncommon trap: reason=bimorphic_or_optimized_type_check action=maybe_recompile pc=0x00007fd21b7f975c method=java.util.AbstractList.listIterator()Ljava/util/ListIterator; @ 2 c2 -Event: 113.997 Thread 0x00007fd22c799000 Uncommon trap: reason=bimorphic_or_optimized_type_check action=maybe_recompile pc=0x00007fd21b7f975c method=java.util.AbstractList.listIterator()Ljava/util/ListIterator; @ 2 c2 -Event: 114.031 Thread 0x00007fd22c799000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007fd21b75d758 method=java.util.Objects.requireNonNull(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object; @ 1 c2 -Event: 114.031 Thread 0x00007fd22c799000 Uncommon trap: reason=null_check action=make_not_entrant pc=0x00007fd21ba1de14 method=ch.qos.logback.classic.spi.EventArgUtil.extractThrowable([Ljava/lang/Object;)Ljava/lang/Throwable; @ 19 c2 -Event: 114.031 Thread 0x00007fd22c799000 Uncommon trap: reason=null_check action=make_not_entrant pc=0x00007fd21b75f82c method=org.slf4j.helpers.MessageFormatter.getThrowableCandidate([Ljava/lang/Object;)Ljava/lang/Throwable; @ 19 c2 -Event: 114.104 Thread 0x00007fd22c799000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007fd21bb3a21c method=org.aion.zero.impl.AionBlockchainImpl.createNewBlockInternal(Lorg/aion/zero/impl/types/AionBlock;Ljava/util/List;ZJ)Lorg/aion/zero/impl/BlockContext; @ 184 c2 -Event: 114.172 Thread 0x00007fd22c799000 Uncommon trap: reason=class_check action=maybe_recompile pc=0x00007fd21b806b10 method=java.util.Collections.reverse(Ljava/util/List;)V @ 1 c2 -Event: 114.200 Thread 0x00007fd22c799000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007fd21bba1978 method=org.aion.zero.impl.AionBlockchainImpl.getTotalDifficultyByHash(Lorg/aion/base/type/Hash256;)Ljava/math/BigInteger; @ 1 c2 -Event: 114.652 Thread 0x00007fd22c799000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007fd21b90047c method=java.math.BigInteger.add([I[I)[I @ 116 c2 - -Classes redefined (0 events): -No events - -Internal exceptions (10 events): -Event: 114.031 Thread 0x00007fd22c799000 Exception (0x0000000745730590) thrown at [/scratch/opt/mach5/mesos/work_dir/slaves/14a03e04-9f3c-408e-8ddf-efd6aa9b759f-S30878/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/execu -Event: 114.031 Thread 0x00007fd22c799000 Exception (0x00000007457315e8) thrown at [/scratch/opt/mach5/mesos/work_dir/slaves/14a03e04-9f3c-408e-8ddf-efd6aa9b759f-S30878/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/executors/a3066abf -Event: 114.031 Thread 0x00007fd22c799000 Implicit null exception at 0x00007fd21ba16af7 to 0x00007fd21ba1ddea -Event: 114.031 Thread 0x00007fd22c799000 Implicit null exception at 0x00007fd21b75f5bc to 0x00007fd21b75f812 -Event: 114.031 Thread 0x00007fd22c799000 NullPointerException at vtable entry 0x00007fd213ccc597 -Event: 114.031 Thread 0x00007fd22c799000 Exception (0x0000000745736090) thrown at [/scratch/opt/mach5/mesos/work_dir/slaves/14a03e04-9f3c-408e-8ddf-efd6aa9b759f-S30878/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/executors/a3066abf -Event: 114.031 Thread 0x00007fd22c799000 Exception (0x0000000745736608) thrown at [/scratch/opt/mach5/mesos/work_dir/slaves/14a03e04-9f3c-408e-8ddf-efd6aa9b759f-S30878/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/execu -Event: 114.104 Thread 0x00007fd22c799000 Implicit null exception at 0x00007fd21bb35acc to 0x00007fd21bb3a1e2 -Event: 114.200 Thread 0x00007fd22c799000 Implicit null exception at 0x00007fd21bba18ec to 0x00007fd21bba1966 -Event: 114.200 Thread 0x00007fd22c799000 Exception (0x000000074bbdc918) thrown at [/scratch/opt/mach5/mesos/work_dir/slaves/14a03e04-9f3c-408e-8ddf-efd6aa9b759f-S30878/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/execu - -Events (10 events): -Event: 114.200 Thread 0x00007fd22c799000 DEOPT PACKING pc=0x00007fd21bba1978 sp=0x00007fd1fc5f8100 -Event: 114.200 Thread 0x00007fd22c799000 DEOPT UNPACKING pc=0x00007fd213be19a5 sp=0x00007fd1fc5f80c0 mode 2 -Event: 114.221 Executing VM operation: G1CollectForAllocation -Event: 114.238 Executing VM operation: G1CollectForAllocation done -Event: 114.256 Thread 0x00007fd22c799000 DEOPT PACKING pc=0x00007fd2145ca535 sp=0x00007fd1fc5f83b0 -Event: 114.256 Thread 0x00007fd22c799000 DEOPT UNPACKING pc=0x00007fd213be17ba sp=0x00007fd1fc5f7890 mode 0 -Event: 114.652 Thread 0x00007fd22c799000 Uncommon trap: trap_request=0xffffff4d fr.pc=0x00007fd21b90047c relative=0x00000000000009fc -Event: 114.652 Thread 0x00007fd22c799000 DEOPT PACKING pc=0x00007fd21b90047c sp=0x00007fd1fc5f7c60 -Event: 114.652 Thread 0x00007fd22c799000 DEOPT UNPACKING pc=0x00007fd213be19a5 sp=0x00007fd1fc5f7ba0 mode 2 -Event: 114.653 Executing VM operation: G1CollectForAllocation - - -Dynamic libraries: -00400000-00401000 r-xp 00000000 fd:01 14029625 /home/jay/ide/jdk-11.0.1/bin/java -00600000-00601000 r--p 00000000 fd:01 14029625 /home/jay/ide/jdk-11.0.1/bin/java -00601000-00602000 rw-p 00001000 fd:01 14029625 /home/jay/ide/jdk-11.0.1/bin/java -0234e000-0236f000 rw-p 00000000 00:00 0 [heap] -707c00000-74c000000 rw-p 00000000 00:00 0 -794000000-800000000 ---p 00000000 00:00 0 -800000000-8003e0000 rw-p 00000000 00:00 0 -8003e0000-840000000 ---p 00000000 00:00 0 -7fd077a25000-7fd077a29000 ---p 00000000 00:00 0 -7fd077a29000-7fd077b26000 rw-p 00000000 00:00 0 -7fd077b26000-7fd077b2a000 ---p 00000000 00:00 0 -7fd077b2a000-7fd077c27000 rw-p 00000000 00:00 0 -7fd077c27000-7fd077c2b000 ---p 00000000 00:00 0 -7fd077c2b000-7fd077d28000 rw-p 00000000 00:00 0 -7fd077d28000-7fd077d2c000 ---p 00000000 00:00 0 -7fd077d2c000-7fd077e29000 rw-p 00000000 00:00 0 -7fd077e29000-7fd077e2d000 ---p 00000000 00:00 0 -7fd077e2d000-7fd077f2a000 rw-p 00000000 00:00 0 -7fd077f2a000-7fd077f2e000 ---p 00000000 00:00 0 -7fd077f2e000-7fd07802b000 rw-p 00000000 00:00 0 -7fd07802b000-7fd07802f000 ---p 00000000 00:00 0 -7fd07802f000-7fd07812c000 rw-p 00000000 00:00 0 -7fd07812c000-7fd078130000 ---p 00000000 00:00 0 -7fd078130000-7fd07822d000 rw-p 00000000 00:00 0 -7fd07822d000-7fd078231000 ---p 00000000 00:00 0 -7fd078231000-7fd07832e000 rw-p 00000000 00:00 0 -7fd07832e000-7fd078332000 ---p 00000000 00:00 0 -7fd078332000-7fd07842f000 rw-p 00000000 00:00 0 -7fd07842f000-7fd078433000 ---p 00000000 00:00 0 -7fd078433000-7fd078530000 rw-p 00000000 00:00 0 -7fd078530000-7fd078534000 ---p 00000000 00:00 0 -7fd078534000-7fd078631000 rw-p 00000000 00:00 0 -7fd078631000-7fd078635000 ---p 00000000 00:00 0 -7fd078635000-7fd078732000 rw-p 00000000 00:00 0 -7fd078732000-7fd078736000 ---p 00000000 00:00 0 -7fd078736000-7fd078833000 rw-p 00000000 00:00 0 -7fd078833000-7fd078837000 ---p 00000000 00:00 0 -7fd078837000-7fd078934000 rw-p 00000000 00:00 0 -7fd078934000-7fd078938000 ---p 00000000 00:00 0 -7fd078938000-7fd078a35000 rw-p 00000000 00:00 0 -7fd078a35000-7fd078a39000 ---p 00000000 00:00 0 -7fd078a39000-7fd078b36000 rw-p 00000000 00:00 0 -7fd078b36000-7fd078b3a000 ---p 00000000 00:00 0 -7fd078b3a000-7fd078c37000 rw-p 00000000 00:00 0 -7fd078c37000-7fd078c3b000 ---p 00000000 00:00 0 -7fd078c3b000-7fd078d38000 rw-p 00000000 00:00 0 -7fd078d38000-7fd078d3c000 ---p 00000000 00:00 0 -7fd078d3c000-7fd078e39000 rw-p 00000000 00:00 0 -7fd078e39000-7fd078e3d000 ---p 00000000 00:00 0 -7fd078e3d000-7fd078f3a000 rw-p 00000000 00:00 0 -7fd078f3a000-7fd078f3e000 ---p 00000000 00:00 0 -7fd078f3e000-7fd07903b000 rw-p 00000000 00:00 0 -7fd07903b000-7fd07903f000 ---p 00000000 00:00 0 -7fd07903f000-7fd07913c000 rw-p 00000000 00:00 0 -7fd07913c000-7fd079140000 ---p 00000000 00:00 0 -7fd079140000-7fd07923d000 rw-p 00000000 00:00 0 -7fd07923d000-7fd079241000 ---p 00000000 00:00 0 -7fd079241000-7fd07933e000 rw-p 00000000 00:00 0 -7fd07933e000-7fd079342000 ---p 00000000 00:00 0 -7fd079342000-7fd07943f000 rw-p 00000000 00:00 0 -7fd07943f000-7fd079443000 ---p 00000000 00:00 0 -7fd079443000-7fd079540000 rw-p 00000000 00:00 0 -7fd079540000-7fd079544000 ---p 00000000 00:00 0 -7fd079544000-7fd079641000 rw-p 00000000 00:00 0 -7fd079641000-7fd079645000 ---p 00000000 00:00 0 -7fd079645000-7fd079742000 rw-p 00000000 00:00 0 -7fd079742000-7fd079746000 ---p 00000000 00:00 0 -7fd079746000-7fd079843000 rw-p 00000000 00:00 0 -7fd079843000-7fd079847000 ---p 00000000 00:00 0 -7fd079847000-7fd079944000 rw-p 00000000 00:00 0 -7fd079944000-7fd079948000 ---p 00000000 00:00 0 -7fd079948000-7fd079a45000 rw-p 00000000 00:00 0 -7fd079a45000-7fd079a49000 ---p 00000000 00:00 0 -7fd079a49000-7fd079b46000 rw-p 00000000 00:00 0 -7fd079b46000-7fd079b4a000 ---p 00000000 00:00 0 -7fd079b4a000-7fd079c47000 rw-p 00000000 00:00 0 -7fd079c47000-7fd079c4b000 ---p 00000000 00:00 0 -7fd079c4b000-7fd079d48000 rw-p 00000000 00:00 0 -7fd079d48000-7fd079d4c000 ---p 00000000 00:00 0 -7fd079d4c000-7fd079e49000 rw-p 00000000 00:00 0 -7fd079e49000-7fd079e4d000 ---p 00000000 00:00 0 -7fd079e4d000-7fd079f4a000 rw-p 00000000 00:00 0 -7fd079f4a000-7fd079f4e000 ---p 00000000 00:00 0 -7fd079f4e000-7fd07a04b000 rw-p 00000000 00:00 0 -7fd07a04b000-7fd07a04f000 ---p 00000000 00:00 0 -7fd07a04f000-7fd07a14c000 rw-p 00000000 00:00 0 -7fd07a14c000-7fd07a150000 ---p 00000000 00:00 0 -7fd07a150000-7fd07a24d000 rw-p 00000000 00:00 0 -7fd07a24d000-7fd07a251000 ---p 00000000 00:00 0 -7fd07a251000-7fd07a34e000 rw-p 00000000 00:00 0 -7fd07a34e000-7fd07a352000 ---p 00000000 00:00 0 -7fd07a352000-7fd07a44f000 rw-p 00000000 00:00 0 -7fd07a44f000-7fd07a453000 ---p 00000000 00:00 0 -7fd07a453000-7fd07a550000 rw-p 00000000 00:00 0 -7fd07a550000-7fd07a554000 ---p 00000000 00:00 0 -7fd07a554000-7fd07a651000 rw-p 00000000 00:00 0 -7fd07a651000-7fd07a655000 ---p 00000000 00:00 0 -7fd07a655000-7fd07a752000 rw-p 00000000 00:00 0 -7fd07a752000-7fd07a756000 ---p 00000000 00:00 0 -7fd07a756000-7fd07a853000 rw-p 00000000 00:00 0 -7fd07a853000-7fd07a857000 ---p 00000000 00:00 0 -7fd07a857000-7fd07a954000 rw-p 00000000 00:00 0 -7fd07a954000-7fd07a958000 ---p 00000000 00:00 0 -7fd07a958000-7fd07aa55000 rw-p 00000000 00:00 0 -7fd07aa55000-7fd07aa59000 ---p 00000000 00:00 0 -7fd07aa59000-7fd07ab56000 rw-p 00000000 00:00 0 -7fd07ab56000-7fd07ab5a000 ---p 00000000 00:00 0 -7fd07ab5a000-7fd07ac57000 rw-p 00000000 00:00 0 -7fd07ac57000-7fd07ac5b000 ---p 00000000 00:00 0 -7fd07ac5b000-7fd07ad58000 rw-p 00000000 00:00 0 -7fd07ad58000-7fd07ad5c000 ---p 00000000 00:00 0 -7fd07ad5c000-7fd07ae59000 rw-p 00000000 00:00 0 -7fd07ae59000-7fd07ae5d000 ---p 00000000 00:00 0 -7fd07ae5d000-7fd07af5a000 rw-p 00000000 00:00 0 -7fd07af5a000-7fd07af5e000 ---p 00000000 00:00 0 -7fd07af5e000-7fd07b05b000 rw-p 00000000 00:00 0 -7fd07b05b000-7fd07b05f000 ---p 00000000 00:00 0 -7fd07b05f000-7fd07b15c000 rw-p 00000000 00:00 0 -7fd07b15c000-7fd07b160000 ---p 00000000 00:00 0 -7fd07b160000-7fd07b25d000 rw-p 00000000 00:00 0 -7fd07b25d000-7fd07b261000 ---p 00000000 00:00 0 -7fd07b261000-7fd07b35e000 rw-p 00000000 00:00 0 -7fd07b35e000-7fd07b362000 ---p 00000000 00:00 0 -7fd07b362000-7fd07b45f000 rw-p 00000000 00:00 0 -7fd07b45f000-7fd07b463000 ---p 00000000 00:00 0 -7fd07b463000-7fd07b560000 rw-p 00000000 00:00 0 -7fd07b560000-7fd07b564000 ---p 00000000 00:00 0 -7fd07b564000-7fd07b661000 rw-p 00000000 00:00 0 -7fd07b661000-7fd07b665000 ---p 00000000 00:00 0 -7fd07b665000-7fd07b762000 rw-p 00000000 00:00 0 -7fd07b762000-7fd07b766000 ---p 00000000 00:00 0 -7fd07b766000-7fd07b863000 rw-p 00000000 00:00 0 -7fd07b863000-7fd07b867000 ---p 00000000 00:00 0 -7fd07b867000-7fd07b964000 rw-p 00000000 00:00 0 -7fd07b964000-7fd07b968000 ---p 00000000 00:00 0 -7fd07b968000-7fd07ba65000 rw-p 00000000 00:00 0 -7fd07ba65000-7fd07ba69000 ---p 00000000 00:00 0 -7fd07ba69000-7fd07bb66000 rw-p 00000000 00:00 0 -7fd07bb66000-7fd07bb6a000 ---p 00000000 00:00 0 -7fd07bb6a000-7fd07bc67000 rw-p 00000000 00:00 0 -7fd07bc67000-7fd07bc6b000 ---p 00000000 00:00 0 -7fd07bc6b000-7fd07bd68000 rw-p 00000000 00:00 0 -7fd07bd68000-7fd07bd6c000 ---p 00000000 00:00 0 -7fd07bd6c000-7fd07be69000 rw-p 00000000 00:00 0 -7fd07be69000-7fd07be6d000 ---p 00000000 00:00 0 -7fd07be6d000-7fd07bf6a000 rw-p 00000000 00:00 0 -7fd07bf6a000-7fd07bf6e000 ---p 00000000 00:00 0 -7fd07bf6e000-7fd07c06b000 rw-p 00000000 00:00 0 -7fd07c06b000-7fd07c06f000 ---p 00000000 00:00 0 -7fd07c06f000-7fd07c16c000 rw-p 00000000 00:00 0 -7fd07c16c000-7fd07c170000 ---p 00000000 00:00 0 -7fd07c170000-7fd07c26d000 rw-p 00000000 00:00 0 -7fd07c26d000-7fd07c271000 ---p 00000000 00:00 0 -7fd07c271000-7fd07c36e000 rw-p 00000000 00:00 0 -7fd07c36e000-7fd07c372000 ---p 00000000 00:00 0 -7fd07c372000-7fd07c46f000 rw-p 00000000 00:00 0 -7fd07c46f000-7fd07c473000 ---p 00000000 00:00 0 -7fd07c473000-7fd07c570000 rw-p 00000000 00:00 0 -7fd07c570000-7fd07c574000 ---p 00000000 00:00 0 -7fd07c574000-7fd07c671000 rw-p 00000000 00:00 0 -7fd07c671000-7fd07c675000 ---p 00000000 00:00 0 -7fd07c675000-7fd07c772000 rw-p 00000000 00:00 0 -7fd07c772000-7fd07c776000 ---p 00000000 00:00 0 -7fd07c776000-7fd07c873000 rw-p 00000000 00:00 0 -7fd07c873000-7fd07c877000 ---p 00000000 00:00 0 -7fd07c877000-7fd07c974000 rw-p 00000000 00:00 0 -7fd07c974000-7fd07c978000 ---p 00000000 00:00 0 -7fd07c978000-7fd07ca75000 rw-p 00000000 00:00 0 -7fd07ca75000-7fd07ca79000 ---p 00000000 00:00 0 -7fd07ca79000-7fd07cb76000 rw-p 00000000 00:00 0 -7fd07cb76000-7fd07cbcc000 r-xp 00000000 fd:01 1968666 /tmp/libleveldbjni-64-1-8891343892984256434.8 -7fd07cbcc000-7fd07cdcb000 ---p 00056000 fd:01 1968666 /tmp/libleveldbjni-64-1-8891343892984256434.8 -7fd07cdcb000-7fd07cdcd000 r--p 00055000 fd:01 1968666 /tmp/libleveldbjni-64-1-8891343892984256434.8 -7fd07cdcd000-7fd07cdce000 rw-p 00057000 fd:01 1968666 /tmp/libleveldbjni-64-1-8891343892984256434.8 -7fd07cdce000-7fd07cdd2000 ---p 00000000 00:00 0 -7fd07cdd2000-7fd07cecf000 rw-p 00000000 00:00 0 -7fd07dbdc000-7fd07dbe0000 ---p 00000000 00:00 0 -7fd07dbe0000-7fd07dcdd000 rw-p 00000000 00:00 0 -7fd07dfe0000-7fd07dfe4000 ---p 00000000 00:00 0 -7fd07dfe4000-7fd07e0e1000 rw-p 00000000 00:00 0 -7fd07e4e5000-7fd07e4e9000 ---p 00000000 00:00 0 -7fd07e4e9000-7fd07e5e6000 rw-p 00000000 00:00 0 -7fd07e5e6000-7fd07e5ea000 ---p 00000000 00:00 0 -7fd07e5ea000-7fd07e6e7000 rw-p 00000000 00:00 0 -7fd07e7e8000-7fd07e7ec000 ---p 00000000 00:00 0 -7fd07e7ec000-7fd07e8e9000 rw-p 00000000 00:00 0 -7fd07e9ea000-7fd07e9ee000 ---p 00000000 00:00 0 -7fd07e9ee000-7fd07eaeb000 rw-p 00000000 00:00 0 -7fd07eaeb000-7fd07eaef000 ---p 00000000 00:00 0 -7fd07eaef000-7fd07ebec000 rw-p 00000000 00:00 0 -7fd07eced000-7fd07ecf1000 ---p 00000000 00:00 0 -7fd07ecf1000-7fd07edee000 rw-p 00000000 00:00 0 -7fd07edee000-7fd07edf2000 ---p 00000000 00:00 0 -7fd07edf2000-7fd07eeef000 rw-p 00000000 00:00 0 -7fd07eeef000-7fd07eef3000 ---p 00000000 00:00 0 -7fd07eef3000-7fd07eff0000 rw-p 00000000 00:00 0 -7fd07f4f5000-7fd07f4f9000 ---p 00000000 00:00 0 -7fd07f4f9000-7fd07f5f6000 rw-p 00000000 00:00 0 -7fd07f8f9000-7fd07f8fd000 ---p 00000000 00:00 0 -7fd07f8fd000-7fd07f9fa000 rw-p 00000000 00:00 0 -7fd080000000-7fd080021000 rw-p 00000000 00:00 0 -7fd080021000-7fd084000000 ---p 00000000 00:00 0 -7fd084000000-7fd08510b000 rw-p 00000000 00:00 0 -7fd08510b000-7fd088000000 ---p 00000000 00:00 0 -7fd088000000-7fd088021000 rw-p 00000000 00:00 0 -7fd088021000-7fd08c000000 ---p 00000000 00:00 0 -7fd08c000000-7fd08c1d1000 rw-p 00000000 00:00 0 -7fd08c1d1000-7fd090000000 ---p 00000000 00:00 0 -7fd090000000-7fd090021000 rw-p 00000000 00:00 0 -7fd090021000-7fd094000000 ---p 00000000 00:00 0 -7fd094000000-7fd094021000 rw-p 00000000 00:00 0 -7fd094021000-7fd098000000 ---p 00000000 00:00 0 -7fd098000000-7fd098021000 rw-p 00000000 00:00 0 -7fd098021000-7fd09c000000 ---p 00000000 00:00 0 -7fd09c000000-7fd09d1f8000 rw-p 00000000 00:00 0 -7fd09d1f8000-7fd0a0000000 ---p 00000000 00:00 0 -7fd0a0000000-7fd0a0021000 rw-p 00000000 00:00 0 -7fd0a0021000-7fd0a4000000 ---p 00000000 00:00 0 -7fd0a4000000-7fd0a4021000 rw-p 00000000 00:00 0 -7fd0a4021000-7fd0a8000000 ---p 00000000 00:00 0 -7fd0a8000000-7fd0a8021000 rw-p 00000000 00:00 0 -7fd0a8021000-7fd0ac000000 ---p 00000000 00:00 0 -7fd0ac000000-7fd0ac021000 rw-p 00000000 00:00 0 -7fd0ac021000-7fd0b0000000 ---p 00000000 00:00 0 -7fd0b0000000-7fd0b0021000 rw-p 00000000 00:00 0 -7fd0b0021000-7fd0b4000000 ---p 00000000 00:00 0 -7fd0b4000000-7fd0b4021000 rw-p 00000000 00:00 0 -7fd0b4021000-7fd0b8000000 ---p 00000000 00:00 0 -7fd0b8000000-7fd0b8021000 rw-p 00000000 00:00 0 -7fd0b8021000-7fd0bc000000 ---p 00000000 00:00 0 -7fd0bc000000-7fd0bc021000 rw-p 00000000 00:00 0 -7fd0bc021000-7fd0c0000000 ---p 00000000 00:00 0 -7fd0c0000000-7fd0c0021000 rw-p 00000000 00:00 0 -7fd0c0021000-7fd0c4000000 ---p 00000000 00:00 0 -7fd0c4000000-7fd0c4021000 rw-p 00000000 00:00 0 -7fd0c4021000-7fd0c8000000 ---p 00000000 00:00 0 -7fd0c8000000-7fd0c8021000 rw-p 00000000 00:00 0 -7fd0c8021000-7fd0cc000000 ---p 00000000 00:00 0 -7fd0cc000000-7fd0cc021000 rw-p 00000000 00:00 0 -7fd0cc021000-7fd0d0000000 ---p 00000000 00:00 0 -7fd0d0000000-7fd0d03bb000 rw-p 00000000 00:00 0 -7fd0d03bb000-7fd0d4000000 ---p 00000000 00:00 0 -7fd0d4000000-7fd0d4021000 rw-p 00000000 00:00 0 -7fd0d4021000-7fd0d8000000 ---p 00000000 00:00 0 -7fd0d8000000-7fd0d8021000 rw-p 00000000 00:00 0 -7fd0d8021000-7fd0dc000000 ---p 00000000 00:00 0 -7fd0dc000000-7fd0dc26e000 rw-p 00000000 00:00 0 -7fd0dc26e000-7fd0e0000000 ---p 00000000 00:00 0 -7fd0e0000000-7fd0e0021000 rw-p 00000000 00:00 0 -7fd0e0021000-7fd0e4000000 ---p 00000000 00:00 0 -7fd0e4000000-7fd0e4021000 rw-p 00000000 00:00 0 -7fd0e4021000-7fd0e8000000 ---p 00000000 00:00 0 -7fd0e8000000-7fd0e8021000 rw-p 00000000 00:00 0 -7fd0e8021000-7fd0ec000000 ---p 00000000 00:00 0 -7fd0ec000000-7fd0ec021000 rw-p 00000000 00:00 0 -7fd0ec021000-7fd0f0000000 ---p 00000000 00:00 0 -7fd0f0000000-7fd0f0021000 rw-p 00000000 00:00 0 -7fd0f0021000-7fd0f4000000 ---p 00000000 00:00 0 -7fd0f4000000-7fd0f4021000 rw-p 00000000 00:00 0 -7fd0f4021000-7fd0f8000000 ---p 00000000 00:00 0 -7fd0f8000000-7fd0f8021000 rw-p 00000000 00:00 0 -7fd0f8021000-7fd0fc000000 ---p 00000000 00:00 0 -7fd0fc000000-7fd0fc021000 rw-p 00000000 00:00 0 -7fd0fc021000-7fd100000000 ---p 00000000 00:00 0 -7fd100000000-7fd100021000 rw-p 00000000 00:00 0 -7fd100021000-7fd104000000 ---p 00000000 00:00 0 -7fd104000000-7fd104021000 rw-p 00000000 00:00 0 -7fd104021000-7fd108000000 ---p 00000000 00:00 0 -7fd108000000-7fd108021000 rw-p 00000000 00:00 0 -7fd108021000-7fd10c000000 ---p 00000000 00:00 0 -7fd10c000000-7fd10c021000 rw-p 00000000 00:00 0 -7fd10c021000-7fd110000000 ---p 00000000 00:00 0 -7fd1101c2000-7fd1101c6000 ---p 00000000 00:00 0 -7fd1101c6000-7fd1102c3000 rw-p 00000000 00:00 0 -7fd1102c3000-7fd1102c7000 ---p 00000000 00:00 0 -7fd1102c7000-7fd1103c4000 rw-p 00000000 00:00 0 -7fd1104c5000-7fd1104c9000 ---p 00000000 00:00 0 -7fd1104c9000-7fd1105c6000 rw-p 00000000 00:00 0 -7fd1105c6000-7fd1105ca000 ---p 00000000 00:00 0 -7fd1105ca000-7fd1106c7000 rw-p 00000000 00:00 0 -7fd1106c7000-7fd1106cb000 ---p 00000000 00:00 0 -7fd1106cb000-7fd1107c8000 rw-p 00000000 00:00 0 -7fd1108c9000-7fd1108cd000 ---p 00000000 00:00 0 -7fd1108cd000-7fd1109ca000 rw-p 00000000 00:00 0 -7fd1109ca000-7fd1109ce000 ---p 00000000 00:00 0 -7fd1109ce000-7fd110acb000 rw-p 00000000 00:00 0 -7fd110acb000-7fd110acf000 ---p 00000000 00:00 0 -7fd110acf000-7fd110bcc000 rw-p 00000000 00:00 0 -7fd1110d1000-7fd1110d5000 ---p 00000000 00:00 0 -7fd1110d5000-7fd1111d2000 rw-p 00000000 00:00 0 -7fd1111d2000-7fd1111d6000 ---p 00000000 00:00 0 -7fd1111d6000-7fd1112d3000 rw-p 00000000 00:00 0 -7fd1112d3000-7fd1112d7000 ---p 00000000 00:00 0 -7fd1112d7000-7fd1113d4000 rw-p 00000000 00:00 0 -7fd1115d6000-7fd1115da000 ---p 00000000 00:00 0 -7fd1115da000-7fd1116d7000 rw-p 00000000 00:00 0 -7fd1116d7000-7fd1116db000 ---p 00000000 00:00 0 -7fd1116db000-7fd1117d8000 rw-p 00000000 00:00 0 -7fd1118d9000-7fd1118dd000 ---p 00000000 00:00 0 -7fd1118dd000-7fd1119da000 rw-p 00000000 00:00 0 -7fd111adb000-7fd111adf000 ---p 00000000 00:00 0 -7fd111adf000-7fd111bdc000 rw-p 00000000 00:00 0 -7fd111cdd000-7fd111ce1000 ---p 00000000 00:00 0 -7fd111ce1000-7fd111dde000 rw-p 00000000 00:00 0 -7fd1120e1000-7fd1120e5000 ---p 00000000 00:00 0 -7fd1120e5000-7fd1121e2000 rw-p 00000000 00:00 0 -7fd1122e3000-7fd1122e7000 ---p 00000000 00:00 0 -7fd1122e7000-7fd1123e4000 rw-p 00000000 00:00 0 -7fd1125e6000-7fd1125ea000 ---p 00000000 00:00 0 -7fd1125ea000-7fd1126e7000 rw-p 00000000 00:00 0 -7fd1127e8000-7fd1127ec000 ---p 00000000 00:00 0 -7fd1127ec000-7fd1128e9000 rw-p 00000000 00:00 0 -7fd112aeb000-7fd112aef000 ---p 00000000 00:00 0 -7fd112aef000-7fd112bec000 rw-p 00000000 00:00 0 -7fd1130f1000-7fd1130f5000 ---p 00000000 00:00 0 -7fd1130f5000-7fd1131f2000 rw-p 00000000 00:00 0 -7fd1133f4000-7fd1133f8000 ---p 00000000 00:00 0 -7fd1133f8000-7fd1134f5000 rw-p 00000000 00:00 0 -7fd1136f7000-7fd1136fb000 ---p 00000000 00:00 0 -7fd1136fb000-7fd1137f8000 rw-p 00000000 00:00 0 -7fd113cfd000-7fd113d01000 ---p 00000000 00:00 0 -7fd113d01000-7fd113dfe000 rw-p 00000000 00:00 0 -7fd114000000-7fd114021000 rw-p 00000000 00:00 0 -7fd114021000-7fd118000000 ---p 00000000 00:00 0 -7fd118000000-7fd118021000 rw-p 00000000 00:00 0 -7fd118021000-7fd11c000000 ---p 00000000 00:00 0 -7fd11c000000-7fd11c021000 rw-p 00000000 00:00 0 -7fd11c021000-7fd120000000 ---p 00000000 00:00 0 -7fd120000000-7fd120021000 rw-p 00000000 00:00 0 -7fd120021000-7fd124000000 ---p 00000000 00:00 0 -7fd124000000-7fd124021000 rw-p 00000000 00:00 0 -7fd124021000-7fd128000000 ---p 00000000 00:00 0 -7fd128000000-7fd128021000 rw-p 00000000 00:00 0 -7fd128021000-7fd12c000000 ---p 00000000 00:00 0 -7fd12c000000-7fd12c021000 rw-p 00000000 00:00 0 -7fd12c021000-7fd130000000 ---p 00000000 00:00 0 -7fd130000000-7fd130021000 rw-p 00000000 00:00 0 -7fd130021000-7fd134000000 ---p 00000000 00:00 0 -7fd134000000-7fd134021000 rw-p 00000000 00:00 0 -7fd134021000-7fd138000000 ---p 00000000 00:00 0 -7fd138000000-7fd138176000 rw-p 00000000 00:00 0 -7fd138176000-7fd13c000000 ---p 00000000 00:00 0 -7fd13c000000-7fd13c021000 rw-p 00000000 00:00 0 -7fd13c021000-7fd140000000 ---p 00000000 00:00 0 -7fd140000000-7fd140021000 rw-p 00000000 00:00 0 -7fd140021000-7fd144000000 ---p 00000000 00:00 0 -7fd144000000-7fd144021000 rw-p 00000000 00:00 0 -7fd144021000-7fd148000000 ---p 00000000 00:00 0 -7fd148000000-7fd148021000 rw-p 00000000 00:00 0 -7fd148021000-7fd14c000000 ---p 00000000 00:00 0 -7fd14c000000-7fd14e63b000 rw-p 00000000 00:00 0 -7fd14e63b000-7fd150000000 ---p 00000000 00:00 0 -7fd150000000-7fd150021000 rw-p 00000000 00:00 0 -7fd150021000-7fd154000000 ---p 00000000 00:00 0 -7fd154000000-7fd154021000 rw-p 00000000 00:00 0 -7fd154021000-7fd158000000 ---p 00000000 00:00 0 -7fd158000000-7fd158021000 rw-p 00000000 00:00 0 -7fd158021000-7fd15c000000 ---p 00000000 00:00 0 -7fd15c000000-7fd15c021000 rw-p 00000000 00:00 0 -7fd15c021000-7fd160000000 ---p 00000000 00:00 0 -7fd160000000-7fd1631dc000 rw-p 00000000 00:00 0 -7fd1631dc000-7fd164000000 ---p 00000000 00:00 0 -7fd164000000-7fd164021000 rw-p 00000000 00:00 0 -7fd164021000-7fd168000000 ---p 00000000 00:00 0 -7fd168000000-7fd168021000 rw-p 00000000 00:00 0 -7fd168021000-7fd16c000000 ---p 00000000 00:00 0 -7fd16c000000-7fd16c021000 rw-p 00000000 00:00 0 -7fd16c021000-7fd170000000 ---p 00000000 00:00 0 -7fd170000000-7fd170021000 rw-p 00000000 00:00 0 -7fd170021000-7fd174000000 ---p 00000000 00:00 0 -7fd174000000-7fd174021000 rw-p 00000000 00:00 0 -7fd174021000-7fd178000000 ---p 00000000 00:00 0 -7fd178000000-7fd178021000 rw-p 00000000 00:00 0 -7fd178021000-7fd17c000000 ---p 00000000 00:00 0 -7fd17c000000-7fd17c021000 rw-p 00000000 00:00 0 -7fd17c021000-7fd180000000 ---p 00000000 00:00 0 -7fd180000000-7fd180021000 rw-p 00000000 00:00 0 -7fd180021000-7fd184000000 ---p 00000000 00:00 0 -7fd184000000-7fd1843d8000 rw-p 00000000 00:00 0 -7fd1843d8000-7fd188000000 ---p 00000000 00:00 0 -7fd188000000-7fd18802a000 rw-p 00000000 00:00 0 -7fd18802a000-7fd18c000000 ---p 00000000 00:00 0 -7fd18c000000-7fd18c595000 rw-p 00000000 00:00 0 -7fd18c595000-7fd190000000 ---p 00000000 00:00 0 -7fd190000000-7fd190485000 rw-p 00000000 00:00 0 -7fd190485000-7fd194000000 ---p 00000000 00:00 0 -7fd1941b4000-7fd1941b8000 ---p 00000000 00:00 0 -7fd1941b8000-7fd1942b5000 rw-p 00000000 00:00 0 -7fd1942b5000-7fd1942b9000 ---p 00000000 00:00 0 -7fd1942b9000-7fd1943b6000 rw-p 00000000 00:00 0 -7fd194539000-7fd194579000 rw-p 00000000 00:00 0 -7fd194579000-7fd194739000 ---p 00000000 00:00 0 -7fd194739000-7fd19473d000 ---p 00000000 00:00 0 -7fd19473d000-7fd19483a000 rw-p 00000000 00:00 0 -7fd19483a000-7fd19483e000 ---p 00000000 00:00 0 -7fd19483e000-7fd19493b000 rw-p 00000000 00:00 0 -7fd1949b4000-7fd1949b8000 ---p 00000000 00:00 0 -7fd1949b8000-7fd194ab5000 rw-p 00000000 00:00 0 -7fd194ab5000-7fd194ab9000 ---p 00000000 00:00 0 -7fd194ab9000-7fd194bb6000 rw-p 00000000 00:00 0 -7fd194bb6000-7fd194bba000 ---p 00000000 00:00 0 -7fd194bba000-7fd194cb7000 rw-p 00000000 00:00 0 -7fd194cb7000-7fd194cbb000 ---p 00000000 00:00 0 -7fd194cbb000-7fd194db8000 rw-p 00000000 00:00 0 -7fd194db8000-7fd194dbc000 ---p 00000000 00:00 0 -7fd194dbc000-7fd1950b9000 rw-p 00000000 00:00 0 -7fd1950b9000-7fd197c97000 r-xp 00000000 fd:01 528481 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libLLVM-4.0.so.1 -7fd197c97000-7fd197c98000 ---p 02bde000 fd:01 528481 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libLLVM-4.0.so.1 -7fd197c98000-7fd197fac000 r--p 02bde000 fd:01 528481 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libLLVM-4.0.so.1 -7fd197fac000-7fd197fb1000 rw-p 02ef2000 fd:01 528481 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libLLVM-4.0.so.1 -7fd197fb1000-7fd198000000 rw-p 00000000 00:00 0 -7fd198000000-7fd198033000 rw-p 00000000 00:00 0 -7fd198033000-7fd19c000000 ---p 00000000 00:00 0 -7fd19c000000-7fd19c02b000 rw-p 00000000 00:00 0 -7fd19c02b000-7fd1a0000000 ---p 00000000 00:00 0 -7fd1a0000000-7fd1a0035000 rw-p 00000000 00:00 0 -7fd1a0035000-7fd1a4000000 ---p 00000000 00:00 0 -7fd1a4000000-7fd1a4046000 rw-p 00000000 00:00 0 -7fd1a4046000-7fd1a8000000 ---p 00000000 00:00 0 -7fd1a8000000-7fd1a802d000 rw-p 00000000 00:00 0 -7fd1a802d000-7fd1ac000000 ---p 00000000 00:00 0 -7fd1ac000000-7fd1ac02b000 rw-p 00000000 00:00 0 -7fd1ac02b000-7fd1b0000000 ---p 00000000 00:00 0 -7fd1b0000000-7fd1b002d000 rw-p 00000000 00:00 0 -7fd1b002d000-7fd1b4000000 ---p 00000000 00:00 0 -7fd1b4000000-7fd1b4075000 rw-p 00000000 00:00 0 -7fd1b4075000-7fd1b8000000 ---p 00000000 00:00 0 -7fd1b8041000-7fd1b8045000 ---p 00000000 00:00 0 -7fd1b8045000-7fd1b8142000 rw-p 00000000 00:00 0 -7fd1b8142000-7fd1b8146000 ---p 00000000 00:00 0 -7fd1b8146000-7fd1b8243000 rw-p 00000000 00:00 0 -7fd1b8344000-7fd1b8348000 ---p 00000000 00:00 0 -7fd1b8348000-7fd1b8445000 rw-p 00000000 00:00 0 -7fd1b8445000-7fd1b8449000 ---p 00000000 00:00 0 -7fd1b8449000-7fd1b8546000 rw-p 00000000 00:00 0 -7fd1b8647000-7fd1b864b000 ---p 00000000 00:00 0 -7fd1b864b000-7fd1b8748000 rw-p 00000000 00:00 0 -7fd1b8748000-7fd1b874c000 ---p 00000000 00:00 0 -7fd1b874c000-7fd1b8849000 rw-p 00000000 00:00 0 -7fd1b8849000-7fd1b884d000 ---p 00000000 00:00 0 -7fd1b884d000-7fd1b894a000 rw-p 00000000 00:00 0 -7fd1b894a000-7fd1b894e000 ---p 00000000 00:00 0 -7fd1b894e000-7fd1b8a4b000 rw-p 00000000 00:00 0 -7fd1b8a4b000-7fd1b8a4f000 ---p 00000000 00:00 0 -7fd1b8a4f000-7fd1b8b4c000 rw-p 00000000 00:00 0 -7fd1b8b4c000-7fd1b8b50000 ---p 00000000 00:00 0 -7fd1b8b50000-7fd1b8c4d000 rw-p 00000000 00:00 0 -7fd1b8c4d000-7fd1b8c51000 ---p 00000000 00:00 0 -7fd1b8c51000-7fd1b8d4e000 rw-p 00000000 00:00 0 -7fd1b8d4e000-7fd1b8d52000 ---p 00000000 00:00 0 -7fd1b8d52000-7fd1b8e4f000 rw-p 00000000 00:00 0 -7fd1b8e4f000-7fd1b8e50000 ---p 00000000 00:00 0 -7fd1b8e50000-7fd1b8f51000 rw-p 00000000 00:00 0 -7fd1b8f51000-7fd1b8f52000 ---p 00000000 00:00 0 -7fd1b8f52000-7fd1b9253000 rw-p 00000000 00:00 0 -7fd1b9253000-7fd1b9254000 ---p 00000000 00:00 0 -7fd1b9254000-7fd1b9355000 rw-p 00000000 00:00 0 -7fd1b9355000-7fd1b9356000 ---p 00000000 00:00 0 -7fd1b9356000-7fd1b9657000 rw-p 00000000 00:00 0 -7fd1b9657000-7fd1b9857000 rw-p 00000000 00:00 0 -7fd1b9857000-7fd1b985a000 r-xp 00000000 fd:01 528488 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libfastvm.so -7fd1b985a000-7fd1b9a5a000 ---p 00003000 fd:01 528488 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libfastvm.so -7fd1b9a5a000-7fd1b9a5b000 r--p 00003000 fd:01 528488 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libfastvm.so -7fd1b9a5b000-7fd1b9a5c000 rw-p 00004000 fd:01 528488 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libfastvm.so -7fd1b9a5c000-7fd1b9ab9000 r-xp 00000000 fd:01 528483 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libevmjit.so -7fd1b9ab9000-7fd1b9cb9000 ---p 0005d000 fd:01 528483 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libevmjit.so -7fd1b9cb9000-7fd1b9cba000 r--p 0005d000 fd:01 528483 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libevmjit.so -7fd1b9cba000-7fd1b9cbb000 rw-p 0005e000 fd:01 528483 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libevmjit.so -7fd1b9cbb000-7fd1b9cbc000 rw-p 00000000 00:00 0 -7fd1b9cbc000-7fd1b9cd3000 r-xp 00000000 fd:01 524323 /lib/x86_64-linux-gnu/libgcc_s.so.1 -7fd1b9cd3000-7fd1b9ed2000 ---p 00017000 fd:01 524323 /lib/x86_64-linux-gnu/libgcc_s.so.1 -7fd1b9ed2000-7fd1b9ed3000 r--p 00016000 fd:01 524323 /lib/x86_64-linux-gnu/libgcc_s.so.1 -7fd1b9ed3000-7fd1b9ed4000 rw-p 00017000 fd:01 524323 /lib/x86_64-linux-gnu/libgcc_s.so.1 -7fd1b9ed4000-7fd1ba04d000 r-xp 00000000 fd:01 12978823 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25 -7fd1ba04d000-7fd1ba24d000 ---p 00179000 fd:01 12978823 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25 -7fd1ba24d000-7fd1ba257000 r--p 00179000 fd:01 12978823 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25 -7fd1ba257000-7fd1ba259000 rw-p 00183000 fd:01 12978823 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25 -7fd1ba259000-7fd1ba25d000 rw-p 00000000 00:00 0 -7fd1ba25d000-7fd1ba264000 r-xp 00000000 fd:01 528487 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libffi.so.6 -7fd1ba264000-7fd1ba463000 ---p 00007000 fd:01 528487 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libffi.so.6 -7fd1ba463000-7fd1ba464000 r--p 00006000 fd:01 528487 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libffi.so.6 -7fd1ba464000-7fd1ba465000 rw-p 00007000 fd:01 528487 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libffi.so.6 -7fd1ba465000-7fd1ba496000 r-xp 00000000 fd:01 528484 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libedit.so.2 -7fd1ba496000-7fd1ba696000 ---p 00031000 fd:01 528484 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libedit.so.2 -7fd1ba696000-7fd1ba698000 r--p 00031000 fd:01 528484 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libedit.so.2 -7fd1ba698000-7fd1ba699000 rw-p 00033000 fd:01 528484 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libedit.so.2 -7fd1ba699000-7fd1ba69d000 rw-p 00000000 00:00 0 -7fd1ba69d000-7fd1ba6c2000 r-xp 00000000 fd:01 528482 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libtinfo.so.5 -7fd1ba6c2000-7fd1ba8c1000 ---p 00025000 fd:01 528482 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libtinfo.so.5 -7fd1ba8c1000-7fd1ba8c5000 r--p 00024000 fd:01 528482 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libtinfo.so.5 -7fd1ba8c5000-7fd1ba8c6000 rw-p 00028000 fd:01 528482 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libtinfo.so.5 -7fd1ba8c6000-7fd1ba8df000 r-xp 00000000 fd:01 528480 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libz.so.1 -7fd1ba8df000-7fd1baade000 ---p 00019000 fd:01 528480 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libz.so.1 -7fd1baade000-7fd1baadf000 r--p 00018000 fd:01 528480 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libz.so.1 -7fd1baadf000-7fd1baae0000 rw-p 00019000 fd:01 528480 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libz.so.1 -7fd1baae0000-7fd1bace0000 rw-p 00000000 00:00 0 -7fd1bad61000-7fd1bad74000 r-xp 00000000 fd:01 528486 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libbsd.so.0 -7fd1bad74000-7fd1baf73000 ---p 00013000 fd:01 528486 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libbsd.so.0 -7fd1baf73000-7fd1baf74000 r--p 00012000 fd:01 528486 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libbsd.so.0 -7fd1baf74000-7fd1baf75000 rw-p 00013000 fd:01 528486 /home/jay/workspace/aion/modAionImpl/native/linux/fastvm/libbsd.so.0 -7fd1baf75000-7fd1baf76000 rw-p 00000000 00:00 0 -7fd1baf76000-7fd1baf7a000 ---p 00000000 00:00 0 -7fd1baf7a000-7fd1bb077000 rw-p 00000000 00:00 0 -7fd1bb077000-7fd1bb078000 ---p 00000000 00:00 0 -7fd1bb078000-7fd1bb179000 rw-p 00000000 00:00 0 -7fd1bb179000-7fd1bb17a000 ---p 00000000 00:00 0 -7fd1bb17a000-7fd1bb27b000 rw-p 00000000 00:00 0 -7fd1bb27b000-7fd1bb27c000 ---p 00000000 00:00 0 -7fd1bb27c000-7fd1bb37d000 rw-p 00000000 00:00 0 -7fd1bb37d000-7fd1bb37e000 ---p 00000000 00:00 0 -7fd1bb37e000-7fd1bb47f000 rw-p 00000000 00:00 0 -7fd1bb47f000-7fd1bb480000 ---p 00000000 00:00 0 -7fd1bb480000-7fd1bb581000 rw-p 00000000 00:00 0 -7fd1bb581000-7fd1bb582000 ---p 00000000 00:00 0 -7fd1bb582000-7fd1bb683000 rw-p 00000000 00:00 0 -7fd1bb683000-7fd1bb684000 ---p 00000000 00:00 0 -7fd1bb684000-7fd1bb785000 rw-p 00000000 00:00 0 -7fd1bb785000-7fd1bb789000 r-xp 00000000 fd:01 528583 /home/jay/workspace/aion/modAionImpl/native/linux/blake2b/libblake2b.so -7fd1bb789000-7fd1bb988000 ---p 00004000 fd:01 528583 /home/jay/workspace/aion/modAionImpl/native/linux/blake2b/libblake2b.so -7fd1bb988000-7fd1bb989000 r--p 00003000 fd:01 528583 /home/jay/workspace/aion/modAionImpl/native/linux/blake2b/libblake2b.so -7fd1bb989000-7fd1bb98a000 rw-p 00004000 fd:01 528583 /home/jay/workspace/aion/modAionImpl/native/linux/blake2b/libblake2b.so -7fd1bb98a000-7fd1bbb8a000 rw-p 00000000 00:00 0 -7fd1bbb8a000-7fd1bbbab000 r-xp 00000000 fd:01 528578 /home/jay/workspace/aion/modAionImpl/native/linux/sodium/libsodiumjni.so -7fd1bbbab000-7fd1bbdaa000 ---p 00021000 fd:01 528578 /home/jay/workspace/aion/modAionImpl/native/linux/sodium/libsodiumjni.so -7fd1bbdaa000-7fd1bbdab000 r--p 00020000 fd:01 528578 /home/jay/workspace/aion/modAionImpl/native/linux/sodium/libsodiumjni.so -7fd1bbdab000-7fd1bbdac000 rw-p 00021000 fd:01 528578 /home/jay/workspace/aion/modAionImpl/native/linux/sodium/libsodiumjni.so -7fd1bbdac000-7fd1bbdfe000 r-xp 00000000 fd:01 528581 /home/jay/workspace/aion/modAionImpl/native/linux/sodium/libsodium.so -7fd1bbdfe000-7fd1bbffe000 ---p 00052000 fd:01 528581 /home/jay/workspace/aion/modAionImpl/native/linux/sodium/libsodium.so -7fd1bbffe000-7fd1bbfff000 r--p 00052000 fd:01 528581 /home/jay/workspace/aion/modAionImpl/native/linux/sodium/libsodium.so -7fd1bbfff000-7fd1bc000000 rw-p 00053000 fd:01 528581 /home/jay/workspace/aion/modAionImpl/native/linux/sodium/libsodium.so -7fd1bc000000-7fd1bed72000 rw-p 00000000 00:00 0 -7fd1bed72000-7fd1c0000000 ---p 00000000 00:00 0 -7fd1c0000000-7fd1c0021000 rw-p 00000000 00:00 0 -7fd1c0021000-7fd1c4000000 ---p 00000000 00:00 0 -7fd1c4000000-7fd1c4021000 rw-p 00000000 00:00 0 -7fd1c4021000-7fd1c8000000 ---p 00000000 00:00 0 -7fd1c8000000-7fd1c895b000 rw-p 00000000 00:00 0 -7fd1c895b000-7fd1cc000000 ---p 00000000 00:00 0 -7fd1cc000000-7fd1cc021000 rw-p 00000000 00:00 0 -7fd1cc021000-7fd1d0000000 ---p 00000000 00:00 0 -7fd1d0000000-7fd1d0021000 rw-p 00000000 00:00 0 -7fd1d0021000-7fd1d4000000 ---p 00000000 00:00 0 -7fd1d4000000-7fd1d47e2000 rw-p 00000000 00:00 0 -7fd1d47e2000-7fd1d8000000 ---p 00000000 00:00 0 -7fd1d8000000-7fd1d8021000 rw-p 00000000 00:00 0 -7fd1d8021000-7fd1dc000000 ---p 00000000 00:00 0 -7fd1dc000000-7fd1dc021000 rw-p 00000000 00:00 0 -7fd1dc021000-7fd1e0000000 ---p 00000000 00:00 0 -7fd1e0000000-7fd1e2081000 rw-p 00000000 00:00 0 -7fd1e2081000-7fd1e4000000 ---p 00000000 00:00 0 -7fd1e4000000-7fd1e4021000 rw-p 00000000 00:00 0 -7fd1e4021000-7fd1e8000000 ---p 00000000 00:00 0 -7fd1e8000000-7fd1e8021000 rw-p 00000000 00:00 0 -7fd1e8021000-7fd1ec000000 ---p 00000000 00:00 0 -7fd1ec000000-7fd1ec021000 rw-p 00000000 00:00 0 -7fd1ec021000-7fd1f0000000 ---p 00000000 00:00 0 -7fd1f0000000-7fd1f0638000 rw-p 00000000 00:00 0 -7fd1f0638000-7fd1f4000000 ---p 00000000 00:00 0 -7fd1f4000000-7fd1f4021000 rw-p 00000000 00:00 0 -7fd1f4021000-7fd1f8000000 ---p 00000000 00:00 0 -7fd1f8000000-7fd1f80bb000 rw-p 00000000 00:00 0 -7fd1f80bb000-7fd1fc000000 ---p 00000000 00:00 0 -7fd1fc0f8000-7fd1fc2f8000 rw-p 00000000 00:00 0 -7fd1fc2f8000-7fd1fc2fc000 ---p 00000000 00:00 0 -7fd1fc2fc000-7fd1fc3f9000 rw-p 00000000 00:00 0 -7fd1fc3f9000-7fd1fc3fd000 ---p 00000000 00:00 0 -7fd1fc3fd000-7fd1fc4fa000 rw-p 00000000 00:00 0 -7fd1fc4fa000-7fd1fc4fe000 ---p 00000000 00:00 0 -7fd1fc4fe000-7fd1fc5fb000 rw-p 00000000 00:00 0 -7fd1fc5fb000-7fd1fc5fd000 r-xp 00000000 fd:01 6291547 /home/jay/ide/jdk-11.0.1/lib/libextnet.so -7fd1fc5fd000-7fd1fc7fc000 ---p 00002000 fd:01 6291547 /home/jay/ide/jdk-11.0.1/lib/libextnet.so -7fd1fc7fc000-7fd1fc7fd000 r--p 00001000 fd:01 6291547 /home/jay/ide/jdk-11.0.1/lib/libextnet.so -7fd1fc7fd000-7fd1fc7fe000 rw-p 00002000 fd:01 6291547 /home/jay/ide/jdk-11.0.1/lib/libextnet.so -7fd1fc7fe000-7fd1fc802000 ---p 00000000 00:00 0 -7fd1fc802000-7fd1fcaff000 rw-p 00000000 00:00 0 -7fd1fcaff000-7fd1fcb15000 r-xp 00000000 fd:01 6291566 /home/jay/ide/jdk-11.0.1/lib/libnet.so -7fd1fcb15000-7fd1fcd14000 ---p 00016000 fd:01 6291566 /home/jay/ide/jdk-11.0.1/lib/libnet.so -7fd1fcd14000-7fd1fcd15000 r--p 00015000 fd:01 6291566 /home/jay/ide/jdk-11.0.1/lib/libnet.so -7fd1fcd15000-7fd1fcd16000 rw-p 00016000 fd:01 6291566 /home/jay/ide/jdk-11.0.1/lib/libnet.so -7fd1fcd16000-7fd1fcd26000 r-xp 00000000 fd:01 6291567 /home/jay/ide/jdk-11.0.1/lib/libnio.so -7fd1fcd26000-7fd1fcf25000 ---p 00010000 fd:01 6291567 /home/jay/ide/jdk-11.0.1/lib/libnio.so -7fd1fcf25000-7fd1fcf26000 r--p 0000f000 fd:01 6291567 /home/jay/ide/jdk-11.0.1/lib/libnio.so -7fd1fcf26000-7fd1fcf27000 rw-p 00010000 fd:01 6291567 /home/jay/ide/jdk-11.0.1/lib/libnio.so -7fd1fcf27000-7fd1fcf2b000 ---p 00000000 00:00 0 -7fd1fcf2b000-7fd1fd028000 rw-p 00000000 00:00 0 -7fd1fd028000-7fd1fd029000 ---p 00000000 00:00 0 -7fd1fd029000-7fd1fd12a000 rw-p 00000000 00:00 0 -7fd1fd12a000-7fd1fd12e000 ---p 00000000 00:00 0 -7fd1fd12e000-7fd1fd22b000 rw-p 00000000 00:00 0 -7fd1fd22b000-7fd1fd22f000 ---p 00000000 00:00 0 -7fd1fd22f000-7fd1fd32c000 rw-p 00000000 00:00 0 -7fd1fd32c000-7fd1fd330000 ---p 00000000 00:00 0 -7fd1fd330000-7fd1fd42d000 rw-p 00000000 00:00 0 -7fd1fd42d000-7fd1fd431000 ---p 00000000 00:00 0 -7fd1fd431000-7fd1fd52e000 rw-p 00000000 00:00 0 -7fd1fd52e000-7fd1fd532000 ---p 00000000 00:00 0 -7fd1fd532000-7fd1fd62f000 rw-p 00000000 00:00 0 -7fd1fd62f000-7fd1fe000000 r--p 00000000 fd:01 12982903 /usr/lib/locale/locale-archive -7fd1fe000000-7fd200000000 rw-p 00000000 00:00 0 -7fd200000000-7fd200021000 rw-p 00000000 00:00 0 -7fd200021000-7fd204000000 ---p 00000000 00:00 0 -7fd2040dc000-7fd2040e0000 ---p 00000000 00:00 0 -7fd2040e0000-7fd2041dd000 rw-p 00000000 00:00 0 -7fd2041dd000-7fd2041e1000 ---p 00000000 00:00 0 -7fd2041e1000-7fd2042de000 rw-p 00000000 00:00 0 -7fd2042de000-7fd2042df000 ---p 00000000 00:00 0 -7fd2042df000-7fd2054f0000 rw-p 00000000 00:00 0 -7fd2054f0000-7fd2081f0000 ---p 00000000 00:00 0 -7fd2081f0000-7fd209300000 rw-p 00000000 00:00 0 -7fd209300000-7fd20c000000 ---p 00000000 00:00 0 -7fd20c000000-7fd20c023000 rw-p 00000000 00:00 0 -7fd20c023000-7fd210000000 ---p 00000000 00:00 0 -7fd210022000-7fd210026000 ---p 00000000 00:00 0 -7fd210026000-7fd210044000 rw-p 00000000 00:00 0 -7fd210044000-7fd2100b7000 r-xp 00000000 00:00 0 -7fd2100b7000-7fd210969000 rw-p 00000000 00:00 0 -7fd210969000-7fd21096a000 ---p 00000000 00:00 0 -7fd21096a000-7fd210a6b000 rw-p 00000000 00:00 0 -7fd210a6b000-7fd210a6c000 ---p 00000000 00:00 0 -7fd210a6c000-7fd211577000 rw-p 00000000 00:00 0 -7fd211577000-7fd211578000 ---p 00000000 00:00 0 -7fd211578000-7fd211679000 rw-p 00000000 00:00 0 -7fd211679000-7fd21167a000 ---p 00000000 00:00 0 -7fd21167a000-7fd211a9e000 rw-p 00000000 00:00 0 -7fd211a9e000-7fd21203e000 ---p 00000000 00:00 0 -7fd21203e000-7fd212260000 rw-p 00000000 00:00 0 -7fd212260000-7fd212800000 ---p 00000000 00:00 0 -7fd212800000-7fd212a22000 rw-p 00000000 00:00 0 -7fd212a22000-7fd212fc2000 ---p 00000000 00:00 0 -7fd212fc2000-7fd2139cc000 rw-p 00000000 00:00 0 -7fd2139cc000-7fd2139cd000 ---p 00000000 00:00 0 -7fd2139cd000-7fd213ada000 rw-p 00000000 00:00 0 -7fd213ada000-7fd213bb9000 ---p 00000000 00:00 0 -7fd213bb9000-7fd213e29000 rwxp 00000000 00:00 0 -7fd213e29000-7fd21414a000 ---p 00000000 00:00 0 -7fd21414a000-7fd214b0a000 rwxp 00000000 00:00 0 -7fd214b0a000-7fd21b681000 ---p 00000000 00:00 0 -7fd21b681000-7fd21bc81000 rwxp 00000000 00:00 0 -7fd21bc81000-7fd222bb9000 ---p 00000000 00:00 0 -7fd222bb9000-7fd22af5d000 r--s 00000000 fd:01 6291577 /home/jay/ide/jdk-11.0.1/lib/modules -7fd22af5d000-7fd22af78000 r-xp 00000000 fd:01 6291558 /home/jay/ide/jdk-11.0.1/lib/libjimage.so -7fd22af78000-7fd22b177000 ---p 0001b000 fd:01 6291558 /home/jay/ide/jdk-11.0.1/lib/libjimage.so -7fd22b177000-7fd22b179000 r--p 0001a000 fd:01 6291558 /home/jay/ide/jdk-11.0.1/lib/libjimage.so -7fd22b179000-7fd22b17a000 rw-p 0001c000 fd:01 6291558 /home/jay/ide/jdk-11.0.1/lib/libjimage.so -7fd22b17a000-7fd22b181000 r-xp 00000000 fd:01 6291576 /home/jay/ide/jdk-11.0.1/lib/libzip.so -7fd22b181000-7fd22b380000 ---p 00007000 fd:01 6291576 /home/jay/ide/jdk-11.0.1/lib/libzip.so -7fd22b380000-7fd22b381000 r--p 00006000 fd:01 6291576 /home/jay/ide/jdk-11.0.1/lib/libzip.so -7fd22b381000-7fd22b382000 rw-p 00007000 fd:01 6291576 /home/jay/ide/jdk-11.0.1/lib/libzip.so -7fd22b382000-7fd22b38d000 r-xp 00000000 fd:01 529151 /lib/x86_64-linux-gnu/libnss_files-2.27.so -7fd22b38d000-7fd22b58c000 ---p 0000b000 fd:01 529151 /lib/x86_64-linux-gnu/libnss_files-2.27.so -7fd22b58c000-7fd22b58d000 r--p 0000a000 fd:01 529151 /lib/x86_64-linux-gnu/libnss_files-2.27.so -7fd22b58d000-7fd22b58e000 rw-p 0000b000 fd:01 529151 /lib/x86_64-linux-gnu/libnss_files-2.27.so -7fd22b58e000-7fd22b594000 rw-p 00000000 00:00 0 -7fd22b594000-7fd22b5ab000 r-xp 00000000 fd:01 529145 /lib/x86_64-linux-gnu/libnsl-2.27.so -7fd22b5ab000-7fd22b7aa000 ---p 00017000 fd:01 529145 /lib/x86_64-linux-gnu/libnsl-2.27.so -7fd22b7aa000-7fd22b7ab000 r--p 00016000 fd:01 529145 /lib/x86_64-linux-gnu/libnsl-2.27.so -7fd22b7ab000-7fd22b7ac000 rw-p 00017000 fd:01 529145 /lib/x86_64-linux-gnu/libnsl-2.27.so -7fd22b7ac000-7fd22b7ae000 rw-p 00000000 00:00 0 -7fd22b7ae000-7fd22b7b9000 r-xp 00000000 fd:01 529162 /lib/x86_64-linux-gnu/libnss_nis-2.27.so -7fd22b7b9000-7fd22b9b8000 ---p 0000b000 fd:01 529162 /lib/x86_64-linux-gnu/libnss_nis-2.27.so -7fd22b9b8000-7fd22b9b9000 r--p 0000a000 fd:01 529162 /lib/x86_64-linux-gnu/libnss_nis-2.27.so -7fd22b9b9000-7fd22b9ba000 rw-p 0000b000 fd:01 529162 /lib/x86_64-linux-gnu/libnss_nis-2.27.so -7fd22b9ba000-7fd22b9c2000 r-xp 00000000 fd:01 529147 /lib/x86_64-linux-gnu/libnss_compat-2.27.so -7fd22b9c2000-7fd22bbc2000 ---p 00008000 fd:01 529147 /lib/x86_64-linux-gnu/libnss_compat-2.27.so -7fd22bbc2000-7fd22bbc3000 r--p 00008000 fd:01 529147 /lib/x86_64-linux-gnu/libnss_compat-2.27.so -7fd22bbc3000-7fd22bbc4000 rw-p 00009000 fd:01 529147 /lib/x86_64-linux-gnu/libnss_compat-2.27.so -7fd22bbc4000-7fd22bbef000 r-xp 00000000 fd:01 6291554 /home/jay/ide/jdk-11.0.1/lib/libjava.so -7fd22bbef000-7fd22bdee000 ---p 0002b000 fd:01 6291554 /home/jay/ide/jdk-11.0.1/lib/libjava.so -7fd22bdee000-7fd22bdef000 r--p 0002a000 fd:01 6291554 /home/jay/ide/jdk-11.0.1/lib/libjava.so -7fd22bdef000-7fd22bdf1000 rw-p 0002b000 fd:01 6291554 /home/jay/ide/jdk-11.0.1/lib/libjava.so -7fd22bdf1000-7fd22bdfe000 r-xp 00000000 fd:01 6291575 /home/jay/ide/jdk-11.0.1/lib/libverify.so -7fd22bdfe000-7fd22bffd000 ---p 0000d000 fd:01 6291575 /home/jay/ide/jdk-11.0.1/lib/libverify.so -7fd22bffd000-7fd22bfff000 r--p 0000c000 fd:01 6291575 /home/jay/ide/jdk-11.0.1/lib/libverify.so -7fd22bfff000-7fd22c000000 rw-p 0000e000 fd:01 6291575 /home/jay/ide/jdk-11.0.1/lib/libverify.so -7fd22c000000-7fd22c7f3000 rw-p 00000000 00:00 0 -7fd22c7f3000-7fd230000000 ---p 00000000 00:00 0 -7fd230020000-7fd23008f000 rw-p 00000000 00:00 0 -7fd23008f000-7fd230166000 ---p 00000000 00:00 0 -7fd230166000-7fd23016d000 r-xp 00000000 fd:01 529202 /lib/x86_64-linux-gnu/librt-2.27.so -7fd23016d000-7fd23036c000 ---p 00007000 fd:01 529202 /lib/x86_64-linux-gnu/librt-2.27.so -7fd23036c000-7fd23036d000 r--p 00006000 fd:01 529202 /lib/x86_64-linux-gnu/librt-2.27.so -7fd23036d000-7fd23036e000 rw-p 00007000 fd:01 529202 /lib/x86_64-linux-gnu/librt-2.27.so -7fd23036e000-7fd230372000 ---p 00000000 00:00 0 -7fd230372000-7fd23046f000 rw-p 00000000 00:00 0 -7fd23046f000-7fd23060c000 r-xp 00000000 fd:01 529124 /lib/x86_64-linux-gnu/libm-2.27.so -7fd23060c000-7fd23080b000 ---p 0019d000 fd:01 529124 /lib/x86_64-linux-gnu/libm-2.27.so -7fd23080b000-7fd23080c000 r--p 0019c000 fd:01 529124 /lib/x86_64-linux-gnu/libm-2.27.so -7fd23080c000-7fd23080d000 rw-p 0019d000 fd:01 529124 /lib/x86_64-linux-gnu/libm-2.27.so -7fd23080d000-7fd231993000 r-xp 00000000 fd:01 6291588 /home/jay/ide/jdk-11.0.1/lib/server/libjvm.so -7fd231993000-7fd231b92000 ---p 01186000 fd:01 6291588 /home/jay/ide/jdk-11.0.1/lib/server/libjvm.so -7fd231b92000-7fd231c5c000 r--p 01185000 fd:01 6291588 /home/jay/ide/jdk-11.0.1/lib/server/libjvm.so -7fd231c5c000-7fd231c96000 rw-p 0124f000 fd:01 6291588 /home/jay/ide/jdk-11.0.1/lib/server/libjvm.so -7fd231c96000-7fd231cec000 rw-p 00000000 00:00 0 -7fd231cec000-7fd231ed3000 r-xp 00000000 fd:01 529061 /lib/x86_64-linux-gnu/libc-2.27.so -7fd231ed3000-7fd2320d3000 ---p 001e7000 fd:01 529061 /lib/x86_64-linux-gnu/libc-2.27.so -7fd2320d3000-7fd2320d7000 r--p 001e7000 fd:01 529061 /lib/x86_64-linux-gnu/libc-2.27.so -7fd2320d7000-7fd2320d9000 rw-p 001eb000 fd:01 529061 /lib/x86_64-linux-gnu/libc-2.27.so -7fd2320d9000-7fd2320dd000 rw-p 00000000 00:00 0 -7fd2320dd000-7fd2320e0000 r-xp 00000000 fd:01 529084 /lib/x86_64-linux-gnu/libdl-2.27.so -7fd2320e0000-7fd2322df000 ---p 00003000 fd:01 529084 /lib/x86_64-linux-gnu/libdl-2.27.so -7fd2322df000-7fd2322e0000 r--p 00002000 fd:01 529084 /lib/x86_64-linux-gnu/libdl-2.27.so -7fd2322e0000-7fd2322e1000 rw-p 00003000 fd:01 529084 /lib/x86_64-linux-gnu/libdl-2.27.so -7fd2322e1000-7fd2322f0000 r-xp 00000000 fd:01 6291539 /home/jay/ide/jdk-11.0.1/lib/jli/libjli.so -7fd2322f0000-7fd2324f0000 ---p 0000f000 fd:01 6291539 /home/jay/ide/jdk-11.0.1/lib/jli/libjli.so -7fd2324f0000-7fd2324f1000 r--p 0000f000 fd:01 6291539 /home/jay/ide/jdk-11.0.1/lib/jli/libjli.so -7fd2324f1000-7fd2324f2000 rw-p 00010000 fd:01 6291539 /home/jay/ide/jdk-11.0.1/lib/jli/libjli.so -7fd2324f2000-7fd23250c000 r-xp 00000000 fd:01 529194 /lib/x86_64-linux-gnu/libpthread-2.27.so -7fd23250c000-7fd23270b000 ---p 0001a000 fd:01 529194 /lib/x86_64-linux-gnu/libpthread-2.27.so -7fd23270b000-7fd23270c000 r--p 00019000 fd:01 529194 /lib/x86_64-linux-gnu/libpthread-2.27.so -7fd23270c000-7fd23270d000 rw-p 0001a000 fd:01 529194 /lib/x86_64-linux-gnu/libpthread-2.27.so -7fd23270d000-7fd232711000 rw-p 00000000 00:00 0 -7fd232711000-7fd23272d000 r-xp 00000000 fd:01 529233 /lib/x86_64-linux-gnu/libz.so.1.2.11 -7fd23272d000-7fd23292c000 ---p 0001c000 fd:01 529233 /lib/x86_64-linux-gnu/libz.so.1.2.11 -7fd23292c000-7fd23292d000 r--p 0001b000 fd:01 529233 /lib/x86_64-linux-gnu/libz.so.1.2.11 -7fd23292d000-7fd23292e000 rw-p 0001c000 fd:01 529233 /lib/x86_64-linux-gnu/libz.so.1.2.11 -7fd23292e000-7fd232955000 r-xp 00000000 fd:01 529033 /lib/x86_64-linux-gnu/ld-2.27.so -7fd232971000-7fd2329dd000 rw-p 00000000 00:00 0 -7fd2329dd000-7fd232a22000 r-xp 00000000 fd:01 14295339 /opt/eset/esets/lib/libesets_pac.so -7fd232a22000-7fd232b21000 ---p 00045000 fd:01 14295339 /opt/eset/esets/lib/libesets_pac.so -7fd232b21000-7fd232b24000 rw-p 00044000 fd:01 14295339 /opt/eset/esets/lib/libesets_pac.so -7fd232b24000-7fd232b39000 rw-p 00000000 00:00 0 -7fd232b39000-7fd232b3e000 r-xp 00000000 00:00 0 -7fd232b3e000-7fd232b3f000 r--p 00000000 00:00 0 -7fd232b3f000-7fd232b44000 rw-p 00000000 00:00 0 -7fd232b44000-7fd232b4b000 ---p 00000000 00:00 0 -7fd232b4b000-7fd232b53000 rw-s 00000000 fd:01 1968665 /tmp/hsperfdata_jay/25106 -7fd232b53000-7fd232b54000 ---p 00000000 00:00 0 -7fd232b54000-7fd232b55000 r--p 00000000 00:00 0 -7fd232b55000-7fd232b56000 r--p 00027000 fd:01 529033 /lib/x86_64-linux-gnu/ld-2.27.so -7fd232b56000-7fd232b57000 rw-p 00028000 fd:01 529033 /lib/x86_64-linux-gnu/ld-2.27.so -7fd232b57000-7fd232b58000 rw-p 00000000 00:00 0 -7ffd40b0c000-7ffd40b2d000 rw-p 00000000 00:00 0 [stack] -7ffd40b67000-7ffd40b6a000 r--p 00000000 00:00 0 [vvar] -7ffd40b6a000-7ffd40b6c000 r-xp 00000000 00:00 0 [vdso] -ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] - - -VM Arguments: -jvm_args: -Dorg.gradle.native=false -Dfile.encoding=UTF-8 -Duser.country=CA -Duser.language=en -Duser.variant -ea -java_command: worker.org.gradle.process.internal.worker.GradleWorkerMain 'Gradle Test Executor 9' -java_class_path (initial): /home/jay/.gradle/caches/4.9/workerMain/gradle-worker.jar:/home/jay/workspace/aion/modAionImpl/build/classes/java/test:/home/jay/workspace/aion/modAionImpl/build/resources/test:/home/jay/workspace/aion/modAionImpl/build/classes/java/main:/home/jay/workspace/aion/modAionImpl/build/resources/main:/home/jay/workspace/aion/aion_fastvm/modFastVM/build/libs/aion_fastvm.jar:/home/jay/workspace/aion/modPrecompiled/build/libs/modPrecompiled.jar:/home/jay/workspace/aion/modVM/build/libs/modVM.jar:/home/jay/workspace/aion/modAion/build/libs/modAion.jar:/home/jay/workspace/aion/modMcf/build/libs/modMcf.jar:/home/jay/workspace/aion/modTxPoolImpl/build/libs/modTxPoolImpl.jar:/home/jay/workspace/aion/modTxPool/build/libs/modTxPool.jar:/home/jay/workspace/aion/aion_api/build/libs/aion_api.jar:/home/jay/workspace/aion/aion_api/lib/libnzmq.jar:/home/jay/workspace/aion/modDbImpl/build/classes/java/test:/home/jay/workspace/aion/modDbImpl/build/resources/test:/home/jay/workspace/aion/modDbImpl/build/libs/modDbImpl.jar:/home/jay/workspace/aion/modAionBase/build/libs/modAionBase.jar:/home/jay/workspace/aion/modCrypto/build/libs/modCrypto.jar:/home/jay/workspace/aion/modRlp/build/libs/modRlp.jar:/home/jay/workspace/aion/modP2pImpl/build/libs/modP2pImpl.jar:/home/jay/workspace/aion/lib/miniupnpc_linux.jar:/home/jay/workspace/aion/modEvtMgrImpl/build/libs/modEvtMgrImpl.jar:/home/jay/workspace/aion/modLogger/build/libs/modLogger.jar:/home/jay/workspace/aion/modP2p/build/libs/modP2p.jar:/home/jay/workspace/aion/modEvtMgr/build/libs/modEvtMgr.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.json/json/20180813/8566b2b0391d9d4479ea225645c6ed47ef17fe41/json-20180813.jar:/home/jay/.gradle/caches/modules-2/files-2.1/info.picocli/picocli/3.6.1/8f0f5beccab1a66cebc871a86800687095a96bed/picocli-3.6.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/pl.pragmatists/JUnitParams/1.1.1/20981e022b8d21deb374c2888bb0be5f6d371a8f/JUnitParams-1.1.1.jar:/home/jay/.gradle/caches/mod -Launcher Type: SUN_STANDARD - -[Global flags] - intx CICompilerCount = 4 {product} {ergonomic} - uint ConcGCThreads = 3 {product} {ergonomic} - uint G1ConcRefinementThreads = 10 {product} {ergonomic} - size_t G1HeapRegionSize = 1048576 {product} {ergonomic} - uintx GCDrainStackTargetSize = 64 {product} {ergonomic} - size_t InitialHeapSize = 262144000 {product} {ergonomic} - size_t MarkStackSize = 4194304 {product} {ergonomic} - size_t MaxHeapSize = 4164943872 {product} {ergonomic} - size_t MaxNewSize = 2498756608 {product} {ergonomic} - size_t MinHeapDeltaBytes = 1048576 {product} {ergonomic} - uintx NonNMethodCodeHeapSize = 5835340 {pd product} {ergonomic} - uintx NonProfiledCodeHeapSize = 122911450 {pd product} {ergonomic} - uintx ProfiledCodeHeapSize = 122911450 {pd product} {ergonomic} - uintx ReservedCodeCacheSize = 251658240 {pd product} {ergonomic} - bool SegmentedCodeCache = true {product} {ergonomic} - bool UseCompressedClassPointers = true {lp64_product} {ergonomic} - bool UseCompressedOops = true {lp64_product} {ergonomic} - bool UseG1GC = true {product} {ergonomic} - -Logging: -Log output configuration: - #0: stdout all=warning uptime,level,tags - #1: stderr all=off uptime,level,tags - -Environment Variables: -JAVA_HOME=/usr/lib/jvm/jdk-11.0.1 -PATH=/usr/lib/jvm/jdk-11.0.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin -USERNAME=jay -SHELL=/bin/bash -DISPLAY=:0 - -Signal Handlers: -SIGSEGV: [libjvm.so+0xe58b80], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGBUS: [libjvm.so+0xe58b80], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGFPE: [libjvm.so+0xe58b80], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGPIPE: [libjvm.so+0xc2ec80], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGXFSZ: [libjvm.so+0xc2ec80], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGILL: [libjvm.so+0xe58b80], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGUSR2: [libjvm.so+0xc2eb20], sa_mask[0]=00100000000000000000000000000000, sa_flags=SA_RESTART|SA_SIGINFO -SIGHUP: [libjvm.so+0xc2ee80], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGINT: [libjvm.so+0xc2ee80], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGTERM: [libjvm.so+0xc2ee80], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO -SIGQUIT: [libjvm.so+0xc2ee80], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO - - ---------------- S Y S T E M --------------- - -OS:DISTRIB_ID=Ubuntu -DISTRIB_RELEASE=18.04 -DISTRIB_CODENAME=bionic -DISTRIB_DESCRIPTION="Ubuntu 18.04.1 LTS" -uname:Linux 4.15.0-43-generic #46-Ubuntu SMP Thu Dec 6 14:45:28 UTC 2018 x86_64 -libc:glibc 2.27 NPTL 2.27 -rlimit: STACK 8192k, CORE 0k, NPROC 62817, NOFILE 4096, AS infinity, DATA infinity, FSIZE infinity -load average:2.41 1.83 1.49 - -/proc/meminfo: -MemTotal: 16267020 kB -MemFree: 183764 kB -MemAvailable: 140264 kB -Buffers: 5496 kB -Cached: 537944 kB -SwapCached: 8428 kB -Active: 14003164 kB -Inactive: 1476108 kB -Active(anon): 13934972 kB -Inactive(anon): 1405292 kB -Active(file): 68192 kB -Inactive(file): 70816 kB -Unevictable: 2204 kB -Mlocked: 2204 kB -SwapTotal: 999420 kB -SwapFree: 0 kB -Dirty: 1664 kB -Writeback: 0 kB -AnonPages: 14930136 kB -Mapped: 258372 kB -Shmem: 404388 kB -Slab: 330868 kB -SReclaimable: 120436 kB -SUnreclaim: 210432 kB -KernelStack: 28240 kB -PageTables: 115204 kB -NFS_Unstable: 0 kB -Bounce: 0 kB -WritebackTmp: 0 kB -CommitLimit: 9132928 kB -Committed_AS: 25974700 kB -VmallocTotal: 34359738367 kB -VmallocUsed: 0 kB -VmallocChunk: 0 kB -HardwareCorrupted: 0 kB -AnonHugePages: 0 kB -ShmemHugePages: 0 kB -ShmemPmdMapped: 0 kB -CmaTotal: 0 kB -CmaFree: 0 kB -HugePages_Total: 0 -HugePages_Free: 0 -HugePages_Rsvd: 0 -HugePages_Surp: 0 -Hugepagesize: 2048 kB -DirectMap4k: 879704 kB -DirectMap2M: 15740928 kB -DirectMap1G: 0 kB - - -/proc/sys/kernel/threads-max (system-wide limit on the number of threads): -125635 - - -/proc/sys/vm/max_map_count (maximum number of memory map areas a process may have): -65530 - - -/proc/sys/kernel/pid_max (system-wide limit on number of process identifiers): -32768 - - -container (cgroup) information: -container_type: cgroupv1 -cpu_cpuset_cpus: 0-11 -cpu_memory_nodes: 0 -active_processor_count: 12 -cpu_quota: -1 -cpu_period: 100000 -cpu_shares: -1 -memory_limit_in_bytes: -1 -memory_and_swap_limit_in_bytes: -2 -memory_soft_limit_in_bytes: -1 -memory_usage_in_bytes: 15768141824 -memory_max_usage_in_bytes: 16185810944 - - -CPU:total 12 (initial active 12) (6 cores per cpu, 2 threads per core) family 6 model 158 stepping 10, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, avx2, aes, clmul, erms, 3dnowpref, lzcnt, ht, tsc, tscinvbit, bmi1, bmi2, adx, fma -CPU Model and flags from /proc/cpuinfo: -model name : Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp flush_l1d - -Memory: 4k page, physical 16267020k(183764k free), swap 999420k(0k free) - -vm_info: OpenJDK 64-Bit Server VM (11.0.1+13) for linux-amd64 JRE (11.0.1+13), built on Oct 6 2018 05:14:05 by "mach5one" with gcc 7.3.0 - -END. diff --git a/modAionImpl/src/module-info.java b/modAionImpl/src/module-info.java index a82b515c41..ad386bb2a0 100644 --- a/modAionImpl/src/module-info.java +++ b/modAionImpl/src/module-info.java @@ -2,7 +2,7 @@ uses org.aion.evtmgr.EventMgrModule; uses org.aion.txpool.TxPoolModule; - requires aion.base; + requires aion.util; requires aion.mcf; requires aion.log; requires aion.p2p; diff --git a/modAionImpl/src/org/aion/equihash/Solution.java b/modAionImpl/src/org/aion/equihash/AionPowSolution.java similarity index 78% rename from modAionImpl/src/org/aion/equihash/Solution.java rename to modAionImpl/src/org/aion/equihash/AionPowSolution.java index 60e0574a3a..ddfe162c7f 100644 --- a/modAionImpl/src/org/aion/equihash/Solution.java +++ b/modAionImpl/src/org/aion/equihash/AionPowSolution.java @@ -1,6 +1,6 @@ package org.aion.equihash; -import org.aion.base.type.ISolution; +import org.aion.interfaces.block.Solution; import org.aion.zero.types.IAionBlock; /** @@ -9,13 +9,13 @@ * * @author Ross Kitsis (ross@nuco.io) */ -public class Solution implements ISolution { +public class AionPowSolution implements Solution { private final IAionBlock block; private final byte[] nonce; private final byte[] solution; - public Solution(IAionBlock block, byte[] nonce, byte[] solution) { + public AionPowSolution(IAionBlock block, byte[] nonce, byte[] solution) { this.block = block; this.nonce = nonce; diff --git a/modAionImpl/src/org/aion/equihash/EquiUtils.java b/modAionImpl/src/org/aion/equihash/EquiUtils.java index 170c5de2b5..3462d70a30 100644 --- a/modAionImpl/src/org/aion/equihash/EquiUtils.java +++ b/modAionImpl/src/org/aion/equihash/EquiUtils.java @@ -1,7 +1,8 @@ package org.aion.equihash; -import static org.aion.base.util.ByteUtil.bytesToInts; -import static org.aion.base.util.ByteUtil.intsToBytes; + +import static org.aion.util.bytes.ByteUtil.bytesToInts; +import static org.aion.util.bytes.ByteUtil.intsToBytes; /** * This package contains utility functions commonly called across multiple equihash classes. diff --git a/modAionImpl/src/org/aion/equihash/EquiValidator.java b/modAionImpl/src/org/aion/equihash/EquiValidator.java index 25df6e8bf7..52b8e8b017 100644 --- a/modAionImpl/src/org/aion/equihash/EquiValidator.java +++ b/modAionImpl/src/org/aion/equihash/EquiValidator.java @@ -1,8 +1,8 @@ package org.aion.equihash; -import static org.aion.base.util.ByteUtil.bytesToInts; -import static org.aion.base.util.ByteUtil.intToBytesLE; -import static org.aion.base.util.ByteUtil.merge; +import static org.aion.util.bytes.ByteUtil.bytesToInts; +import static org.aion.util.bytes.ByteUtil.intToBytesLE; +import static org.aion.util.bytes.ByteUtil.merge; import java.util.Arrays; import org.aion.crypto.hash.Blake2b; diff --git a/modAionImpl/src/org/aion/equihash/Equihash.java b/modAionImpl/src/org/aion/equihash/Equihash.java index f6014a7dcc..9a2a38c86e 100644 --- a/modAionImpl/src/org/aion/equihash/Equihash.java +++ b/modAionImpl/src/org/aion/equihash/Equihash.java @@ -1,15 +1,17 @@ package org.aion.equihash; -import static org.aion.base.util.ByteUtil.merge; -import static org.aion.base.util.ByteUtil.toLEByteArray; -import static org.aion.base.util.Hex.toHexString; + +import static org.aion.util.bytes.ByteUtil.merge; +import static org.aion.util.bytes.ByteUtil.toLEByteArray; +import static org.aion.util.conversions.Hex.toHexString; import java.math.BigInteger; import java.util.concurrent.atomic.AtomicLong; -import org.aion.base.util.NativeLoader; import org.aion.crypto.HashUtil; +import org.aion.interfaces.block.Solution; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; +import org.aion.util.file.NativeLoader; import org.aion.zero.types.A0BlockHeader; import org.aion.zero.types.IAionBlock; import org.slf4j.Logger; @@ -75,7 +77,7 @@ public int[][] getSolutionsForNonce(byte[] header, byte[] nonce) { /* * Mine for a single nonce */ - public Solution mine(IAionBlock block, byte[] nonce) { + public AionPowSolution mine(IAionBlock block, byte[] nonce) { A0BlockHeader updateHeader = new A0BlockHeader(block.getHeader()); @@ -109,7 +111,7 @@ public Solution mine(IAionBlock block, byte[] nonce) { // Found a valid solution if (isValidBlock(validationBytes, target)) { - return new Solution(block, nonce, minimal); + return new AionPowSolution(block, nonce, minimal); } } diff --git a/modAionImpl/src/org/aion/equihash/EquihashMiner.java b/modAionImpl/src/org/aion/equihash/EquihashMiner.java index dd17f65507..54f11a0060 100644 --- a/modAionImpl/src/org/aion/equihash/EquihashMiner.java +++ b/modAionImpl/src/org/aion/equihash/EquihashMiner.java @@ -1,6 +1,7 @@ package org.aion.equihash; -import static org.aion.base.util.Hex.toHexString; + +import static org.aion.util.conversions.Hex.toHexString; import java.util.ArrayList; import java.util.Collections; @@ -12,7 +13,6 @@ import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; -import org.aion.base.util.MAF; import org.aion.evtmgr.IEvent; import org.aion.evtmgr.IEventMgr; import org.aion.evtmgr.IHandler; @@ -20,7 +20,9 @@ import org.aion.evtmgr.impl.es.EventExecuteService; import org.aion.evtmgr.impl.evt.EventConsensus; import org.aion.evtmgr.impl.evt.EventMiner; +import org.aion.interfaces.block.Solution; import org.aion.mcf.mine.AbstractMineRunner; +import org.aion.util.others.MAF; import org.aion.zero.impl.blockchain.AionImpl; import org.aion.zero.impl.blockchain.IAionChain; import org.aion.zero.impl.config.CfgAion; diff --git a/modAionImpl/src/org/aion/equihash/FullStepRow.java b/modAionImpl/src/org/aion/equihash/FullStepRow.java index 2048151603..e0c253001e 100644 --- a/modAionImpl/src/org/aion/equihash/FullStepRow.java +++ b/modAionImpl/src/org/aion/equihash/FullStepRow.java @@ -1,6 +1,6 @@ package org.aion.equihash; -import static org.aion.base.util.ByteUtil.intToBytes; +import static org.aion.util.bytes.ByteUtil.intToBytes; class FullStepRow extends StepRow { diff --git a/modAionImpl/src/org/aion/equihash/OptimizedEquiValidator.java b/modAionImpl/src/org/aion/equihash/OptimizedEquiValidator.java index bcfe85f47f..a9f8560e0a 100644 --- a/modAionImpl/src/org/aion/equihash/OptimizedEquiValidator.java +++ b/modAionImpl/src/org/aion/equihash/OptimizedEquiValidator.java @@ -1,7 +1,7 @@ package org.aion.equihash; -import static org.aion.base.util.ByteUtil.intToBytesLE; -import static org.aion.base.util.ByteUtil.merge; +import static org.aion.util.bytes.ByteUtil.intToBytesLE; +import static org.aion.util.bytes.ByteUtil.merge; import java.util.HashSet; import java.util.Set; diff --git a/modAionImpl/src/org/aion/net/Peer.java b/modAionImpl/src/org/aion/net/Peer.java index 56dde2823a..61d539e146 100644 --- a/modAionImpl/src/org/aion/net/Peer.java +++ b/modAionImpl/src/org/aion/net/Peer.java @@ -4,7 +4,7 @@ import java.util.Set; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; /** * Peer is a class intended to represent application specific information about a network node, diff --git a/modAionImpl/src/org/aion/utils/NativeLibrary.java b/modAionImpl/src/org/aion/utils/NativeLibrary.java index 35899d56f6..da6d13297a 100644 --- a/modAionImpl/src/org/aion/utils/NativeLibrary.java +++ b/modAionImpl/src/org/aion/utils/NativeLibrary.java @@ -2,7 +2,7 @@ import java.util.ArrayList; import java.util.List; -import org.aion.base.util.NativeLoader; +import org.aion.util.file.NativeLoader; public enum NativeLibrary { COMMON("common"), diff --git a/modAionImpl/src/org/aion/zero/impl/A0BCConfig.java b/modAionImpl/src/org/aion/zero/impl/A0BCConfig.java index 190b15ac9d..b23bda6799 100644 --- a/modAionImpl/src/org/aion/zero/impl/A0BCConfig.java +++ b/modAionImpl/src/org/aion/zero/impl/A0BCConfig.java @@ -1,6 +1,6 @@ package org.aion.zero.impl; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; import org.aion.zero.impl.core.energy.AbstractEnergyStrategyLimit; public interface A0BCConfig { diff --git a/modAionImpl/src/org/aion/zero/impl/AionBlockLoader.java b/modAionImpl/src/org/aion/zero/impl/AionBlockLoader.java index 650445d52b..ef4d66ee69 100644 --- a/modAionImpl/src/org/aion/zero/impl/AionBlockLoader.java +++ b/modAionImpl/src/org/aion/zero/impl/AionBlockLoader.java @@ -3,7 +3,6 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; -import org.aion.base.util.ExecutorPipeline; import org.aion.log.LogEnum; import org.aion.mcf.core.ImportResult; import org.aion.zero.impl.types.AionBlock; diff --git a/modAionImpl/src/org/aion/zero/impl/AionBlockchainImpl.java b/modAionImpl/src/org/aion/zero/impl/AionBlockchainImpl.java index d7fbbf6019..a997a36741 100644 --- a/modAionImpl/src/org/aion/zero/impl/AionBlockchainImpl.java +++ b/modAionImpl/src/org/aion/zero/impl/AionBlockchainImpl.java @@ -1,16 +1,16 @@ package org.aion.zero.impl; -import static java.lang.Math.max; +import static java.lang.Long.max; import static java.lang.Runtime.getRuntime; import static java.math.BigInteger.ZERO; import static java.util.Collections.emptyList; -import static org.aion.base.util.BIUtil.isMoreThan; -import static org.aion.base.util.Hex.toHexString; import static org.aion.mcf.core.ImportResult.EXIST; import static org.aion.mcf.core.ImportResult.IMPORTED_BEST; import static org.aion.mcf.core.ImportResult.IMPORTED_NOT_BEST; import static org.aion.mcf.core.ImportResult.INVALID_BLOCK; import static org.aion.mcf.core.ImportResult.NO_PARENT; +import static org.aion.util.biginteger.BIUtil.isMoreThan; +import static org.aion.util.conversions.Hex.toHexString; import java.math.BigInteger; import java.util.ArrayDeque; @@ -22,24 +22,21 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.Stack; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; -import org.aion.base.db.IRepository; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.base.type.Hash256; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.Hex; import org.aion.crypto.HashUtil; import org.aion.equihash.EquihashMiner; import org.aion.evtmgr.IEvent; import org.aion.evtmgr.IEventMgr; import org.aion.evtmgr.impl.evt.EventBlock; +import org.aion.interfaces.db.Repository; +import org.aion.interfaces.db.RepositoryCache; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; +import org.aion.mcf.core.FastImportResult; import org.aion.mcf.core.ImportResult; import org.aion.mcf.db.IBlockStorePow; import org.aion.mcf.db.TransactionStore; @@ -47,16 +44,24 @@ import org.aion.mcf.trie.Trie; import org.aion.mcf.trie.TrieImpl; import org.aion.mcf.trie.TrieNodeResult; -import org.aion.mcf.types.BlockIdentifier; +import org.aion.mcf.tx.TransactionTypes; +import org.aion.mcf.types.BlockIdentifierImpl; import org.aion.mcf.valid.BlockHeaderValidator; import org.aion.mcf.valid.GrandParentBlockHeaderValidator; import org.aion.mcf.valid.ParentBlockHeaderValidator; +import org.aion.mcf.valid.TransactionTypeRule; import org.aion.mcf.vm.types.Bloom; import org.aion.rlp.RLP; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; +import org.aion.types.Hash256; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.conversions.Hex; import org.aion.vm.BulkExecutor; import org.aion.vm.ExecutionBatch; import org.aion.vm.PostExecutionWork; -import org.aion.vm.api.interfaces.Address; +import org.aion.vm.api.interfaces.IBloomFilter; +import org.aion.vm.exception.VMException; import org.aion.zero.exceptions.HeaderStructureException; import org.aion.zero.impl.blockchain.ChainConfiguration; import org.aion.zero.impl.config.CfgAion; @@ -108,7 +113,7 @@ public class AionBlockchainImpl implements IAionBlockchain { private long exitOn = Long.MAX_VALUE; private AionRepositoryImpl repository; - private IRepositoryCache track; + private RepositoryCache track; private TransactionStore transactionStore; private AionBlock bestBlock; @@ -132,8 +137,8 @@ public class AionBlockchainImpl implements IAionBlockchain { private final GrandParentBlockHeaderValidator grandParentBlockHeaderValidator; private final ParentBlockHeaderValidator parentHeaderValidator; private final BlockHeaderValidator blockHeaderValidator; - private AtomicReference bestKnownBlock = - new AtomicReference(); + private AtomicReference bestKnownBlock = + new AtomicReference(); private boolean fork = false; @@ -180,7 +185,7 @@ public boolean getExitOnBlockConflict() { @Override public Address getMinerCoinbase() { - return AionAddress.wrap(cfgAion.getConsensus().getMinerAddress()); + return Address.wrap(cfgAion.getConsensus().getMinerAddress()); } // TODO: hook up to configuration file @@ -199,7 +204,13 @@ public AbstractEnergyStrategyLimit getEnergyLimitStrategy() { @Override public boolean isAvmEnabled() { - return cfgAion.getVm().isAvmEnabled(); + // TODO: temporarily hack the TransactionTypeRule by the network name. Once avm + // ready for the production, this check should be removed. + if (cfgAion.getNetwork().equals("avmtestnet")) { + TransactionTypeRule.allowAVMContractDeployment(); + } + + return true; } }; } @@ -232,8 +243,7 @@ protected AionBlockchainImpl( this.transactionStore = this.repository.getTransactionStore(); this.minerCoinbase = this.config.getMinerCoinbase(); - - if (minerCoinbase.isEmptyAddress()) { + if (minerCoinbase == null) { LOG.warn("No miner Coinbase!"); } @@ -319,6 +329,11 @@ public AionBlock getBlockByNumber(long blockNr) { return getBlockStore().getChainBlockByNumber(blockNr); } + @Override + public List getBlocksByRange(long first, long last) { + return getBlockStore().getBlocksByRange(first, last); + } + @Override /* NOTE: only returns receipts from the main chain */ @@ -555,6 +570,89 @@ public boolean isPruneRestricted(long blockNumber) { return blockNumber < bestBlockNumber.get() - repository.getPruneBlockCount() + 1; } + /** + * Import block without validity checks and creating the state. Cannot be used for storing the + * pivot which will not have a parent present in the database. + * + * @param block the block to be imported + * @return a result describing the status of the attempted import + */ + public synchronized FastImportResult tryFastImport(final AionBlock block) { + if (block == null) { + if (LOG.isDebugEnabled()) { + LOG.debug("Fast sync import attempted with null block or header."); + } + return FastImportResult.INVALID_BLOCK; + } + if (block.getTimestamp() + > (System.currentTimeMillis() / THOUSAND_MS + + this.chainConfiguration.getConstants().getClockDriftBufferTime())) { + if (LOG.isDebugEnabled()) { + LOG.debug( + "Block {} invalid due to timestamp {}.", + block.getShortHash(), + block.getTimestamp()); + } + return FastImportResult.INVALID_BLOCK; + } + + // check that the block is not already known + AionBlock known = getBlockStore().getBlockByHash(block.getHash()); + if (known != null && known.getNumber() == block.getNumber()) { + return FastImportResult.KNOWN; + } + + // a child must be present to import the parent + AionBlock child = getBlockStore().getChainBlockByNumber(block.getNumber() + 1); + if (child == null || !Arrays.equals(child.getParentHash(), block.getHash())) { + return FastImportResult.NO_CHILD; + } else { + // the total difficulty will be updated after the chain is complete + getBlockStore().saveBlock(block, ZERO, true); + + if (LOG.isDebugEnabled()) { + LOG.debug( + "Fast sync block saved: number: {}, hash: {}, child: {}", + block.getNumber(), + block.getShortHash(), + child.getShortHash()); + } + return FastImportResult.IMPORTED; + } + } + + /** + * Walks though the ancestor blocks starting with the given hash to determine if there is an + * ancestor missing from storage. Returns the ancestor's hash if one is found missing or {@code + * null} when the history is complete, i.e. no missing ancestors exist. + * + * @param block the first block to be checked if present in the repository + * @return the ancestor's hash and height if one is found missing or {@code null} when the + * history is complete + * @throws NullPointerException when given a null block as input + */ + public Pair findMissingAncestor(AionBlock block) { + Objects.requireNonNull(block); + + // initialize with given parameter + byte[] currentHash = block.getHash(); + long currentNumber = block.getNumber(); + + AionBlock known = getBlockStore().getBlockByHash(currentHash); + + while (known != null && known.getNumber() > 0) { + currentHash = known.getParentHash(); + currentNumber--; + known = getBlockStore().getBlockByHash(currentHash); + } + + if (known == null) { + return Pair.of(ByteArrayWrapper.wrap(currentHash), currentNumber); + } else { + return null; + } + } + public synchronized ImportResult tryToConnect(final AionBlock block) { return tryToConnectInternal(block, System.currentTimeMillis() / THOUSAND_MS); } @@ -645,14 +743,15 @@ && getBlockStore().isBlockExist(block.getHash())) { if (ret.isSuccessful()) { if (this.evtMgr != null) { + List evts = new ArrayList<>(); IEvent evtOnBlock = new EventBlock(EventBlock.CALLBACK.ONBLOCK0); evtOnBlock.setFuncArgs(Collections.singletonList(summary)); - this.evtMgr.newEvent(evtOnBlock); + evts.add(evtOnBlock); IEvent evtTrace = new EventBlock(EventBlock.CALLBACK.ONTRACE0); String str = String.format("Block chain size: [ %d ]", this.getSizeInternal()); evtTrace.setFuncArgs(Collections.singletonList(str)); - this.evtMgr.newEvent(evtTrace); + evts.add(evtTrace); if (ret == IMPORTED_BEST) { if (LOG.isTraceEnabled()) { @@ -660,23 +759,23 @@ && getBlockStore().isBlockExist(block.getHash())) { } IEvent evtOnBest = new EventBlock(EventBlock.CALLBACK.ONBEST0); evtOnBest.setFuncArgs(Arrays.asList(block, summary.getReceipts())); - this.evtMgr.newEvent(evtOnBest); + evts.add(evtOnBest); } + + this.evtMgr.newEvents(evts); } } if (ret == IMPORTED_BEST) { if (TX_LOG.isDebugEnabled()) { - if (summary != null) { - for (AionTxReceipt receipt : summary.getReceipts()) { - if (receipt != null) { - byte[] transactionHash = receipt.getTransaction().getTransactionHash(); - TX_LOG.debug( - "Transaction: " - + Hex.toHexString(transactionHash) - + " was sealed into block #" - + block.getNumber()); - } + for (AionTxReceipt receipt : summary.getReceipts()) { + if (receipt != null) { + byte[] transactionHash = receipt.getTransaction().getTransactionHash(); + TX_LOG.debug( + "Transaction: " + + Hex.toHexString(transactionHash) + + " was sealed into block #" + + block.getNumber()); } } } @@ -909,6 +1008,20 @@ public AionBlockSummary add(AionBlock block, boolean rebuild) { // update corresponding account with the new balance track.flush(); + // save contract creation data to index database + for (AionTxReceipt receipt : receipts) { + AionTransaction tx = receipt.getTransaction(); + if (tx.isContractCreationTransaction() && receipt.isSuccessful()) { + repository.saveIndexedContractInformation( + tx.getContractAddress(), + block.getNumber(), + TransactionTypeRule.isValidAVMContractDeployment(tx.getTargetVM()) + ? TransactionTypes.AVM_CREATE_CODE + : TransactionTypes.FVM_CREATE_CODE, + true); + } + } + if (rebuild) { for (int i = 0; i < receipts.size(); i++) { transactionStore.putToBatch(new AionTxInfo(receipts.get(i), block.getHash(), i)); @@ -946,26 +1059,23 @@ private boolean needFlushByMemory(double maxMemoryPercents) { } private static byte[] calcReceiptsTrie(List receipts) { - Trie receiptsTrie = new TrieImpl(null); - if (receipts == null || receipts.isEmpty()) { return HashUtil.EMPTY_TRIE_HASH; } + Trie receiptsTrie = new TrieImpl(null); for (int i = 0; i < receipts.size(); i++) { receiptsTrie.update(RLP.encodeInt(i), receipts.get(i).getReceiptTrieEncoded()); } return receiptsTrie.getRootHash(); } - private byte[] calcLogBloom(List receipts) { - - Bloom retBloomFilter = new Bloom(); - + private static byte[] calcLogBloom(List receipts) { if (receipts == null || receipts.isEmpty()) { - return retBloomFilter.getBloomFilterBytes(); + return new byte[IBloomFilter.SIZE]; } + Bloom retBloomFilter = new Bloom(); for (AionTxReceipt receipt : receipts) { retBloomFilter.or(receipt.getBloomFilter()); } @@ -1034,7 +1144,7 @@ private boolean isValid(AionBlock block) { } if (txs != null && !txs.isEmpty()) { - IRepository parentRepo = repository; + Repository parentRepo = repository; if (!Arrays.equals(bestBlock.getHash(), block.getParentHash())) { parentRepo = repository.getSnapshotTo( @@ -1117,10 +1227,7 @@ private AionBlockSummary processBlock(AionBlock block) { return applyBlock(block); } else { return new AionBlockSummary( - block, - new HashMap(), - new ArrayList(), - new ArrayList()); + block, new HashMap<>(), new ArrayList<>(), new ArrayList<>()); } } @@ -1138,28 +1245,37 @@ private RetValidPreBlock generatePreBlock(IAionBlock block) { List summaries = new ArrayList<>(); List transactions = new ArrayList<>(); - ExecutionBatch batch = new ExecutionBatch(block, block.getTransactionsList()); - BulkExecutor executor = - new BulkExecutor( - batch, - repository, - track, - false, - true, - block.getNrgLimit(), - LOGGER_VM, - getPostExecutionWorkForGeneratePreBlock()); - List executionSummaries = executor.execute(); - - for (AionTxExecSummary summary : executionSummaries) { - if (!summary.isRejected()) { - transactions.add(summary.getTransaction()); - receipts.add(summary.getReceipt()); - summaries.add(summary); + if (!block.getTransactionsList().isEmpty()) { + ExecutionBatch batch = new ExecutionBatch(block, block.getTransactionsList()); + BulkExecutor executor = + new BulkExecutor( + batch, + repository, + track, + false, + true, + block.getNrgLimit(), + LOGGER_VM, + getPostExecutionWorkForGeneratePreBlock()); + + List executionSummaries = null; + try { + executionSummaries = executor.execute(); + } catch (VMException e) { + LOG.error("Shutdown due to a VM fatal error.", e); + System.exit(-1); + } + + for (AionTxExecSummary summary : executionSummaries) { + if (!summary.isRejected()) { + transactions.add(summary.getTransaction()); + receipts.add(summary.getReceipt()); + summaries.add(summary); + } } } - Map rewards = addReward(block, summaries); + Map rewards = addReward(block); track.flush(); @@ -1202,24 +1318,33 @@ private AionBlockSummary applyBlock(IAionBlock block) { List receipts = new ArrayList<>(); List summaries = new ArrayList<>(); - ExecutionBatch batch = new ExecutionBatch(block, block.getTransactionsList()); - BulkExecutor executor = - new BulkExecutor( - batch, - repository, - track, - false, - true, - block.getNrgLimit(), - LOGGER_VM, - getPostExecutionWorkForApplyBlock()); - List executionSummaries = executor.execute(); - - for (AionTxExecSummary summary : executionSummaries) { - receipts.add(summary.getReceipt()); - summaries.add(summary); - } - Map rewards = addReward(block, summaries); + if (!block.getTransactionsList().isEmpty()) { + ExecutionBatch batch = new ExecutionBatch(block, block.getTransactionsList()); + BulkExecutor executor = + new BulkExecutor( + batch, + repository, + track, + false, + true, + block.getNrgLimit(), + LOGGER_VM, + getPostExecutionWorkForApplyBlock()); + + List executionSummaries = null; + try { + executionSummaries = executor.execute(); + } catch (VMException e) { + LOG.error("Shutdown due to a VM fatal error.", e); + System.exit(-1); + } + + for (AionTxExecSummary summary : executionSummaries) { + receipts.add(summary.getReceipt()); + summaries.add(summary); + } + } + Map rewards = addReward(block); long totalTime = System.nanoTime() - saveTime; chainStats.addBlockExecTime(totalTime); @@ -1252,8 +1377,7 @@ private static PostExecutionWork getPostExecutionWorkForApplyBlock() { * * @param block object containing the header and uncles */ - private Map addReward( - IAionBlock block, List summaries) { + private Map addReward(IAionBlock block) { Map rewards = new HashMap<>(); BigInteger minerReward = @@ -1297,14 +1421,13 @@ public synchronized void storeBlock(AionBlock block, List receipt repository.commitBlock(block.getHeader()); - if (LOG.isDebugEnabled()) + if (LOG.isDebugEnabled()) { LOG.debug( "Block saved: number: {}, hash: {}, TD: {}", block.getNumber(), block.getShortHash(), totalDifficulty); - if (LOG.isDebugEnabled()) { LOG.debug("block added to the blockChain: index: [{}]", block.getNumber()); } @@ -1525,7 +1648,8 @@ private byte[] getStartHash(long blockNumber, int qty) { // * @return {@link A0BlockHeader}'s list or empty list if none found // */ // @Override - // public List getListOfHeadersStartFrom(BlockIdentifier identifier, int skip, + // public List getListOfHeadersStartFrom(BlockIdentifierImpl identifier, int + // skip, // int limit, // boolean reverse) { // @@ -1696,7 +1820,7 @@ private void updateBestKnownBlock(AionBlock block) { private void updateBestKnownBlock(A0BlockHeader header) { if (bestKnownBlock.get() == null || header.getNumber() > bestKnownBlock.get().getNumber()) { - bestKnownBlock.set(new BlockIdentifier(header.getHash(), header.getNumber())); + bestKnownBlock.set(new BlockIdentifierImpl(header.getHash(), header.getNumber())); } } @@ -1705,7 +1829,7 @@ public IEventMgr getEventMgr() { } @Override - public synchronized boolean recoverWorldState(IRepository repository, AionBlock block) { + public synchronized boolean recoverWorldState(Repository repository, AionBlock block) { if (block == null) { LOG.error("World state recovery attempted with null block."); return false; @@ -1788,7 +1912,7 @@ public synchronized boolean recoverWorldState(IRepository repository, AionBlock } @Override - public synchronized boolean recoverIndexEntry(IRepository repository, AionBlock block) { + public synchronized boolean recoverIndexEntry(Repository repository, AionBlock block) { if (block == null) { LOG.error("Index recovery attempted with null block."); return false; diff --git a/modAionImpl/src/org/aion/zero/impl/AionGenesis.java b/modAionImpl/src/org/aion/zero/impl/AionGenesis.java index 2748220be6..2e8948144b 100644 --- a/modAionImpl/src/org/aion/zero/impl/AionGenesis.java +++ b/modAionImpl/src/org/aion/zero/impl/AionGenesis.java @@ -4,18 +4,17 @@ import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.HashUtil; import org.aion.mcf.core.AccountState; import org.aion.mcf.trie.SecureTrie; import org.aion.mcf.trie.Trie; import org.aion.mcf.types.AbstractBlockHeader; -import org.aion.mcf.vm.types.DataWord; import org.aion.precompiled.ContractFactory; -import org.aion.vm.api.interfaces.Address; -import org.aion.zero.db.AionContractDetailsImpl; +import org.aion.util.bytes.ByteUtil; +import org.aion.zero.impl.db.AionContractDetailsImpl; import org.aion.zero.exceptions.HeaderStructureException; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.types.A0BlockHeader; @@ -49,7 +48,7 @@ public class AionGenesis extends AionBlock { * Corresponds to {@link AbstractBlockHeader#getCoinbase()} that mined the first block. For * fairness, the address is set to an address that is not ever to be used */ - protected static final Address GENESIS_COINBASE = AionAddress.ZERO_ADDRESS(); + protected static final Address GENESIS_COINBASE = Address.ZERO_ADDRESS(); /** * Corresponds to {@link AbstractBlockHeader#getLogsBloom()} indicates the logsBloom of the @@ -351,8 +350,8 @@ protected byte[] generateRootHash() { for (Map.Entry entry : this.networkBalance.entrySet()) { // we assume there are no deletions in the genesis networkBalanceStorage.put( - new DataWord(entry.getKey()).toWrapper(), - wrapValueForPut(new DataWord(entry.getValue()))); + new DataWordImpl(entry.getKey()).toWrapper(), + wrapValueForPut(new DataWordImpl(entry.getValue()))); } byte[] networkBalanceStorageHash = networkBalanceStorage.getStorageHash(); @@ -370,9 +369,9 @@ protected byte[] generateRootHash() { return worldTrie.getRootHash(); } - private static ByteArrayWrapper wrapValueForPut(DataWord value) { + private static ByteArrayWrapper wrapValueForPut(DataWordImpl value) { return (value.isZero()) - ? DataWord.ZERO.toWrapper() + ? DataWordImpl.ZERO.toWrapper() : new ByteArrayWrapper(value.getNoLeadZeroesData()); } diff --git a/modAionImpl/src/org/aion/zero/impl/AionHub.java b/modAionImpl/src/org/aion/zero/impl/AionHub.java index ad667833a4..8074119770 100644 --- a/modAionImpl/src/org/aion/zero/impl/AionHub.java +++ b/modAionImpl/src/org/aion/zero/impl/AionHub.java @@ -9,8 +9,7 @@ import java.util.Properties; import java.util.ServiceLoader; import java.util.concurrent.atomic.AtomicBoolean; -import org.aion.base.db.IRepository; -import org.aion.base.util.ByteUtil; +import org.aion.interfaces.db.Repository; import org.aion.evtmgr.EventMgrModule; import org.aion.evtmgr.IEvent; import org.aion.evtmgr.IEventMgr; @@ -24,6 +23,7 @@ import org.aion.p2p.Handler; import org.aion.p2p.IP2pMgr; import org.aion.p2p.impl1.P2pMgr; +import org.aion.util.bytes.ByteUtil; import org.aion.zero.impl.blockchain.AionPendingStateImpl; import org.aion.zero.impl.blockchain.ChainConfiguration; import org.aion.zero.impl.config.CfgAion; @@ -259,7 +259,7 @@ private void loadEventMgr(boolean forTest) { } } - public IRepository getRepository() { + public Repository getRepository() { return repository; } diff --git a/modAionImpl/src/org/aion/zero/impl/AionHubUtils.java b/modAionImpl/src/org/aion/zero/impl/AionHubUtils.java index 09bc4661dd..600f2390ef 100644 --- a/modAionImpl/src/org/aion/zero/impl/AionHubUtils.java +++ b/modAionImpl/src/org/aion/zero/impl/AionHubUtils.java @@ -2,11 +2,11 @@ import java.math.BigInteger; import java.util.Map; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.mcf.vm.types.DataWord; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.precompiled.ContractFactory; -import org.aion.vm.api.interfaces.Address; import org.aion.zero.impl.db.AionRepositoryImpl; /** {@link AionHub} functionality where a full instantiation of the class is not desirable. */ @@ -14,7 +14,7 @@ public class AionHubUtils { public static void buildGenesis(AionGenesis genesis, AionRepositoryImpl repository) { // initialization section for network balance contract - IRepositoryCache track = repository.startTracking(); + RepositoryCache track = repository.startTracking(); Address networkBalanceAddress = ContractFactory.getTotalCurrencyContractAddress(); track.createAccount(networkBalanceAddress); @@ -23,8 +23,8 @@ public static void buildGenesis(AionGenesis genesis, AionRepositoryImpl reposito // assumes only additions are performed in the genesis track.addStorageRow( networkBalanceAddress, - new DataWord(addr.getKey()).toWrapper(), - wrapValueForPut(new DataWord(addr.getValue()))); + new DataWordImpl(addr.getKey()).toWrapper(), + wrapValueForPut(new DataWordImpl(addr.getValue()))); } for (Address addr : genesis.getPremine().keySet()) { @@ -37,7 +37,7 @@ public static void buildGenesis(AionGenesis genesis, AionRepositoryImpl reposito repository.getBlockStore().saveBlock(genesis, genesis.getDifficultyBI(), true); } - private static ByteArrayWrapper wrapValueForPut(DataWord value) { + private static ByteArrayWrapper wrapValueForPut(DataWordImpl value) { return (value.isZero()) ? value.toWrapper() : new ByteArrayWrapper(value.getNoLeadZeroesData()); diff --git a/modAionBase/src/org/aion/base/util/ExecutorPipeline.java b/modAionImpl/src/org/aion/zero/impl/ExecutorPipeline.java similarity index 98% rename from modAionBase/src/org/aion/base/util/ExecutorPipeline.java rename to modAionImpl/src/org/aion/zero/impl/ExecutorPipeline.java index 399d18e3d8..043f0c9969 100644 --- a/modAionBase/src/org/aion/base/util/ExecutorPipeline.java +++ b/modAionImpl/src/org/aion/zero/impl/ExecutorPipeline.java @@ -1,4 +1,6 @@ -package org.aion.base.util; +package org.aion.zero.impl; + +import org.aion.interfaces.functional.Functional; import java.util.HashMap; import java.util.List; diff --git a/modAionImpl/src/org/aion/zero/impl/GenesisBlockLoader.java b/modAionImpl/src/org/aion/zero/impl/GenesisBlockLoader.java index f616912f1a..193021b00b 100644 --- a/modAionImpl/src/org/aion/zero/impl/GenesisBlockLoader.java +++ b/modAionImpl/src/org/aion/zero/impl/GenesisBlockLoader.java @@ -7,9 +7,9 @@ import java.io.InputStream; import java.math.BigInteger; import java.util.regex.Pattern; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; +import org.aion.types.Address; import org.aion.mcf.core.AccountState; +import org.aion.util.bytes.ByteUtil; import org.aion.zero.exceptions.HeaderStructureException; import org.json.JSONException; import org.json.JSONObject; @@ -50,7 +50,7 @@ public static AionGenesis loadJSON(String filePath) } if (mapper.has("coinbase")) { - genesisBuilder.withCoinbase(AionAddress.wrap(mapper.getString("coinbase"))); + genesisBuilder.withCoinbase(Address.wrap(mapper.getString("coinbase"))); } if (mapper.has("difficulty")) { @@ -130,7 +130,7 @@ public static AionGenesis loadJSON(String filePath) new BigInteger( accountAllocs.getJSONObject(key).getString("balance")); AccountState acctState = new AccountState(BigInteger.ZERO, balance); - genesisBuilder.addPreminedAccount(AionAddress.wrap(key), acctState); + genesisBuilder.addPreminedAccount(Address.wrap(key), acctState); } } diff --git a/modAionImpl/src/org/aion/zero/impl/StandaloneBlockchain.java b/modAionImpl/src/org/aion/zero/impl/StandaloneBlockchain.java index 57b93393e9..3106275501 100644 --- a/modAionImpl/src/org/aion/zero/impl/StandaloneBlockchain.java +++ b/modAionImpl/src/org/aion/zero/impl/StandaloneBlockchain.java @@ -8,13 +8,13 @@ import java.util.List; import java.util.Map; import java.util.Properties; -import org.aion.base.db.IContractDetails; -import org.aion.base.db.IPruneConfig; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.db.IRepositoryConfig; -import org.aion.base.type.AionAddress; -import org.aion.base.type.Hash256; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.db.ContractDetails; +import org.aion.interfaces.db.PruneConfig; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.interfaces.db.RepositoryConfig; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.crypto.HashUtil; @@ -24,9 +24,8 @@ import org.aion.mcf.core.AccountState; import org.aion.mcf.core.ImportResult; import org.aion.mcf.valid.BlockHeaderValidator; -import org.aion.mcf.vm.types.DataWord; import org.aion.precompiled.ContractFactory; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Hash256; import org.aion.zero.exceptions.HeaderStructureException; import org.aion.zero.impl.blockchain.ChainConfiguration; import org.aion.zero.impl.core.energy.AbstractEnergyStrategyLimit; @@ -51,20 +50,20 @@ public class StandaloneBlockchain extends AionBlockchainImpl { public AionGenesis genesis; - private static IRepositoryConfig repoConfig = - new IRepositoryConfig() { + private static RepositoryConfig repoConfig = + new RepositoryConfig() { @Override public String getDbPath() { return ""; } @Override - public IPruneConfig getPruneConfig() { + public PruneConfig getPruneConfig() { return new CfgPrune(false); } @Override - public IContractDetails contractDetailsImpl() { + public ContractDetails contractDetailsImpl() { return ContractDetailsAion.createForTesting(0, 1000000).getDetails(); } @@ -84,7 +83,7 @@ protected StandaloneBlockchain(final A0BCConfig config, final ChainConfiguration protected StandaloneBlockchain( final A0BCConfig config, final ChainConfiguration chainConfig, - IRepositoryConfig repoConfig) { + RepositoryConfig repoConfig) { super(config, AionRepositoryImpl.createForTesting(repoConfig), chainConfig); } @@ -123,7 +122,7 @@ public static class Builder { private List defaultKeys = new ArrayList<>(); private Map initialState = new HashMap<>(); - private IRepositoryConfig repoConfig; + private RepositoryConfig repoConfig; public static final int INITIAL_ACC_LEN = 10; public static final BigInteger DEFAULT_BALANCE = @@ -164,7 +163,7 @@ public Builder withDefaultAccounts(List defaultAccounts) { return this; } - public Builder withRepoConfig(IRepositoryConfig config) { + public Builder withRepoConfig(RepositoryConfig config) { this.repoConfig = config; return this; } @@ -193,20 +192,20 @@ public Builder withAccount(ByteArrayWrapper publicKey, AccountState accState) { return this; } - private IRepositoryConfig generateRepositoryConfig() { - return new IRepositoryConfig() { + private RepositoryConfig generateRepositoryConfig() { + return new RepositoryConfig() { @Override public String getDbPath() { return ""; } @Override - public IPruneConfig getPruneConfig() { + public PruneConfig getPruneConfig() { return new CfgPrune(false); } @Override - public IContractDetails contractDetailsImpl() { + public ContractDetails contractDetailsImpl() { return ContractDetailsAion.createForTesting(0, 1000000).getDetails(); } @@ -226,7 +225,7 @@ public Bundle build() { ? new A0BCConfig() { @Override public Address getCoinbase() { - return AionAddress.ZERO_ADDRESS(); + return Address.ZERO_ADDRESS(); } @Override @@ -241,7 +240,7 @@ public boolean getExitOnBlockConflict() { @Override public Address getMinerCoinbase() { - return AionAddress.ZERO_ADDRESS(); + return Address.ZERO_ADDRESS(); } @Override @@ -309,7 +308,7 @@ public boolean isAvmEnabled() { AionGenesis.Builder genesisBuilder = new AionGenesis.Builder(); for (Map.Entry acc : this.initialState.entrySet()) { - genesisBuilder.addPreminedAccount(AionAddress.wrap(acc.getKey()), acc.getValue()); + genesisBuilder.addPreminedAccount(Address.wrap(acc.getKey()), acc.getValue()); } AionGenesis genesis; @@ -320,15 +319,15 @@ public boolean isAvmEnabled() { } bc.genesis = genesis; - IRepositoryCache track = bc.getRepository().startTracking(); + RepositoryCache track = bc.getRepository().startTracking(); track.createAccount(ContractFactory.getTotalCurrencyContractAddress()); for (Map.Entry key : genesis.getNetworkBalances().entrySet()) { // assumes only additions can be made in the genesis track.addStorageRow( ContractFactory.getTotalCurrencyContractAddress(), - new DataWord(key.getKey()).toWrapper(), - new ByteArrayWrapper(new DataWord(key.getValue()).getNoLeadZeroesData())); + new DataWordImpl(key.getKey()).toWrapper(), + new ByteArrayWrapper(new DataWordImpl(key.getValue()).getNoLeadZeroesData())); } for (Address key : genesis.getPremine().keySet()) { diff --git a/modAionImpl/src/org/aion/zero/impl/SystemExitCodes.java b/modAionImpl/src/org/aion/zero/impl/SystemExitCodes.java new file mode 100644 index 0000000000..f77ea4d9c8 --- /dev/null +++ b/modAionImpl/src/org/aion/zero/impl/SystemExitCodes.java @@ -0,0 +1,8 @@ +package org.aion.zero.impl; + +/** Error coded to be used when calling {@link System#exit(int)} from the kernel. */ +public class SystemExitCodes { + + public static final int NORMAL = 0; + public static final int OUT_OF_DISK_SPACE = 1; +} diff --git a/modAionImpl/src/org/aion/zero/impl/Version.java b/modAionImpl/src/org/aion/zero/impl/Version.java index ba8c355ce7..4f958e00f9 100644 --- a/modAionImpl/src/org/aion/zero/impl/Version.java +++ b/modAionImpl/src/org/aion/zero/impl/Version.java @@ -1,7 +1,7 @@ package org.aion.zero.impl; public class Version { - public static final String KERNEL_VERSION = "0.3.3"; + public static final String KERNEL_VERSION = "0.3.4"; public static final String REPO_VERSION = "0.1.0"; public static final boolean FORK = true; } diff --git a/modAionImpl/src/org/aion/zero/impl/blockchain/AionImpl.java b/modAionImpl/src/org/aion/zero/impl/blockchain/AionImpl.java index 48fb3230ec..f5cd7c1333 100644 --- a/modAionImpl/src/org/aion/zero/impl/blockchain/AionImpl.java +++ b/modAionImpl/src/org/aion/zero/impl/blockchain/AionImpl.java @@ -4,13 +4,10 @@ import java.util.Collections; import java.util.List; import java.util.Optional; -import org.aion.base.db.IRepository; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; import org.aion.crypto.ECKeyFac; import org.aion.equihash.EquihashMiner; +import org.aion.interfaces.db.Repository; +import org.aion.interfaces.db.RepositoryCache; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.aion.mcf.blockchain.IPendingStateInternal; @@ -18,10 +15,13 @@ import org.aion.mcf.core.AccountState; import org.aion.mcf.core.ImportResult; import org.aion.mcf.mine.IMineRunner; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; +import org.aion.util.bytes.ByteUtil; import org.aion.vm.BulkExecutor; import org.aion.vm.ExecutionBatch; import org.aion.vm.PostExecutionWork; -import org.aion.vm.api.interfaces.Address; +import org.aion.vm.exception.VMException; import org.aion.zero.impl.AionHub; import org.aion.zero.impl.config.CfgAion; import org.aion.zero.impl.tx.TxCollector; @@ -44,14 +44,6 @@ public class AionImpl implements IAionChain { private TxCollector collector; - private static class Holder { - static final AionImpl INSTANCE = new AionImpl(); - } - - public static AionImpl inst() { - return Holder.INSTANCE; - } - private AionImpl() { this.cfg = CfgAion.inst(); aionHub = new AionHub(); @@ -67,6 +59,18 @@ private AionImpl() { collector = new TxCollector(this.aionHub.getP2pMgr(), LOG_TX); } + public static AionImpl inst() { + return Holder.INSTANCE; + } + + /** + * There is no post-execution work to do for any calls in this class to do. In accordance with + * the specs, we return zero since we have no meaningful value to return here. + */ + private static PostExecutionWork getPostExecutionWork() { + return (r, c, s, t, b) -> 0; + } + @Override public IPowChain getBlockchain() { return aionHub.getBlockchain(); @@ -84,14 +88,13 @@ public synchronized ImportResult addNewMinedBlock(AionBlock block) { @Override public IMineRunner getBlockMiner() { - AionAddress minerCoinbase = AionAddress.wrap(this.cfg.getConsensus().getMinerAddress()); - - if (minerCoinbase.isEmptyAddress()) { + try { + Address.wrap(this.cfg.getConsensus().getMinerAddress()); + return EquihashMiner.inst(); + } catch (Exception e) { LOG_GEN.info("Miner address is not set"); return null; } - - return EquihashMiner.inst(); } @Override @@ -131,7 +134,7 @@ public long estimateTxNrg(AionTransaction tx, IAionBlock block) { tx.sign(ECKeyFac.inst().fromPrivate(new byte[64])); } - IRepositoryCache repository = + RepositoryCache repository = aionHub.getRepository().getSnapshotTo(block.getStateRoot()).startTracking(); try { @@ -146,6 +149,10 @@ public long estimateTxNrg(AionTransaction tx, IAionBlock block) { LOG_VM, getPostExecutionWork()); return executor.execute().get(0).getReceipt().getEnergyUsed(); + } catch (VMException e) { + LOG_GEN.error("Shutdown due to a VM fatal error.", e); + System.exit(-1); + return 0; } finally { repository.rollback(); } @@ -158,7 +165,7 @@ public AionTxReceipt callConstant(AionTransaction tx, IAionBlock block) { tx.sign(ECKeyFac.inst().fromPrivate(new byte[64])); } - IRepositoryCache repository = + RepositoryCache repository = aionHub.getRepository().getSnapshotTo(block.getStateRoot()).startTracking(); try { @@ -173,35 +180,29 @@ public AionTxReceipt callConstant(AionTransaction tx, IAionBlock block) { LOG_VM, getPostExecutionWork()); return executor.execute().get(0).getReceipt(); + } catch (VMException e) { + LOG_GEN.error("Shutdown due to a VM fatal error.", e); + System.exit(-1); + return null; } finally { repository.rollback(); } } - /** - * There is no post-execution work to do for any calls in this class to do. In accordance with - * the specs, we return zero since we have no meaningful value to return here. - */ - private static PostExecutionWork getPostExecutionWork() { - return (r, c, s, t, b) -> { - return 0; - }; - } - @Override - public IRepository getRepository() { + public Repository getRepository() { return aionHub.getRepository(); } @Override - public IRepository getPendingState() { + public Repository getPendingState() { return aionHub.getPendingState().getRepository(); } @Override - public IRepository getSnapshotTo(byte[] root) { - IRepository repository = aionHub.getRepository(); - IRepository snapshot = repository.getSnapshotTo(root); + public Repository getSnapshotTo(byte[] root) { + Repository repository = aionHub.getRepository(); + Repository snapshot = repository.getSnapshotTo(root); return snapshot; } @@ -252,31 +253,6 @@ public Optional getNetworkBestBlockNumber() { } } - /** - * Returns whether syncing is completed. Note that this implementation is more of a switch than - * a guarantee as the syncing system may kick back into action if the network falls behind. - * - * @return {@code true} if syncing is completed, {@code false} otherwise - */ - @Override - public boolean isSyncComplete() { - try { - long localBestBlockNumber = - this.getAionHub().getBlockchain().getBestBlock().getNumber(); - long networkBestBlockNumber = - this.getAionHub().getSyncMgr().getNetworkBestBlockNumber(); - // to prevent unecessary flopping, consider being within 5 blocks of - // head to be - // block propagation and not syncing. - // NOTE: in the future block propagation may not be tied in with - // syncing - return (localBestBlockNumber + 5) < networkBestBlockNumber; - } catch (Exception e) { - LOG_GEN.debug("query request failed", e); - return false; - } - } - @Override public Optional getInitialStartingBlockNumber() { try { @@ -357,4 +333,8 @@ public Optional getCode(Address address) { if (code == null) return Optional.empty(); return Optional.of(new ByteArrayWrapper(code)); } + + private static class Holder { + static final AionImpl INSTANCE = new AionImpl(); + } } diff --git a/modAionImpl/src/org/aion/zero/impl/blockchain/AionPendingStateImpl.java b/modAionImpl/src/org/aion/zero/impl/blockchain/AionPendingStateImpl.java index 7ff8707134..f28e23291d 100644 --- a/modAionImpl/src/org/aion/zero/impl/blockchain/AionPendingStateImpl.java +++ b/modAionImpl/src/org/aion/zero/impl/blockchain/AionPendingStateImpl.java @@ -21,11 +21,9 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.aion.base.Constant; -import org.aion.base.db.IRepository; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.Hex; +import org.aion.interfaces.block.Constant; +import org.aion.interfaces.db.Repository; +import org.aion.interfaces.db.RepositoryCache; import org.aion.evtmgr.IEvent; import org.aion.evtmgr.IEventMgr; import org.aion.evtmgr.IHandler; @@ -43,10 +41,13 @@ import org.aion.p2p.IP2pMgr; import org.aion.txpool.ITxPool; import org.aion.txpool.TxPoolModule; +import org.aion.types.Address; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.conversions.Hex; import org.aion.vm.BulkExecutor; import org.aion.vm.ExecutionBatch; import org.aion.vm.PostExecutionWork; -import org.aion.vm.api.interfaces.Address; +import org.aion.vm.exception.VMException; import org.aion.zero.impl.AionBlockchainImpl; import org.aion.zero.impl.config.CfgAion; import org.aion.zero.impl.core.IAionBlockchain; @@ -95,13 +96,13 @@ public TransactionSortedSet() { private TransactionStore transactionStore; - private IRepository repository; + private Repository repository; private ITxPool txPool; private IEventMgr evtMgr = null; - private IRepositoryCache pendingState; + private RepositoryCache pendingState; private AtomicReference best; @@ -401,7 +402,7 @@ private void regTxEvents() { } @Override - public synchronized IRepositoryCache getRepository() { + public synchronized RepositoryCache getRepository() { // Todo : no class use this method. return pendingState; } @@ -1073,7 +1074,13 @@ private AionTxExecSummary executeTx(AionTransaction tx, boolean inPool) { bestBlk.getNrgLimit(), LOGGER_VM, getPostExecutionWork()); - return txExe.execute().get(0); + try { + return txExe.execute().get(0); + } catch (VMException e) { + LOGGER_VM.error("Shutdown due to a VM fatal error.", e); + System.exit(-1); + return null; + } } /** diff --git a/modAionImpl/src/org/aion/zero/impl/blockchain/ChainConfiguration.java b/modAionImpl/src/org/aion/zero/impl/blockchain/ChainConfiguration.java index bad21ca04a..c0a2de4678 100644 --- a/modAionImpl/src/org/aion/zero/impl/blockchain/ChainConfiguration.java +++ b/modAionImpl/src/org/aion/zero/impl/blockchain/ChainConfiguration.java @@ -2,6 +2,7 @@ import java.math.BigInteger; import java.util.Arrays; +import java.util.Collections; import org.aion.equihash.OptimizedEquiValidator; import org.aion.mcf.blockchain.IBlockConstants; import org.aion.mcf.blockchain.IChainCfg; @@ -13,11 +14,12 @@ import org.aion.mcf.valid.GrandParentBlockHeaderValidator; import org.aion.mcf.valid.ParentBlockHeaderValidator; import org.aion.mcf.valid.TimeStampRule; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; import org.aion.zero.api.BlockConstants; import org.aion.zero.impl.config.CfgAion; import org.aion.zero.impl.core.DiffCalc; import org.aion.zero.impl.core.RewardsCalculator; +import org.aion.zero.impl.types.AionBlock; import org.aion.zero.impl.valid.AionDifficultyRule; import org.aion.zero.impl.valid.AionExtraDataRule; import org.aion.zero.impl.valid.AionHeaderVersionRule; @@ -27,7 +29,6 @@ import org.aion.zero.impl.valid.EquihashSolutionRule; import org.aion.zero.types.A0BlockHeader; import org.aion.zero.types.AionTransaction; -import org.aion.zero.types.IAionBlock; /** * Chain configuration handles the default parameters on a particular chain. Also handles the @@ -36,7 +37,7 @@ * * @author yao */ -public class ChainConfiguration implements IChainCfg { +public class ChainConfiguration implements IChainCfg { protected BlockConstants constants; protected IMiner miner; @@ -123,6 +124,7 @@ public ParentBlockHeaderValidator createParentHeaderValidator() { } public GrandParentBlockHeaderValidator createGrandParentHeaderValidator() { - return new GrandParentBlockHeaderValidator<>(Arrays.asList(new AionDifficultyRule(this))); + return new GrandParentBlockHeaderValidator<>( + Collections.singletonList(new AionDifficultyRule(this))); } } diff --git a/modAionImpl/src/org/aion/zero/impl/blockchain/IAionChain.java b/modAionImpl/src/org/aion/zero/impl/blockchain/IAionChain.java index 6602c356e3..354084c2d2 100644 --- a/modAionImpl/src/org/aion/zero/impl/blockchain/IAionChain.java +++ b/modAionImpl/src/org/aion/zero/impl/blockchain/IAionChain.java @@ -2,10 +2,10 @@ import java.math.BigInteger; import java.util.List; -import org.aion.base.db.IRepository; +import org.aion.interfaces.db.Repository; import org.aion.mcf.blockchain.IChainInstancePOW; import org.aion.mcf.blockchain.IPowChain; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; import org.aion.zero.impl.AionHub; import org.aion.zero.impl.query.QueryInterface; import org.aion.zero.impl.types.AionBlock; @@ -27,11 +27,11 @@ public interface IAionChain extends IChainInstancePOW, QueryInterface { AionTxReceipt callConstant(AionTransaction tx, IAionBlock block); - IRepository getRepository(); + Repository getRepository(); - IRepository getPendingState(); + Repository getPendingState(); - IRepository getSnapshotTo(byte[] root); + Repository getSnapshotTo(byte[] root); List getWireTransactions(); diff --git a/modAionImpl/src/org/aion/zero/impl/blockchain/PendingTxCache.java b/modAionImpl/src/org/aion/zero/impl/blockchain/PendingTxCache.java index 7681dc5cd3..33ec9a8fff 100644 --- a/modAionImpl/src/org/aion/zero/impl/blockchain/PendingTxCache.java +++ b/modAionImpl/src/org/aion/zero/impl/blockchain/PendingTxCache.java @@ -10,10 +10,9 @@ import java.util.Set; import java.util.TreeMap; import java.util.concurrent.atomic.AtomicInteger; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; -import org.aion.vm.api.interfaces.Address; import org.aion.zero.types.AionTransaction; import org.apache.commons.collections4.map.LRUMap; import org.slf4j.Logger; diff --git a/modAionImpl/src/org/aion/zero/impl/cli/Cli.java b/modAionImpl/src/org/aion/zero/impl/cli/Cli.java index ee1818809a..957b6cb48b 100644 --- a/modAionImpl/src/org/aion/zero/impl/cli/Cli.java +++ b/modAionImpl/src/org/aion/zero/impl/cli/Cli.java @@ -18,13 +18,14 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import org.aion.base.util.Hex; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.mcf.account.Keystore; import org.aion.mcf.config.Cfg; import org.aion.mcf.config.CfgSsl; import org.aion.mcf.config.CfgSync; +import org.aion.util.conversions.Hex; +import org.aion.vm.VirtualMachineProvider; import org.aion.zero.impl.Version; import org.aion.zero.impl.config.Network; import org.aion.zero.impl.db.RecoveryUtils; @@ -521,7 +522,9 @@ public ReturnType call(final String[] args, Cfg cfg) { String parameter = options.isRedoImport(); if (parameter.isEmpty()) { + VirtualMachineProvider.initializeAllVirtualMachines(); RecoveryUtils.redoMainChainImport(height); + VirtualMachineProvider.shutdownAllVirtualMachines(); return EXIT; } else { try { @@ -533,7 +536,10 @@ public ReturnType call(final String[] args, Cfg cfg) { + "» cannot be converted to a number."); return ERROR; } + + VirtualMachineProvider.initializeAllVirtualMachines(); RecoveryUtils.redoMainChainImport(height); + VirtualMachineProvider.shutdownAllVirtualMachines(); return EXIT; } } diff --git a/modAionImpl/src/org/aion/zero/impl/config/CfgConsensusPow.java b/modAionImpl/src/org/aion/zero/impl/config/CfgConsensusPow.java index 0fb38882b0..a1e135445c 100644 --- a/modAionImpl/src/org/aion/zero/impl/config/CfgConsensusPow.java +++ b/modAionImpl/src/org/aion/zero/impl/config/CfgConsensusPow.java @@ -7,7 +7,7 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.mcf.config.Cfg; import org.aion.mcf.config.CfgConsensus; @@ -17,7 +17,7 @@ public final class CfgConsensusPow extends CfgConsensus { CfgConsensusPow() { this.mining = false; - this.minerAddress = AionAddress.ZERO_ADDRESS().toString(); + this.minerAddress = Address.ZERO_ADDRESS().toString(); this.cpuMineThreads = (byte) (Runtime.getRuntime().availableProcessors() diff --git a/modAionImpl/src/org/aion/zero/impl/core/BloomFilter.java b/modAionImpl/src/org/aion/zero/impl/core/BloomFilter.java index f57018551f..eb39393394 100644 --- a/modAionImpl/src/org/aion/zero/impl/core/BloomFilter.java +++ b/modAionImpl/src/org/aion/zero/impl/core/BloomFilter.java @@ -2,7 +2,7 @@ import org.aion.crypto.HashUtil; import org.aion.mcf.vm.types.Bloom; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; public class BloomFilter { public static boolean containsAddress(Bloom bloom, Address address) { diff --git a/modAionImpl/src/org/aion/zero/impl/core/DiffCalc.java b/modAionImpl/src/org/aion/zero/impl/core/DiffCalc.java index 8fcdafa2f4..cd648a955a 100644 --- a/modAionImpl/src/org/aion/zero/impl/core/DiffCalc.java +++ b/modAionImpl/src/org/aion/zero/impl/core/DiffCalc.java @@ -1,7 +1,7 @@ package org.aion.zero.impl.core; -import static org.aion.base.util.BIUtil.max; -import static org.aion.base.util.BIUtil.min; +import static org.aion.util.biginteger.BIUtil.max; +import static org.aion.util.biginteger.BIUtil.min; import java.math.BigInteger; import org.aion.mcf.blockchain.IBlockConstants; diff --git a/modAionImpl/src/org/aion/zero/impl/core/IAionBlockchain.java b/modAionImpl/src/org/aion/zero/impl/core/IAionBlockchain.java index be049ec165..3b026c485b 100644 --- a/modAionImpl/src/org/aion/zero/impl/core/IAionBlockchain.java +++ b/modAionImpl/src/org/aion/zero/impl/core/IAionBlockchain.java @@ -2,9 +2,9 @@ import java.util.List; import java.util.Map; -import org.aion.base.db.IRepository; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.db.Repository; import org.aion.mcf.core.IBlockchain; +import org.aion.types.ByteArrayWrapper; import org.aion.zero.impl.BlockContext; import org.aion.zero.impl.sync.DatabaseType; import org.aion.zero.impl.types.AionBlock; @@ -27,19 +27,35 @@ BlockContext createNewBlockContext( AionBlock getBlockByNumber(long num); + /** + * Returns a range of main chain blocks. + * + * @param first the height of the first block in the requested range; this block must exist in + * the blockchain and be above the genesis to return a non-null output + * @param last the height of the last block in the requested range; when requesting blocks in + * ascending order the last element will be substituted with the best block if its height is + * above the best known block + * @return a list containing consecutive main chain blocks with heights ranging according to the + * given parameters; or {@code null} in case of errors or illegal request + * @apiNote The blocks must be added to the list in the order that they are requested. If {@code + * first > last} the blocks are returned in descending order of their height, otherwise when + * {@code first < last} the blocks are returned in ascending order of their height. + */ + List getBlocksByRange(long first, long last); + /** * Recovery functionality for rebuilding the world state. * * @return {@code true} if the recovery was successful, {@code false} otherwise */ - boolean recoverWorldState(IRepository repository, AionBlock block); + boolean recoverWorldState(Repository repository, AionBlock block); /** * Recovery functionality for recreating the block info in the index database. * * @return {@code true} if the recovery was successful, {@code false} otherwise */ - boolean recoverIndexEntry(IRepository repository, AionBlock block); + boolean recoverIndexEntry(Repository repository, AionBlock block); /** * Heuristic for skipping the call to tryToConnect with very large or very small block number. diff --git a/modMcf/src/org/aion/mcf/db/AbstractContractDetails.java b/modAionImpl/src/org/aion/zero/impl/db/AbstractContractDetails.java similarity index 88% rename from modMcf/src/org/aion/mcf/db/AbstractContractDetails.java rename to modAionImpl/src/org/aion/zero/impl/db/AbstractContractDetails.java index 5cfe0e56d2..c5740d0bfb 100644 --- a/modMcf/src/org/aion/mcf/db/AbstractContractDetails.java +++ b/modAionImpl/src/org/aion/zero/impl/db/AbstractContractDetails.java @@ -1,4 +1,4 @@ -package org.aion.mcf.db; +package org.aion.zero.impl.db; import static org.aion.crypto.HashUtil.EMPTY_DATA_HASH; import static org.aion.crypto.HashUtil.h256; @@ -8,12 +8,13 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; -import org.aion.base.db.IContractDetails; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.db.ContractDetails; +import org.aion.mcf.tx.TransactionTypes; +import org.aion.types.ByteArrayWrapper; import org.aion.util.conversions.Hex; /** Abstract contract details. */ -public abstract class AbstractContractDetails implements IContractDetails { +public abstract class AbstractContractDetails implements ContractDetails { private boolean dirty = false; private boolean deleted = false; @@ -22,6 +23,8 @@ public abstract class AbstractContractDetails implements IContractDetails { protected int detailsInMemoryStorageLimit; private Map codes = new HashMap<>(); + // set to FVM_CREATE_CODE to update encoding for FVM contracts + protected byte vmType = TransactionTypes.FVM_CREATE_CODE; protected AbstractContractDetails() { this(0, 64 * 1024); @@ -72,6 +75,14 @@ public void appendCodes(Map codes) { this.codes.putAll(codes); } + public void setVmType(byte vmType) { + this.vmType = vmType; + } + + public byte getVmType() { + return vmType; + } + @Override public void setDirty(boolean dirty) { this.dirty = dirty; diff --git a/modAionImpl/src/org/aion/zero/impl/db/AionBlockStore.java b/modAionImpl/src/org/aion/zero/impl/db/AionBlockStore.java index 152e9a44f7..9aa7142161 100644 --- a/modAionImpl/src/org/aion/zero/impl/db/AionBlockStore.java +++ b/modAionImpl/src/org/aion/zero/impl/db/AionBlockStore.java @@ -17,13 +17,12 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Deque; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.Hex; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.aion.mcf.db.AbstractPowBlockstore; @@ -33,6 +32,8 @@ import org.aion.rlp.RLP; import org.aion.rlp.RLPElement; import org.aion.rlp.RLPList; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.conversions.Hex; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.types.A0BlockHeader; import org.aion.zero.types.IAionBlock; @@ -54,19 +55,19 @@ public class AionBlockStore extends AbstractPowBlockstore(); private long branchingLevel; - public AionBlockStore(IByteArrayKeyValueDatabase index, IByteArrayKeyValueDatabase blocks) { + public AionBlockStore(ByteArrayKeyValueDatabase index, ByteArrayKeyValueDatabase blocks) { init(index, blocks); } public AionBlockStore( - IByteArrayKeyValueDatabase index, - IByteArrayKeyValueDatabase blocks, + ByteArrayKeyValueDatabase index, + ByteArrayKeyValueDatabase blocks, boolean checkIntegrity) { this(index, blocks); this.checkIntegrity = checkIntegrity; } - private void init(IByteArrayKeyValueDatabase index, IByteArrayKeyValueDatabase blocks) { + private void init(ByteArrayKeyValueDatabase index, ByteArrayKeyValueDatabase blocks) { this.index = new DataSourceArray<>(new ObjectDataSource<>(index, BLOCK_INFO_SERIALIZER)); @@ -241,6 +242,103 @@ public AionBlock getChainBlockByNumber(long number) { } } + /** + * Returns a range of main chain blocks. + * + * @param first the height of the first block in the requested range; this block must exist in + * the blockchain and be above the genesis to return a non-null output + * @param last the height of the last block in the requested range; when requesting blocks in + * ascending order the last element will be substituted with the best block if its height is + * above the best known block + * @return a list containing consecutive main chain blocks with heights ranging according to the + * given parameters; or {@code null} in case of errors or illegal request + * @apiNote The blocks must be added to the list in the order that they are requested. If {@code + * first > last} the blocks are returned in descending order of their height, otherwise when + * {@code first < last} the blocks are returned in ascending order of their height. + */ + public List getBlocksByRange(long first, long last) { + if (first <= 0L) { + return null; + } + + lock.readLock().lock(); + + try { + AionBlock block = getChainBlockByNumber(first); + if (block == null) { + // invalid request + return null; + } + + if (first == last) { + return List.of(block); + } else if (first > last) { // first is highest -> can query directly by parent hash + List blocks = new ArrayList<>(); + blocks.add(block); + + for (long i = first - 1; i >= (last > 0 ? last : 1); i--) { + block = getBlockByHash(block.getParentHash()); + if (block == null) { + // the block should have been stored but null was returned above + LOG.error( + "Encountered a kernel database corruption: cannot find block at level {} in data store.", + i); + return null; // stops at any invalid data + } else { + blocks.add(block); + } + } + return blocks; + } else { // last is highest + LinkedList blocks = new LinkedList<>(); + AionBlock lastBlock = getChainBlockByNumber(last); + + if (lastBlock == null) { // assuming height was above best block + // attempt to get best block + lastBlock = getBestBlock(); + if (lastBlock == null) { + LOG.error( + "Encountered a kernel database corruption: cannot find best block in data store."); + // invalid data store + return null; + } else if (last < lastBlock.getNumber()) { + // the block should have been stored but null was returned above + LOG.error( + "Encountered a kernel database corruption: cannot find block at level {} in data store.", + last); + // invalid data store + return null; + } + } + // the block was not null + // or it was higher than the best block and replaced with the best block + + // building existing range + blocks.addFirst(lastBlock); + long newLast = lastBlock.getNumber(); + for (long i = newLast - 1; i > first; i--) { + lastBlock = getBlockByHash(lastBlock.getParentHash()); + if (lastBlock == null) { + LOG.error( + "Encountered a kernel database corruption: cannot find block at level {} in data store.", + i); + return null; // stops at any invalid data + } else { + // always adding at the beginning of the list + // to return the expected order of blocks + blocks.addFirst(lastBlock); + } + } + + // adding the initial block + blocks.addFirst(block); + return blocks; + } + } finally { + lock.readLock().unlock(); + } + } + @SuppressWarnings("Duplicates") public Map.Entry getChainBlockByNumberWithTotalDifficulty(long number) { lock.readLock().lock(); diff --git a/modAion/src/org/aion/zero/db/AionContractDetailsImpl.java b/modAionImpl/src/org/aion/zero/impl/db/AionContractDetailsImpl.java similarity index 72% rename from modAion/src/org/aion/zero/db/AionContractDetailsImpl.java rename to modAionImpl/src/org/aion/zero/impl/db/AionContractDetailsImpl.java index 7d62f22a1c..2f13a5c5f2 100644 --- a/modAion/src/org/aion/zero/db/AionContractDetailsImpl.java +++ b/modAionImpl/src/org/aion/zero/impl/db/AionContractDetailsImpl.java @@ -1,40 +1,40 @@ -package org.aion.zero.db; +package org.aion.zero.impl.db; -import static org.aion.base.util.ByteArrayWrapper.wrap; -import static org.aion.base.util.ByteUtil.EMPTY_BYTE_ARRAY; import static org.aion.crypto.HashUtil.EMPTY_TRIE_HASH; import static org.aion.crypto.HashUtil.h256; +import static org.aion.types.ByteArrayWrapper.wrap; +import static org.aion.util.bytes.ByteUtil.EMPTY_BYTE_ARRAY; +import com.google.common.annotations.VisibleForTesting; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; -import org.aion.base.db.IByteArrayKeyValueStore; -import org.aion.base.db.IContractDetails; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.mcf.db.AbstractContractDetails; +import org.aion.interfaces.db.ByteArrayKeyValueStore; +import org.aion.interfaces.db.ContractDetails; import org.aion.mcf.ds.XorDataSource; import org.aion.mcf.trie.SecureTrie; +import org.aion.mcf.tx.TransactionTypes; import org.aion.rlp.RLP; import org.aion.rlp.RLPElement; import org.aion.rlp.RLPItem; import org.aion.rlp.RLPList; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; public class AionContractDetailsImpl extends AbstractContractDetails { - private IByteArrayKeyValueStore dataSource; + private ByteArrayKeyValueStore dataSource; private byte[] rlpEncoded; - private Address address = AionAddress.EMPTY_ADDRESS(); + private Address address; private SecureTrie storageTrie = new SecureTrie(null); public boolean externalStorage; - private IByteArrayKeyValueStore externalStorageDataSource; + private ByteArrayKeyValueStore externalStorageDataSource; public AionContractDetailsImpl() {} @@ -44,7 +44,11 @@ public AionContractDetailsImpl(int prune, int memStorageLimit) { private AionContractDetailsImpl( Address address, SecureTrie storageTrie, Map codes) { - this.address = address; + if (address == null) { + throw new IllegalArgumentException("Address can not be null!"); + } else { + this.address = address; + } this.storageTrie = storageTrie; setCodes(codes); } @@ -71,8 +75,8 @@ public void put(ByteArrayWrapper key, ByteArrayWrapper value) { Objects.requireNonNull(value); // The following must be done before making this call: - // We strip leading zeros of a DataWord but not a DoubleDataWord so that when we call get - // we can differentiate between the two. + // We strip leading zeros of a DataWordImpl but not a DoubleDataWord so that when we call + // get we can differentiate between the two. byte[] data = RLP.encodeElement(value.getData()); storageTrie.update(key.getData(), data); @@ -92,11 +96,11 @@ public void delete(ByteArrayWrapper key) { } /** - * Returns the value associated with key if it exists, otherwise returns a DataWord consisting - * entirely of zero bytes. + * Returns the value associated with key if it exists, otherwise returns a DataWordImpl + * consisting entirely of zero bytes. * * @param key The key to query. - * @return the corresponding value or a zero-byte DataWord if no such value. + * @return the corresponding value or a zero-byte DataWordImpl if no such value. */ @Override public ByteArrayWrapper get(ByteArrayWrapper key) { @@ -106,6 +110,10 @@ public ByteArrayWrapper get(ByteArrayWrapper key) { : new ByteArrayWrapper(RLP.decode2(data).get(0).getRLPData()); } + public byte getVmType() { + return vmType; + } + /** * Returns the storage hash. * @@ -136,8 +144,41 @@ public void decode(byte[] rlpCode) { @Override public void decode(byte[] rlpCode, boolean fastCheck) { RLPList data = RLP.decode2(rlpCode); + RLPList rlpList = (RLPList) data.get(0); + // compatible with old encoding + decodeEncodingWithoutVmType(rlpList, fastCheck); + + if (rlpList.size() == 5) { + // only FVM contracts used the old encoding + vmType = TransactionTypes.FVM_CREATE_CODE; + + // save with new encoding + this.rlpEncoded = null; + getEncoded(); + } else { + // Decodes the new version of encoding which is a list of 6 elements, specifically:
    + // { 0:address, 1:isExternalStorage, 2:storageRoot, 3:storage, 4:code, 5: vmType } + RLPItem vm = (RLPItem) rlpList.get(5); + + if (vm == null || vm.getRLPData() == null || vm.getRLPData().length == 0) { + throw new IllegalArgumentException("rlp decode error: invalid vm code"); + } else { + this.vmType = vm.getRLPData()[0]; + } + + this.rlpEncoded = rlpCode; + } + } + + /** + * Decodes the old version of encoding which was a list of 5 elements, specifically:
    + * { 0:address, 1:isExternalStorage, 2:storageRoot, 3:storage, 4:code } + * + *

    Only FVM contracts used this encoding on the mainnet and mastery networks. + */ + public void decodeEncodingWithoutVmType(RLPList rlpList, boolean fastCheck) { RLPItem isExternalStorage = (RLPItem) rlpList.get(1); RLPItem storage = (RLPItem) rlpList.get(3); this.externalStorage = isExternalStorage.getRLPData().length > 0; @@ -152,10 +193,12 @@ public void decode(byte[] rlpCode, boolean fastCheck) { RLPItem storageRoot = (RLPItem) rlpList.get(2); RLPElement code = rlpList.get(4); - if (address.getRLPData() == null) { - this.address = AionAddress.EMPTY_ADDRESS(); + if (address == null + || address.getRLPData() == null + || address.getRLPData().length != Address.SIZE) { + throw new IllegalArgumentException("rlp decode error."); } else { - this.address = AionAddress.wrap(address.getRLPData()); + this.address = Address.wrap(address.getRLPData()); } if (code instanceof RLPList) { @@ -179,13 +222,14 @@ public void decode(byte[] rlpCode, boolean fastCheck) { externalStorage = true; storageTrie.getCache().setDB(getExternalStorageDataSource()); } - - this.rlpEncoded = rlpCode; } /** * Returns an rlp encoding of this AionContractDetailsImpl object. * + *

    The encoding is a list of 6 elements:
    + * { 0:address, 1:isExternalStorage, 2:storageRoot, 3:storage, 4:code, 5: vmType } + * * @return an rlp encoding of this. */ @Override @@ -206,9 +250,17 @@ public byte[] getEncoded() { } byte[] rlpCode = RLP.encodeList(codes); + // vm type was not added + byte[] rlpVmType = RLP.encodeByte(vmType); + this.rlpEncoded = RLP.encodeList( - rlpAddress, rlpIsExternalStorage, rlpStorageRoot, rlpStorage, rlpCode); + rlpAddress, + rlpIsExternalStorage, + rlpStorageRoot, + rlpStorage, + rlpCode, + rlpVmType); } return rlpEncoded; @@ -231,6 +283,9 @@ public Address getAddress() { */ @Override public void setAddress(Address address) { + if (address == null) { + throw new IllegalArgumentException("Address can not be null!"); + } this.address = address; this.rlpEncoded = null; } @@ -248,7 +303,7 @@ public void syncStorage() { * * @param dataSource The new dataSource. */ - public void setDataSource(IByteArrayKeyValueStore dataSource) { + public void setDataSource(ByteArrayKeyValueStore dataSource) { this.dataSource = dataSource; } @@ -257,7 +312,7 @@ public void setDataSource(IByteArrayKeyValueStore dataSource) { * * @return the external storage data source. */ - private IByteArrayKeyValueStore getExternalStorageDataSource() { + private ByteArrayKeyValueStore getExternalStorageDataSource() { if (externalStorageDataSource == null) { externalStorageDataSource = new XorDataSource( @@ -270,8 +325,12 @@ private IByteArrayKeyValueStore getExternalStorageDataSource() { * Sets the external storage data source to dataSource. * * @param dataSource The new data source. + * @implNote The tests are taking a shortcut here in bypassing the XorDataSource created by + * {@link #getExternalStorageDataSource()}. Do not use this method in production. */ - public void setExternalStorageDataSource(IByteArrayKeyValueStore dataSource) { + @VisibleForTesting + void setExternalStorageDataSource(ByteArrayKeyValueStore dataSource) { + // TODO: regarding the node above: the tests should be updated and the method removed this.externalStorageDataSource = dataSource; this.externalStorage = true; this.storageTrie = new SecureTrie(getExternalStorageDataSource()); @@ -285,7 +344,7 @@ public void setExternalStorageDataSource(IByteArrayKeyValueStore dataSource) { * @return the specified AionContractDetailsImpl. */ @Override - public IContractDetails getSnapshotTo(byte[] hash) { + public ContractDetails getSnapshotTo(byte[] hash) { SecureTrie snapStorage = wrap(hash).equals(wrap(EMPTY_TRIE_HASH)) @@ -295,6 +354,11 @@ public IContractDetails getSnapshotTo(byte[] hash) { AionContractDetailsImpl details = new AionContractDetailsImpl(this.address, snapStorage, getCodes()); + + // vm information + details.vmType = this.vmType; + + // storage information details.externalStorage = this.externalStorage; details.externalStorageDataSource = this.externalStorageDataSource; details.dataSource = dataSource; @@ -319,16 +383,21 @@ public IContractDetails getSnapshotTo(byte[] hash) { @Override public AionContractDetailsImpl copy() { AionContractDetailsImpl aionContractDetailsCopy = new AionContractDetailsImpl(); + + // vm information + aionContractDetailsCopy.vmType = this.vmType; + + // storage information aionContractDetailsCopy.dataSource = this.dataSource; aionContractDetailsCopy.externalStorageDataSource = this.externalStorageDataSource; aionContractDetailsCopy.externalStorage = this.externalStorage; + aionContractDetailsCopy.prune = this.prune; aionContractDetailsCopy.detailsInMemoryStorageLimit = this.detailsInMemoryStorageLimit; aionContractDetailsCopy.setCodes(getDeepCopyOfCodes()); aionContractDetailsCopy.setDirty(this.isDirty()); aionContractDetailsCopy.setDeleted(this.isDeleted()); - aionContractDetailsCopy.address = - (this.address == null) ? null : new AionAddress(this.address.toBytes()); + aionContractDetailsCopy.address = new Address(this.address.toBytes()); aionContractDetailsCopy.rlpEncoded = (this.rlpEncoded == null) ? null diff --git a/modAionImpl/src/org/aion/zero/impl/db/AionRepositoryCache.java b/modAionImpl/src/org/aion/zero/impl/db/AionRepositoryCache.java new file mode 100644 index 0000000000..49e728dd6c --- /dev/null +++ b/modAionImpl/src/org/aion/zero/impl/db/AionRepositoryCache.java @@ -0,0 +1,627 @@ +package org.aion.zero.impl.db; + +import static org.aion.crypto.HashUtil.h256; +import static org.aion.util.bytes.ByteUtil.EMPTY_BYTE_ARRAY; + +import java.math.BigInteger; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import org.aion.interfaces.db.ByteArrayKeyValueStore; +import org.aion.interfaces.db.ContractDetails; +import org.aion.interfaces.db.Repository; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.log.AionLoggerFactory; +import org.aion.log.LogEnum; +import org.aion.mcf.core.AccountState; +import org.aion.mcf.db.IBlockStoreBase; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; +import org.slf4j.Logger; + +public class AionRepositoryCache implements RepositoryCache> { + + // Logger + protected static final Logger LOG = AionLoggerFactory.getLogger(LogEnum.DB.name()); + + /** the repository being tracked */ + protected Repository> repository; + + /** local accounts cache */ + protected Map cachedAccounts; + + protected ReadWriteLock lockAccounts = new ReentrantReadWriteLock(); + /** local contract details cache */ + protected Map cachedDetails; + + protected ReadWriteLock lockDetails = new ReentrantReadWriteLock(); + + public AionRepositoryCache(final Repository trackedRepository) { + this.repository = trackedRepository; + this.cachedAccounts = new HashMap<>(); + this.cachedDetails = new HashMap<>(); + } + + @Override + public RepositoryCache startTracking() { + return new AionRepositoryCache(this); + } + + @Override + public AccountState createAccount(Address address) { + fullyWriteLock(); + try { + AccountState accountState = new AccountState(); + cachedAccounts.put(address, accountState); + + // TODO: unify contract details initialization from Impl and Track + ContractDetails contractDetails = new ContractDetailsCacheImpl(null); + // TODO: refactor to use makeDirty() from AbstractState + contractDetails.setDirty(true); + cachedDetails.put(address, contractDetails); + + return accountState; + } finally { + fullyWriteUnlock(); + } + } + + /** + * Retrieves the current state of the account associated with the given address. + * + * @param address the address of the account of interest + * @return a {@link AccountState} object representing the account state as is stored in the + * database or cache + * @implNote If there is no account associated with the given address, it will create it. + */ + @Override + public AccountState getAccountState(Address address) { + lockAccounts.readLock().lock(); + + try { + // check if the account is cached locally + AccountState accountState = this.cachedAccounts.get(address); + + // when the account is not cached load it from the repository + if (accountState == null) { + // must unlock to perform write operation from loadAccountState(address) + lockAccounts.readLock().unlock(); + loadAccountState(address); + lockAccounts.readLock().lock(); + accountState = this.cachedAccounts.get(address); + } + + return accountState; + } finally { + try { + lockAccounts.readLock().unlock(); + } catch (Exception e) { + // there was nothing to unlock + } + } + } + + public boolean hasAccountState(Address address) { + lockAccounts.readLock().lock(); + try { + AccountState accountState = cachedAccounts.get(address); + + if (accountState != null) { + // checks that the account is not cached as deleted + // TODO: may also need to check if the state is empty + return !accountState.isDeleted(); + } else { + // check repository when not cached + return repository.hasAccountState(address); + } + } finally { + lockAccounts.readLock().unlock(); + } + } + + @Override + public ContractDetails getContractDetails(Address address) { + lockDetails.readLock().lock(); + + try { + ContractDetails contractDetails = this.cachedDetails.get(address); + + if (contractDetails == null) { + // loads the address into cache + // must unlock to perform write operation from loadAccountState(address) + lockDetails.readLock().unlock(); + loadAccountState(address); + lockDetails.readLock().lock(); + // retrieves the contract details + contractDetails = this.cachedDetails.get(address); + } + + return contractDetails; + } finally { + try { + lockDetails.readLock().unlock(); + } catch (Exception e) { + // there was nothing to unlock + } + } + } + + @Override + public boolean hasContractDetails(Address address) { + lockDetails.readLock().lock(); + + try { + ContractDetails contractDetails = cachedDetails.get(address); + + if (contractDetails == null) { + // ask repository when not cached + return repository.hasContractDetails(address); + } else { + // TODO: may also need to check if the details are empty + return !contractDetails.isDeleted(); + } + } finally { + lockDetails.readLock().unlock(); + } + } + + /** + * @implNote The loaded objects are fresh copies of the locally cached account state and + * contract details. + */ + @Override + public void loadAccountState( + Address address, + Map accounts, + Map details) { + fullyReadLock(); + + try { + // check if the account is cached locally + AccountState accountState = this.cachedAccounts.get(address); + ContractDetails contractDetails = this.cachedDetails.get(address); + + // when account not cached load from repository + if (accountState == null) { + // load directly to the caches given as parameters + repository.loadAccountState(address, accounts, details); + } else { + // copy the objects if they were cached locally + accounts.put(address, new AccountState(accountState)); + details.put(address, new ContractDetailsCacheImpl(contractDetails)); + } + } finally { + fullyReadUnlock(); + } + } + + /** + * Loads the state of the account into this object' caches. Requires write locks on both + * {@link #lockAccounts} and {@link #lockDetails}. + * + * @implNote If the calling method has acquired a weaker lock, the lock must be released before + * calling this method. + * @apiNote If the account was never stored this call will create it. + */ + private void loadAccountState(Address address) { + fullyWriteLock(); + try { + repository.loadAccountState(address, this.cachedAccounts, this.cachedDetails); + } finally { + fullyWriteUnlock(); + } + } + + @Override + public void deleteAccount(Address address) { + fullyWriteLock(); + try { + getAccountState(address).delete(); + getContractDetails(address).setDeleted(true); + } finally { + fullyWriteUnlock(); + } + } + + @Override + public BigInteger incrementNonce(Address address) { + lockAccounts.writeLock().lock(); + try { + return getAccountState(address).incrementNonce(); + } finally { + lockAccounts.writeLock().unlock(); + } + } + + @Override + public BigInteger setNonce(Address address, BigInteger newNonce) { + lockAccounts.writeLock().lock(); + try { + return getAccountState(address).setNonce(newNonce); + } finally { + lockAccounts.writeLock().unlock(); + } + } + + @Override + public BigInteger getNonce(Address address) { + AccountState accountState = getAccountState(address); + // account state can never be null, but may be empty or deleted + return (accountState.isEmpty() || accountState.isDeleted()) + ? BigInteger.ZERO + : accountState.getNonce(); + } + + @Override + public BigInteger getBalance(Address address) { + AccountState accountState = getAccountState(address); + // account state can never be null, but may be empty or deleted + return (accountState.isEmpty() || accountState.isDeleted()) + ? BigInteger.ZERO + : accountState.getBalance(); + } + + @Override + public BigInteger addBalance(Address address, BigInteger value) { + lockAccounts.writeLock().lock(); + try { + // TODO: where do we ensure that this does not result in a negative value? + AccountState accountState = getAccountState(address); + return accountState.addToBalance(value); + } finally { + lockAccounts.writeLock().unlock(); + } + } + + @Override + public void saveCode(Address address, byte[] code) { + fullyWriteLock(); + try { + // save the code + // TODO: why not create contract here directly? also need to check that there is no + // preexisting code! + ContractDetails contractDetails = getContractDetails(address); + contractDetails.setCode(code); + // TODO: ensure that setDirty is done by the class itself + contractDetails.setDirty(true); + + // update the code hash + getAccountState(address).setCodeHash(h256(code)); + } finally { + fullyWriteUnlock(); + } + } + + @Override + public byte[] getCode(Address address) { + if (!hasAccountState(address)) { + return EMPTY_BYTE_ARRAY; + } + + byte[] codeHash = getAccountState(address).getCodeHash(); + + // TODO: why use codeHash here? may require refactoring + return getContractDetails(address).getCode(codeHash); + } + + @Override + public void addStorageRow(Address address, ByteArrayWrapper key, ByteArrayWrapper value) { + lockDetails.writeLock().lock(); + try { + getContractDetails(address).put(key, value); + } finally { + lockDetails.writeLock().unlock(); + } + } + + @Override + public void removeStorageRow(Address address, ByteArrayWrapper key) { + lockDetails.writeLock().lock(); + try { + getContractDetails(address).delete(key); + } finally { + lockDetails.writeLock().unlock(); + } + } + + @Override + public ByteArrayWrapper getStorageValue(Address address, ByteArrayWrapper key) { + return getContractDetails(address).get(key); + } + + @Override + public Map getStorage( + Address address, Collection keys) { + ContractDetails details = getContractDetails(address); + return (details == null) ? Collections.emptyMap() : details.getStorage(keys); + } + + @Override + public void rollback() { + fullyWriteLock(); + try { + cachedAccounts.clear(); + cachedDetails.clear(); + } finally { + fullyWriteUnlock(); + } + } + + @Override + public Repository getSnapshotTo(byte[] root) { + return repository.getSnapshotTo(root); + } + + // This method was originally disabled because changes to the blockstore + // can not be reverted. The reason for re-enabling it is that we have no way + // to + // get a reference of the blockstore without using + // NProgInvoke/NcpProgInvoke. + @Override + public IBlockStoreBase getBlockStore() { + return repository.getBlockStore(); + } + + /** Lock to prevent writing on both accounts and details. */ + protected void fullyWriteLock() { + lockAccounts.writeLock().lock(); + lockDetails.writeLock().lock(); + } + + /** Unlock to allow writing on both accounts and details. */ + protected void fullyWriteUnlock() { + lockDetails.writeLock().unlock(); + lockAccounts.writeLock().unlock(); + } + + /** Lock for reading both accounts and details. */ + protected void fullyReadLock() { + lockAccounts.readLock().lock(); + lockDetails.readLock().lock(); + } + + /** Unlock reading for both accounts and details. */ + protected void fullyReadUnlock() { + lockDetails.readLock().unlock(); + lockAccounts.readLock().unlock(); + } + + @Override + public boolean isSnapshot() { + return repository.isSnapshot(); + } + + /** + * Flushes its state to other in such a manner that other receives sufficiently deep copies of + * its {@link AccountState} and {@link ContractDetails} objects. + * + *

    If {@code clearStateAfterFlush == true} then this repository's state will be completely + * cleared after this method returns, otherwise it will retain all of its state. + * + *

    A "sufficiently deep copy" is an imperfect deep copy (some original object references get + * leaked) but such that for all conceivable use cases these imperfections should go unnoticed. + * This is because doing something like copying the underlying data store makes no sense, both + * repositories should be accessing it, and there are some other cases where objects are defined + * as type {@link Object} and are cast to their expected types and copied, but will not be + * copied if they are not in fact their expected types. This is something to be aware of. Most + * of the imperfection results from the inability to copy {@link ByteArrayKeyValueStore} and + * {@link org.aion.mcf.trie.SecureTrie} perfectly or at all (in the case of the former), for the + * above reasons. + * + * @param other The repository that will consume the state of this repository. + * @param clearStateAfterFlush True if this repository should clear its state after flushing. + */ + public void flushCopiesTo(Repository other, boolean clearStateAfterFlush) { + fullyWriteLock(); + try { + // determine which accounts should get stored + HashMap cleanedCacheAccounts = new HashMap<>(); + for (Map.Entry entry : cachedAccounts.entrySet()) { + AccountState account = entry.getValue().copy(); + if (account != null && account.isDirty() && account.isEmpty()) { + // ignore contract state for empty accounts at storage + cachedDetails.remove(entry.getKey()); + } else { + cleanedCacheAccounts.put(new Address(entry.getKey().toBytes()), account); + } + } + // determine which contracts should get stored + for (Map.Entry entry : cachedDetails.entrySet()) { + ContractDetails ctd = entry.getValue().copy(); + // TODO: this functionality will be improved with the switch to a + // different ContractDetails implementation + if (ctd != null && ctd instanceof ContractDetailsCacheImpl) { + ContractDetailsCacheImpl contractDetailsCache = (ContractDetailsCacheImpl) ctd; + contractDetailsCache.commit(); + + if (contractDetailsCache.origContract == null + && other.hasContractDetails(entry.getKey())) { + // in forked block the contract account might not exist thus + // it is created without + // origin, but on the main chain details can contain data + // which should be merged + // into a single storage trie so both branches with + // different stateRoots are valid + contractDetailsCache.origContract = + other.getContractDetails(entry.getKey()).copy(); + contractDetailsCache.commit(); + } + } + } + + other.updateBatch(cleanedCacheAccounts, cachedDetails); + if (clearStateAfterFlush) { + cachedAccounts.clear(); + cachedDetails.clear(); + } + } finally { + fullyWriteUnlock(); + } + } + + @Override + public void flushTo(Repository other, boolean clearStateAfterFlush) { + fullyWriteLock(); + try { + // determine which accounts should get stored + HashMap cleanedCacheAccounts = new HashMap<>(); + for (Map.Entry entry : cachedAccounts.entrySet()) { + AccountState account = entry.getValue(); + if (account != null && account.isDirty() && account.isEmpty()) { + // ignore contract state for empty accounts at storage + cachedDetails.remove(entry.getKey()); + } else { + cleanedCacheAccounts.put(entry.getKey(), entry.getValue()); + } + } + // determine which contracts should get stored + for (Map.Entry entry : cachedDetails.entrySet()) { + ContractDetails ctd = entry.getValue(); + // TODO: this functionality will be improved with the switch to a + // different ContractDetails implementation + if (ctd instanceof ContractDetailsCacheImpl) { + ContractDetailsCacheImpl contractDetailsCache = (ContractDetailsCacheImpl) ctd; + contractDetailsCache.commit(); + + if (contractDetailsCache.origContract == null + && other.hasContractDetails(entry.getKey())) { + // in forked block the contract account might not exist thus + // it is created without + // origin, but on the main chain details can contain data + // which should be merged + // into a single storage trie so both branches with + // different stateRoots are valid + contractDetailsCache.origContract = + other.getContractDetails(entry.getKey()); + contractDetailsCache.commit(); + } + } + } + + other.updateBatch(cleanedCacheAccounts, cachedDetails); + if (clearStateAfterFlush) { + cachedAccounts.clear(); + cachedDetails.clear(); + } + } finally { + fullyWriteUnlock(); + } + } + + /** + * @implNote To maintain intended functionality this method does not call the parent's {@code + * flush()} method. The changes are propagated to the parent through calling the parent's + * {@code updateBatch()} method. + */ + @Override + public void flush() { + flushTo(repository, true); + } + + @Override + public void updateBatch( + Map accounts, final Map details) { + fullyWriteLock(); + try { + + for (Map.Entry accEntry : accounts.entrySet()) { + this.cachedAccounts.put(accEntry.getKey(), accEntry.getValue()); + } + + for (Map.Entry ctdEntry : details.entrySet()) { + ContractDetailsCacheImpl contractDetailsCache = + (ContractDetailsCacheImpl) ctdEntry.getValue().copy(); + if (contractDetailsCache.origContract != null + && !(contractDetailsCache.origContract + instanceof AionContractDetailsImpl)) { + // Copying the parent because contract details changes were pushed to the parent + // in previous method (flush) + cachedDetails.put( + ctdEntry.getKey(), + ContractDetailsCacheImpl.copy( + (ContractDetailsCacheImpl) contractDetailsCache.origContract)); + } else { + // Either no parent or we have Repo's AionContractDetailsImpl, which should be + // flushed through RepoImpl + cachedDetails.put( + ctdEntry.getKey(), ContractDetailsCacheImpl.copy(contractDetailsCache)); + } + } + } finally { + fullyWriteUnlock(); + } + } + + @Override + public boolean isClosed() { + // delegate to the tracked repository + return repository.isClosed(); + } + + @Override + public void close() { + throw new UnsupportedOperationException( + "The tracking cache cannot be closed. \'Close\' should be called on the tracked repository."); + } + + @Override + public void compact() { + throw new UnsupportedOperationException( + "The tracking cache cannot be compacted. \'Compact\' should be called on the tracked repository."); + } + + @Override + public byte[] getRoot() { + throw new UnsupportedOperationException( + "The tracking cache cannot return the root. \'Get root\' should be called on the tracked repository."); + } + + @Override + public void syncToRoot(byte[] root) { + throw new UnsupportedOperationException( + "The tracking cache cannot sync to root. \'Sync to root\' should be called on the tracked repository."); + } + + @Override + public void addTxBatch(Map pendingTx, boolean isPool) { + throw new UnsupportedOperationException( + "addTxBatch should be called on the tracked repository."); + } + + @Override + public void removeTxBatch(Set pendingTx, boolean isPool) { + throw new UnsupportedOperationException( + "removeTxBatch should be called on the tracked repository."); + } + + @Override + public boolean isValidRoot(byte[] root) { + return this.repository.isValidRoot(root); + } + + @Override + public boolean isIndexed(byte[] hash, long level) { + return repository.isIndexed(hash, level); + } + + @Override + public List getPoolTx() { + throw new UnsupportedOperationException( + "getPoolTx should be called on the tracked repository."); + } + + @Override + public List getCacheTx() { + throw new UnsupportedOperationException( + "getCachelTx should be called on the tracked repository."); + } + + public byte getVMUsed(Address contract) { + return repository.getVMUsed(contract); + } +} diff --git a/modAionImpl/src/org/aion/zero/impl/db/AionRepositoryDummy.java b/modAionImpl/src/org/aion/zero/impl/db/AionRepositoryDummy.java deleted file mode 100644 index df44bb878a..0000000000 --- a/modAionImpl/src/org/aion/zero/impl/db/AionRepositoryDummy.java +++ /dev/null @@ -1,283 +0,0 @@ -package org.aion.zero.impl.db; - -import static org.aion.crypto.HashUtil.h256; - -import java.math.BigInteger; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import org.aion.base.db.IContractDetails; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.db.IRepositoryConfig; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.Hex; -import org.aion.mcf.core.AccountState; -import org.aion.mcf.db.ContractDetailsCacheImpl; -import org.aion.vm.api.interfaces.Address; -import org.aion.zero.db.AionRepositoryCache; -import org.aion.zero.types.IAionBlock; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** @author jay */ -public class AionRepositoryDummy extends AionRepositoryImpl { - - private static final Logger logger = LoggerFactory.getLogger("repository"); - private Map worldState = new HashMap<>(); - private Map detailsDB = new HashMap<>(); - - public AionRepositoryDummy(IRepositoryConfig cfg) { - super(cfg); - } - - public void reset() { - - worldState.clear(); - detailsDB.clear(); - } - - public void close() { - worldState.clear(); - detailsDB.clear(); - } - - public boolean isClosed() { - throw new UnsupportedOperationException(); - } - - public void updateBatch( - HashMap stateCache, - HashMap detailsCache) { - - for (ByteArrayWrapper hash : stateCache.keySet()) { - - AccountState accountState = stateCache.get(hash); - IContractDetails contractDetails = detailsCache.get(hash); - - if (accountState.isDeleted()) { - worldState.remove(hash); - detailsDB.remove(hash); - - logger.debug("delete: [{}]", Hex.toHexString(hash.getData())); - - } else { - - if (accountState.isDirty() || contractDetails.isDirty()) { - detailsDB.put(hash, contractDetails); - accountState.setStateRoot(contractDetails.getStorageHash()); - accountState.setCodeHash(h256(contractDetails.getCode())); - worldState.put(hash, accountState); - if (logger.isDebugEnabled()) { - logger.debug( - "update: [{}],nonce: [{}] balance: [{}] \n [{}]", - Hex.toHexString(hash.getData()), - accountState.getNonce(), - accountState.getBalance(), - Hex.toHexString(contractDetails.getStorageHash())); - } - } - } - } - - stateCache.clear(); - detailsCache.clear(); - } - - public void flush() { - throw new UnsupportedOperationException(); - } - - public void rollback() { - throw new UnsupportedOperationException(); - } - - public void commit() { - throw new UnsupportedOperationException(); - } - - public void syncToRoot(byte[] root) { - throw new UnsupportedOperationException(); - } - - public IRepositoryCache startTracking() { - return new AionRepositoryCache(this); - } - - public void dumpState(IAionBlock block, long nrgUsed, int txNumber, byte[] txHash) {} - - public Set

    getAccountsKeys() { - return null; - } - - public Set getFullAddressSet() { - return worldState.keySet(); - } - - public BigInteger addBalance(Address addr, BigInteger value) { - AccountState account = getAccountState(addr); - - if (account == null) { - account = createAccount(addr); - } - - BigInteger result = account.addToBalance(value); - worldState.put(ByteArrayWrapper.wrap(addr.toBytes()), account); - - return result; - } - - public BigInteger getBalance(Address addr) { - AccountState account = getAccountState(addr); - - if (account == null) { - return BigInteger.ZERO; - } - - return account.getBalance(); - } - - public ByteArrayWrapper getStorageValue(Address addr, ByteArrayWrapper key) { - IContractDetails details = getContractDetails(addr); - ByteArrayWrapper value = (details == null) ? null : details.get(key); - - if (value != null && value.isZero()) { - // TODO: remove when integrating the AVM - // used to ensure FVM correctness - throw new IllegalStateException( - "The contract address " - + addr.toString() - + " returned a zero value for the key " - + key.toString() - + " which is not a valid stored value for the FVM. "); - } - - return value; - } - - // never used - // public void addStorageRow(Address addr, ByteArrayWrapper key, ByteArrayWrapper value) { - // IContractDetails details = getContractDetails(addr); - // - // if (details == null) { - // createAccount(addr); - // details = getContractDetails(addr); - // } - // details.put(key, value); - // detailsDB.put(ByteArrayWrapper.wrap(addr.toBytes()), details); - // } - - public byte[] getCode(Address addr) { - IContractDetails details = getContractDetails(addr); - - if (details == null) { - return null; - } - - return details.getCode(); - } - - public void saveCode(Address addr, byte[] code) { - IContractDetails details = getContractDetails(addr); - - if (details == null) { - createAccount(addr); - details = getContractDetails(addr); - } - - details.setCode(code); - detailsDB.put(ByteArrayWrapper.wrap(addr.toBytes()), details); - } - - public BigInteger getNonce(Address addr) { - AccountState account = getAccountState(addr); - - if (account == null) { - account = createAccount(addr); - } - - return account.getNonce(); - } - - public BigInteger increaseNonce(Address addr) { - AccountState account = getAccountState(addr); - - if (account == null) { - account = createAccount(addr); - } - - account.incrementNonce(); - worldState.put(ByteArrayWrapper.wrap(addr.toBytes()), account); - - return account.getNonce(); - } - - public BigInteger setNonce(Address addr, BigInteger nonce) { - - AccountState account = getAccountState(addr); - - if (account == null) { - account = createAccount(addr); - } - - account.setNonce(nonce); - worldState.put(ByteArrayWrapper.wrap(addr.toBytes()), account); - - return account.getNonce(); - } - - public void delete(Address addr) { - worldState.remove(ByteArrayWrapper.wrap(addr.toBytes())); - detailsDB.remove(ByteArrayWrapper.wrap(addr.toBytes())); - } - - public IContractDetails getContractDetails(Address addr) { - - return detailsDB.get(ByteArrayWrapper.wrap(addr.toBytes())); - } - - public AccountState getAccountState(Address addr) { - return worldState.get((ByteArrayWrapper.wrap(addr.toBytes()))); - } - - public AccountState createAccount(Address addr) { - AccountState accountState = new AccountState(); - worldState.put(ByteArrayWrapper.wrap(addr.toBytes()), accountState); - - IContractDetails contractDetails = this.cfg.contractDetailsImpl(); - detailsDB.put(ByteArrayWrapper.wrap(addr.toBytes()), contractDetails); - - return accountState; - } - - public boolean isExist(Address addr) { - return getAccountState(addr) != null; - } - - public byte[] getRoot() { - throw new UnsupportedOperationException(); - } - - public void loadAccount( - Address addr, - HashMap cacheAccounts, - HashMap cacheDetails) { - - AccountState account = getAccountState(addr); - IContractDetails details = getContractDetails(addr); - - if (account == null) { - account = new AccountState(); - } else { - account = new AccountState(account); - } - - if (details == null) { - details = this.cfg.contractDetailsImpl(); - } else { - details = new ContractDetailsCacheImpl(details); - } - - cacheAccounts.put(ByteArrayWrapper.wrap(addr.toBytes()), account); - cacheDetails.put(ByteArrayWrapper.wrap(addr.toBytes()), details); - } -} diff --git a/modAionImpl/src/org/aion/zero/impl/db/AionRepositoryImpl.java b/modAionImpl/src/org/aion/zero/impl/db/AionRepositoryImpl.java index dff34f2d74..27b81dbedf 100644 --- a/modAionImpl/src/org/aion/zero/impl/db/AionRepositoryImpl.java +++ b/modAionImpl/src/org/aion/zero/impl/db/AionRepositoryImpl.java @@ -1,7 +1,7 @@ package org.aion.zero.impl.db; -import static org.aion.base.util.ByteUtil.EMPTY_BYTE_ARRAY; import static org.aion.crypto.HashUtil.EMPTY_TRIE_HASH; +import static org.aion.util.bytes.ByteUtil.EMPTY_BYTE_ARRAY; import static org.aion.zero.impl.AionHub.INIT_ERROR_EXIT_CODE; import java.math.BigInteger; @@ -14,24 +14,24 @@ import java.util.Map; import java.util.Optional; import java.util.Set; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.db.IContractDetails; -import org.aion.base.db.IRepository; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.db.IRepositoryConfig; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.Hex; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.ContractDetails; +import org.aion.interfaces.db.Repository; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.interfaces.db.RepositoryConfig; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.AbstractRepository; -import org.aion.mcf.db.ContractDetailsCacheImpl; import org.aion.mcf.db.TransactionStore; +import org.aion.mcf.ds.ObjectDataSource; import org.aion.mcf.trie.SecureTrie; import org.aion.mcf.trie.Trie; import org.aion.mcf.trie.TrieImpl; import org.aion.mcf.trie.TrieNodeResult; +import org.aion.mcf.tx.TransactionTypes; import org.aion.p2p.V1Constants; -import org.aion.vm.api.interfaces.Address; -import org.aion.zero.db.AionRepositoryCache; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; +import org.aion.util.conversions.Hex; import org.aion.zero.impl.config.CfgAion; import org.aion.zero.impl.sync.DatabaseType; import org.aion.zero.impl.types.AionBlock; @@ -49,6 +49,9 @@ public class AionRepositoryImpl // pending block store private PendingBlockStore pendingStore; + // inferred contract information not used for consensus + private ObjectDataSource contractInfoSource; + /** * used by getSnapShotTo * @@ -57,29 +60,16 @@ public class AionRepositoryImpl */ protected AionRepositoryImpl() {} - protected AionRepositoryImpl(IRepositoryConfig repoConfig) { + protected AionRepositoryImpl(RepositoryConfig repoConfig) { this.cfg = repoConfig; init(); } - private static class AionRepositoryImplHolder { - // configuration - private static CfgAion config = CfgAion.inst(); - - // repository singleton instance - private static final AionRepositoryImpl inst = - new AionRepositoryImpl( - new RepositoryConfig( - config.getDatabasePath(), - ContractDetailsAion.getInstance(), - config.getDb())); - } - public static AionRepositoryImpl inst() { return AionRepositoryImplHolder.inst; } - public static AionRepositoryImpl createForTesting(IRepositoryConfig repoConfig) { + public static AionRepositoryImpl createForTesting(RepositoryConfig repoConfig) { return new AionRepositoryImpl(repoConfig); } @@ -96,6 +86,9 @@ private void init() { this.blockStore = new AionBlockStore(indexDatabase, blockDatabase, checkIntegrity); this.pendingStore = new PendingBlockStore(pendingStoreProperties); + this.contractInfoSource = + new ObjectDataSource<>( + contractIndexDatabase, ContractInformation.RLP_SERIALIZER); // Setup world trie. worldState = createStateTrie(); @@ -122,14 +115,14 @@ private Trie createStateTrie() { @Override public void updateBatch( - Map stateCache, Map detailsCache) { + Map stateCache, Map detailsCache) { rwLock.writeLock().lock(); try { for (Map.Entry entry : stateCache.entrySet()) { Address address = entry.getKey(); AccountState accountState = entry.getValue(); - IContractDetails contractDetails = detailsCache.get(address); + ContractDetails contractDetails = detailsCache.get(address); if (accountState.isDeleted()) { // TODO-A: batch operations here @@ -212,7 +205,7 @@ public void updateBatch( /** @implNote The method calling this method must handle the locking. */ private void updateContractDetails( - final Address address, final IContractDetails contractDetails) { + final Address address, final ContractDetails contractDetails) { // locked by calling method detailsDS.update(address, contractDetails); } @@ -242,7 +235,7 @@ public void flush() { } if (databaseGroup != null) { - for (IByteArrayKeyValueDatabase db : databaseGroup) { + for (ByteArrayKeyValueDatabase db : databaseGroup) { if (!db.isAutoCommitEnabled()) { db.commit(); } @@ -297,7 +290,7 @@ public void syncToRoot(final byte[] root) { } @Override - public IRepositoryCache startTracking() { + public RepositoryCache startTracking() { return new AionRepositoryCache(this); } @@ -318,7 +311,7 @@ public BigInteger getBalance(Address address) { @Override public ByteArrayWrapper getStorageValue(Address address, ByteArrayWrapper key) { - IContractDetails details = getContractDetails(address); + ContractDetails details = getContractDetails(address); return (details == null) ? null : details.get(key); } @@ -365,7 +358,7 @@ public List getCacheTx() { @Override public Map getStorage( Address address, Collection keys) { - IContractDetails details = getContractDetails(address); + ContractDetails details = getContractDetails(address); return (details == null) ? Collections.emptyMap() : details.getStorage(keys); } @@ -379,7 +372,7 @@ public byte[] getCode(Address address) { byte[] codeHash = accountState.getCodeHash(); - IContractDetails details = getContractDetails(address); + ContractDetails details = getContractDetails(address); return (details == null) ? EMPTY_BYTE_ARRAY : details.getCode(codeHash); } @@ -398,16 +391,16 @@ private void updateAccountState(Address address, AccountState accountState) { /** * @inheritDoc * @implNote Any other method calling this can rely on the fact that the contract details - * returned is a newly created object by {@link IContractDetails#getSnapshotTo(byte[])}. + * returned is a newly created object by {@link ContractDetails#getSnapshotTo(byte[])}. * Since this querying method it locked, the methods calling it may not need to be locked * or synchronized, depending on the specific use case. */ @Override - public IContractDetails getContractDetails(Address address) { + public ContractDetails getContractDetails(Address address) { rwLock.readLock().lock(); try { - IContractDetails details; + ContractDetails details; // That part is important cause if we have // to sync details storage according the trie root @@ -482,10 +475,10 @@ public boolean hasAccountState(Address address) { public void loadAccountState( Address address, Map cacheAccounts, - Map cacheDetails) { + Map cacheDetails) { AccountState account = getAccountState(address); - IContractDetails details = getContractDetails(address); + ContractDetails details = getContractDetails(address); account = (account == null) ? new AccountState() : new AccountState(account); details = new ContractDetailsCacheImpl(details); @@ -523,7 +516,6 @@ public void commitBlock(A0BlockHeader blockHeader) { try { worldState.sync(); - detailsDS.syncLargeStorage(); if (pruneEnabled) { if (stateDSPrune.isArchiveEnabled() && blockHeader.getNumber() % archiveRate == 0) { @@ -571,12 +563,13 @@ public Trie getWorldState() { } @Override - public IRepository getSnapshotTo(byte[] root) { + public Repository getSnapshotTo(byte[] root) { rwLock.readLock().lock(); try { AionRepositoryImpl repo = new AionRepositoryImpl(); repo.blockStore = blockStore; + repo.contractInfoSource = contractInfoSource; repo.cfg = cfg; repo.stateDatabase = this.stateDatabase; repo.stateWithArchive = this.stateWithArchive; @@ -655,6 +648,17 @@ public void close() { LOGGEN.error("Exception occurred while closing the details data source.", e); } + try { + if (contractIndexDatabase != null) { + contractIndexDatabase.close(); + LOGGEN.info("contractIndexDatabase store closed."); + contractIndexDatabase = null; + } + } catch (Exception e) { + LOGGEN.error( + "Exception occurred while closing the pendingTxCacheDatabase store.", e); + } + try { if (stateDatabase != null) { stateDatabase.close(); @@ -739,11 +743,11 @@ public void close() { * * @return */ - public IByteArrayKeyValueDatabase getStateDatabase() { + public ByteArrayKeyValueDatabase getStateDatabase() { return this.stateDatabase; } - public IByteArrayKeyValueDatabase getStateArchiveDatabase() { + public ByteArrayKeyValueDatabase getStateArchiveDatabase() { return this.stateArchiveDatabase; } @@ -756,17 +760,17 @@ public IByteArrayKeyValueDatabase getStateArchiveDatabase() { * * @return */ - public IByteArrayKeyValueDatabase getDetailsDatabase() { + public ByteArrayKeyValueDatabase getDetailsDatabase() { return this.detailsDatabase; } /** For testing. */ - public IByteArrayKeyValueDatabase getBlockDatabase() { + public ByteArrayKeyValueDatabase getBlockDatabase() { return this.blockDatabase; } /** For testing. */ - public IByteArrayKeyValueDatabase getIndexDatabase() { + public ByteArrayKeyValueDatabase getIndexDatabase() { return this.indexDatabase; } @@ -782,13 +786,13 @@ public String toString() { } /** - * Calls {@link IByteArrayKeyValueDatabase#drop()} on all the current databases except for the + * Calls {@link ByteArrayKeyValueDatabase#drop()} on all the current databases except for the * ones given in the list by name. * * @param names the names of the databases that should not be dropped */ public void dropDatabasesExcept(List names) { - for (IByteArrayKeyValueDatabase db : databaseGroup) { + for (ByteArrayKeyValueDatabase db : databaseGroup) { if (!names.contains(db.getName().get())) { LOG.warn("Dropping database " + db.toString() + " ..."); db.drop(); @@ -802,7 +806,7 @@ public void compact() { rwLock.writeLock().lock(); try { if (databaseGroup != null) { - for (IByteArrayKeyValueDatabase db : databaseGroup) { + for (ByteArrayKeyValueDatabase db : databaseGroup) { db.compact(); } } else { @@ -833,14 +837,10 @@ public void compactState() { * supported */ public byte[] getTrieNode(byte[] key, DatabaseType dbType) { - IByteArrayKeyValueDatabase db = selectDatabase(dbType); + ByteArrayKeyValueDatabase db = selectDatabase(dbType); Optional value = db.get(key); - if (value.isPresent()) { - return value.get(); - } else { - return null; - } + return value.orElse(null); } /** @@ -861,7 +861,7 @@ public Map getReferencedTrieNodes( if (limit <= 0) { return Collections.emptyMap(); } else { - IByteArrayKeyValueDatabase db = selectDatabase(dbType); + ByteArrayKeyValueDatabase db = selectDatabase(dbType); Trie trie = new TrieImpl(db); return trie.getReferencedTrieNodes(value, limit); @@ -874,9 +874,9 @@ public Map getReferencedTrieNodes( * @param key the hash key of the trie node to be imported * @param value the value of the trie node to be imported * @param dbType the database where the key-value pair should be stored + * @return a {@link TrieNodeResult} indicating the success or failure of the import operation * @throws IllegalArgumentException if the given key is null or the database type is not * supported - * @return a {@link TrieNodeResult} indicating the success or failure of the import operation */ public TrieNodeResult importTrieNode(byte[] key, byte[] value, DatabaseType dbType) { // empty keys are not allowed @@ -889,7 +889,7 @@ public TrieNodeResult importTrieNode(byte[] key, byte[] value, DatabaseType dbTy return TrieNodeResult.INVALID_VALUE; } - IByteArrayKeyValueDatabase db = selectDatabase(dbType); + ByteArrayKeyValueDatabase db = selectDatabase(dbType); Optional stored = db.get(key); if (stored.isPresent()) { @@ -904,7 +904,7 @@ public TrieNodeResult importTrieNode(byte[] key, byte[] value, DatabaseType dbTy return TrieNodeResult.IMPORTED; } - private IByteArrayKeyValueDatabase selectDatabase(DatabaseType dbType) { + private ByteArrayKeyValueDatabase selectDatabase(DatabaseType dbType) { switch (dbType) { case DETAILS: return detailsDatabase; @@ -917,4 +917,44 @@ private IByteArrayKeyValueDatabase selectDatabase(DatabaseType dbType) { "The database type " + dbType.toString() + " is not supported."); } } + + /** + * Returns the {@link ContractInformation} stored for the given contract. + * + * @return the {@link ContractInformation} stored for the given contract + */ + public ContractInformation getIndexedContractInformation(Address contract) { + return contract == null ? null : contractInfoSource.get(contract.toBytes()); + } + + public void saveIndexedContractInformation( + Address contract, long inceptionBlock, byte vmUsed, boolean complete) { + if (contract != null) { + contractInfoSource.put( + contract.toBytes(), new ContractInformation(inceptionBlock, vmUsed, complete)); + } + } + + public byte getVMUsed(Address contract) { + ContractInformation ci = getIndexedContractInformation(contract); + if (ci == null) { + // defaults to FastVM for backwards compatibility + return TransactionTypes.FVM_CREATE_CODE; + } else { + return ci.getVmUsed(); + } + } + + private static class AionRepositoryImplHolder { + // configuration + private static CfgAion config = CfgAion.inst(); + + // repository singleton instance + private static final AionRepositoryImpl inst = + new AionRepositoryImpl( + new RepositoryConfigImpl( + config.getDatabasePath(), + ContractDetailsAion.getInstance(), + config.getDb())); + } } diff --git a/modAionImpl/src/org/aion/zero/impl/db/AionTransactionStoreSerializer.java b/modAionImpl/src/org/aion/zero/impl/db/AionTransactionStoreSerializer.java index 36e6cff543..f1ea2b9e5f 100644 --- a/modAionImpl/src/org/aion/zero/impl/db/AionTransactionStoreSerializer.java +++ b/modAionImpl/src/org/aion/zero/impl/db/AionTransactionStoreSerializer.java @@ -10,7 +10,7 @@ public class AionTransactionStoreSerializer { public static final Serializer, byte[]> serializer = - new Serializer, byte[]>() { + new Serializer<>() { @Override public byte[] serialize(List object) { byte[][] txsRlp = new byte[object.size()][]; diff --git a/modAionImpl/src/org/aion/zero/impl/db/ContractDetailsAion.java b/modAionImpl/src/org/aion/zero/impl/db/ContractDetailsAion.java index 54f1f53da7..163840b4fd 100644 --- a/modAionImpl/src/org/aion/zero/impl/db/ContractDetailsAion.java +++ b/modAionImpl/src/org/aion/zero/impl/db/ContractDetailsAion.java @@ -1,8 +1,7 @@ package org.aion.zero.impl.db; -import org.aion.base.db.DetailsProvider; -import org.aion.base.db.IContractDetails; -import org.aion.zero.db.AionContractDetailsImpl; +import org.aion.interfaces.db.ContractDetails; +import org.aion.interfaces.db.DetailsProvider; /** * Contract details provider for Aion. @@ -54,7 +53,7 @@ public static ContractDetailsAion getInstance() { } @Override - public IContractDetails getDetails() { + public ContractDetails getDetails() { return new AionContractDetailsImpl(this.prune, this.memStorageLimit); } } diff --git a/modMcf/src/org/aion/mcf/db/ContractDetailsCacheImpl.java b/modAionImpl/src/org/aion/zero/impl/db/ContractDetailsCacheImpl.java similarity index 87% rename from modMcf/src/org/aion/mcf/db/ContractDetailsCacheImpl.java rename to modAionImpl/src/org/aion/zero/impl/db/ContractDetailsCacheImpl.java index 4532ad03c7..bc63147a21 100644 --- a/modMcf/src/org/aion/mcf/db/ContractDetailsCacheImpl.java +++ b/modAionImpl/src/org/aion/zero/impl/db/ContractDetailsCacheImpl.java @@ -1,23 +1,24 @@ -package org.aion.mcf.db; +package org.aion.zero.impl.db; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; -import org.aion.base.db.IByteArrayKeyValueStore; -import org.aion.base.db.IContractDetails; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.vm.api.interfaces.Address; +import org.aion.interfaces.db.ByteArrayKeyValueStore; +import org.aion.interfaces.db.ContractDetails; +import org.aion.mcf.tx.TransactionTypes; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; /** Contract details cache implementation. */ public class ContractDetailsCacheImpl extends AbstractContractDetails { private Map storage = new HashMap<>(); - public IContractDetails origContract; + public ContractDetails origContract; - public ContractDetailsCacheImpl(IContractDetails origContract) { + public ContractDetailsCacheImpl(ContractDetails origContract) { this.origContract = origContract; if (origContract != null) { if (origContract instanceof AbstractContractDetails) { @@ -31,6 +32,7 @@ public ContractDetailsCacheImpl(IContractDetails origContract) { public static ContractDetailsCacheImpl copy(ContractDetailsCacheImpl cache) { ContractDetailsCacheImpl copy = new ContractDetailsCacheImpl(cache.origContract); copy.setCodes(new HashMap<>(cache.getCodes())); + copy.vmType = cache.vmType; copy.storage = new HashMap<>(cache.storage); copy.setDirty(cache.isDirty()); copy.setDeleted(cache.isDeleted()); @@ -96,6 +98,13 @@ public ByteArrayWrapper get(ByteArrayWrapper key) { return value; } + public byte getVmType() { + if (vmType == TransactionTypes.DEFAULT && origContract != null) { + vmType = ((AbstractContractDetails) origContract).getVmType(); + } + return vmType; + } + /** * Returns the storage hash. * @@ -103,7 +112,7 @@ public ByteArrayWrapper get(ByteArrayWrapper key) { */ @Override public byte[] getStorageHash() { - return origContract.getStorageHash(); + return origContract == null ? null : origContract.getStorageHash(); } /** This method is not supported. */ @@ -184,13 +193,13 @@ public void commit() { /** This method is not supported. */ @Override - public IContractDetails getSnapshotTo(byte[] hash) { + public ContractDetails getSnapshotTo(byte[] hash) { throw new UnsupportedOperationException("No snapshot option during cache state"); } /** This method is not supported. */ @Override - public void setDataSource(IByteArrayKeyValueStore dataSource) { + public void setDataSource(ByteArrayKeyValueStore dataSource) { throw new UnsupportedOperationException("Can't set datasource in cache implementation."); } @@ -220,17 +229,17 @@ public ContractDetailsCacheImpl copy() { "Cannot copy a ContractDetailsCacheImpl whose original contract is itself!"); } - IContractDetails originalContractCopy = + ContractDetails originalContractCopy = (this.origContract == null) ? null : this.origContract.copy(); - ContractDetailsCacheImpl contractDetailsCacheCopy = - new ContractDetailsCacheImpl(originalContractCopy); - contractDetailsCacheCopy.storage = getDeepCopyOfStorage(); - contractDetailsCacheCopy.prune = this.prune; - contractDetailsCacheCopy.detailsInMemoryStorageLimit = this.detailsInMemoryStorageLimit; - contractDetailsCacheCopy.setCodes(getDeepCopyOfCodes()); - contractDetailsCacheCopy.setDirty(this.isDirty()); - contractDetailsCacheCopy.setDeleted(this.isDeleted()); - return contractDetailsCacheCopy; + ContractDetailsCacheImpl copy = new ContractDetailsCacheImpl(originalContractCopy); + copy.vmType = this.vmType; + copy.storage = getDeepCopyOfStorage(); + copy.prune = this.prune; + copy.detailsInMemoryStorageLimit = this.detailsInMemoryStorageLimit; + copy.setCodes(getDeepCopyOfCodes()); + copy.setDirty(this.isDirty()); + copy.setDeleted(this.isDeleted()); + return copy; } private Map getDeepCopyOfCodes() { diff --git a/modAionImpl/src/org/aion/zero/impl/db/ContractInformation.java b/modAionImpl/src/org/aion/zero/impl/db/ContractInformation.java new file mode 100644 index 0000000000..e8d38ce296 --- /dev/null +++ b/modAionImpl/src/org/aion/zero/impl/db/ContractInformation.java @@ -0,0 +1,107 @@ +package org.aion.zero.impl.db; + +import java.math.BigInteger; +import org.aion.mcf.ds.Serializer; +import org.aion.rlp.RLP; +import org.aion.rlp.RLPList; + +/** + * Indexed information about contracts that is not part of consensus. Used to: + * + *
      + *
    1. quickly find the block where the contract was created; + *
    2. determine which virtual machine was used in deploying the contract; + *
    3. check if the contract information is complete during fast sync. + *
    + * + * @author Alexandra Roatis + */ +public class ContractInformation { + private long inceptionBlock; + private byte vmUsed; + private boolean complete; + + private ContractInformation() {} + + public ContractInformation(long inceptionBlock, byte vmUsed, boolean complete) { + this.inceptionBlock = inceptionBlock; + this.vmUsed = vmUsed; + this.complete = complete; + } + + public static final Serializer RLP_SERIALIZER = + new Serializer<>() { + + /** + * Returns an RLP encoding of the given contract information object. + * + * @return an RLP encoding of the given contract information object. + */ + @Override + public byte[] serialize(ContractInformation info) { + // NOTE: not using encodeLong because of the non-standard RLP + byte[] rlpBlockNumber = RLP.encode(info.inceptionBlock); + byte[] rlpVmUsed = RLP.encodeByte(info.vmUsed); + byte[] rlpIsComplete = RLP.encodeByte((byte) (info.complete ? 1 : 0)); + + return RLP.encodeList(rlpBlockNumber, rlpVmUsed, rlpIsComplete); + } + + /** + * Decodes a contract information object from the RLP encoding. + * + * @param rlpEncoded The encoding to be interpreted as contract information. + */ + @Override + public ContractInformation deserialize(byte[] rlpEncoded) { + if (rlpEncoded == null || rlpEncoded.length == 0) { + return null; + } else { + RLPList list = (RLPList) RLP.decode2(rlpEncoded).get(0); + if (list.size() != 3) { + return null; + } else { + // create and populate object + ContractInformation info = new ContractInformation(); + + // decode the inception block + info.inceptionBlock = + new BigInteger(1, list.get(0).getRLPData()).longValue(); + if (info.inceptionBlock < 0) { + return null; + } + + // decode the VM used + byte[] array = list.get(1).getRLPData(); + if (array.length != 1) { + return null; + } else { + info.vmUsed = array[0]; + } + + // decode the completeness status + array = list.get(2).getRLPData(); + if (array.length != 1) { + return null; + } else { + info.complete = array[0] == 1; + } + + return info; + } + } + } + }; + + public long getInceptionBlock() { + return inceptionBlock; + } + + public byte getVmUsed() { + return vmUsed; + } + + public boolean isComplete() { + return complete; + } +} diff --git a/modAionImpl/src/org/aion/zero/impl/db/PendingBlockStore.java b/modAionImpl/src/org/aion/zero/impl/db/PendingBlockStore.java index 90a81671e1..33e937aeee 100644 --- a/modAionImpl/src/org/aion/zero/impl/db/PendingBlockStore.java +++ b/modAionImpl/src/org/aion/zero/impl/db/PendingBlockStore.java @@ -22,11 +22,9 @@ import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import org.aion.base.db.Flushable; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.Hex; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.Flushable; +import org.aion.types.ByteArrayWrapper; import org.aion.db.impl.DBVendor; import org.aion.db.impl.DatabaseFactory.Props; import org.aion.log.AionLoggerFactory; @@ -37,6 +35,8 @@ import org.aion.rlp.RLP; import org.aion.rlp.RLPElement; import org.aion.rlp.RLPList; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.conversions.Hex; import org.aion.zero.impl.types.AionBlock; import org.slf4j.Logger; @@ -79,13 +79,13 @@ public class PendingBlockStore implements Flushable, Closeable { */ private ObjectDataSource> levelSource; - private IByteArrayKeyValueDatabase levelDatabase; + private ByteArrayKeyValueDatabase levelDatabase; /** Used to map a queue identifier to a list of consecutive blocks. */ private ObjectDataSource> queueSource; - private IByteArrayKeyValueDatabase queueDatabase; + private ByteArrayKeyValueDatabase queueDatabase; /** Used to maps a block hash to its current queue identifier. */ - private IByteArrayKeyValueDatabase indexSource; + private ByteArrayKeyValueDatabase indexSource; // tracking the status: with access managed by the `internalLock` private Map status; @@ -531,7 +531,7 @@ int getQueueSize() { } } - private static int countDatabaseKeys(IByteArrayKeyValueDatabase db) { + private static int countDatabaseKeys(ByteArrayKeyValueDatabase db) { int size = 0; Iterator iterator = db.keys(); while (iterator.hasNext()) { diff --git a/modAionImpl/src/org/aion/zero/impl/db/RecoveryUtils.java b/modAionImpl/src/org/aion/zero/impl/db/RecoveryUtils.java index dd24833b8b..30338cc7b9 100644 --- a/modAionImpl/src/org/aion/zero/impl/db/RecoveryUtils.java +++ b/modAionImpl/src/org/aion/zero/impl/db/RecoveryUtils.java @@ -4,7 +4,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.aion.base.type.IBlock; +import org.aion.interfaces.block.Block; import org.aion.log.AionLoggerFactory; import org.aion.mcf.config.CfgDb; import org.aion.mcf.core.ImportResult; @@ -78,7 +78,7 @@ public static void pruneAndCorrect() { IBlockStoreBase store = blockchain.getBlockStore(); - IBlock bestBlock = store.getBestBlock(); + Block bestBlock = store.getBestBlock(); if (bestBlock == null) { System.out.println("Empty database. Nothing to do."); return; @@ -151,7 +151,7 @@ public static void dumpBlocks(long count) { public static Status revertTo(IAionBlockchain blockchain, long nbBlock) { IBlockStoreBase store = blockchain.getBlockStore(); - IBlock bestBlock = store.getBestBlock(); + Block bestBlock = store.getBestBlock(); if (bestBlock == null) { System.out.println("Empty database. Nothing to do."); return Status.ILLEGAL_ARGUMENT; diff --git a/modAionImpl/src/org/aion/zero/impl/db/RepositoryConfig.java b/modAionImpl/src/org/aion/zero/impl/db/RepositoryConfigImpl.java similarity index 65% rename from modAionImpl/src/org/aion/zero/impl/db/RepositoryConfig.java rename to modAionImpl/src/org/aion/zero/impl/db/RepositoryConfigImpl.java index a5190df066..c5bc52d8df 100644 --- a/modAionImpl/src/org/aion/zero/impl/db/RepositoryConfig.java +++ b/modAionImpl/src/org/aion/zero/impl/db/RepositoryConfigImpl.java @@ -2,16 +2,16 @@ import java.util.Map; import java.util.Properties; -import org.aion.base.db.DetailsProvider; -import org.aion.base.db.IContractDetails; -import org.aion.base.db.IPruneConfig; -import org.aion.base.db.IRepositoryConfig; +import org.aion.interfaces.db.ContractDetails; +import org.aion.interfaces.db.DetailsProvider; +import org.aion.interfaces.db.PruneConfig; +import org.aion.interfaces.db.RepositoryConfig; import org.aion.mcf.config.CfgDb; -public class RepositoryConfig implements IRepositoryConfig { +public class RepositoryConfigImpl implements RepositoryConfig { private final String dbPath; - private final IPruneConfig cfgPrune; + private final PruneConfig cfgPrune; private final DetailsProvider detailsProvider; private final Map cfg; @@ -21,12 +21,12 @@ public String getDbPath() { } @Override - public IPruneConfig getPruneConfig() { + public PruneConfig getPruneConfig() { return cfgPrune; } @Override - public IContractDetails contractDetailsImpl() { + public ContractDetails contractDetailsImpl() { return this.detailsProvider.getDetails(); } @@ -39,11 +39,11 @@ public Properties getDatabaseConfig(String db_name) { return new Properties(prop); } - public RepositoryConfig( + public RepositoryConfigImpl( final String dbPath, final DetailsProvider detailsProvider, final CfgDb cfgDb) { this.dbPath = dbPath; this.detailsProvider = detailsProvider; this.cfg = cfgDb.asProperties(); - this.cfgPrune = cfgDb.getPrune(); + this.cfgPrune = (PruneConfig) cfgDb.getPrune(); } } diff --git a/modAionImpl/src/org/aion/zero/impl/pow/AionPoW.java b/modAionImpl/src/org/aion/zero/impl/pow/AionPoW.java index af90496b18..1d1faf5ea1 100644 --- a/modAionImpl/src/org/aion/zero/impl/pow/AionPoW.java +++ b/modAionImpl/src/org/aion/zero/impl/pow/AionPoW.java @@ -10,8 +10,7 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; -import org.aion.base.util.Hex; -import org.aion.equihash.Solution; +import org.aion.equihash.AionPowSolution; import org.aion.evtmgr.IEvent; import org.aion.evtmgr.IEventMgr; import org.aion.evtmgr.IHandler; @@ -24,6 +23,7 @@ import org.aion.log.LogEnum; import org.aion.mcf.blockchain.IPendingState; import org.aion.mcf.core.ImportResult; +import org.aion.util.conversions.Hex; import org.aion.zero.impl.blockchain.AionImpl; import org.aion.zero.impl.config.CfgAion; import org.aion.zero.impl.core.IAionBlockchain; @@ -72,7 +72,7 @@ public void run() { createNewBlockTemplate(); } else if (e.getEventType() == IHandler.TYPE.CONSENSUS.getValue() && e.getCallbackType() == EventConsensus.CALLBACK.ON_SOLUTION.getValue()) { - processSolution((Solution) e.getFuncArgs().get(0)); + processSolution((AionPowSolution) e.getFuncArgs().get(0)); } else if (e.getEventType() == IHandler.TYPE.POISONPILL.getValue()) { go = false; } @@ -191,7 +191,7 @@ public void registerCallback() { * * @param solution The generated equihash solution */ - protected synchronized void processSolution(Solution solution) { + protected synchronized void processSolution(AionPowSolution solution) { if (!shutDown.get()) { if (LOG.isDebugEnabled()) { LOG.debug("Best block num [{}]", blockchain.getBestBlock().getNumber()); diff --git a/modAionImpl/src/org/aion/zero/impl/query/StateQueryInterface.java b/modAionImpl/src/org/aion/zero/impl/query/StateQueryInterface.java index a201f6bcb6..7e472a2ab4 100644 --- a/modAionImpl/src/org/aion/zero/impl/query/StateQueryInterface.java +++ b/modAionImpl/src/org/aion/zero/impl/query/StateQueryInterface.java @@ -1,9 +1,9 @@ package org.aion.zero.impl.query; import java.util.Optional; -import org.aion.base.util.ByteArrayWrapper; import org.aion.mcf.core.AccountState; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; public interface StateQueryInterface { Optional getAccountState(Address address, long blockNumber); diff --git a/modAionImpl/src/org/aion/zero/impl/query/SyncQueryInterface.java b/modAionImpl/src/org/aion/zero/impl/query/SyncQueryInterface.java index ae4d966375..be9f952880 100644 --- a/modAionImpl/src/org/aion/zero/impl/query/SyncQueryInterface.java +++ b/modAionImpl/src/org/aion/zero/impl/query/SyncQueryInterface.java @@ -6,6 +6,4 @@ public interface SyncQueryInterface { Optional getLocalBestBlockNumber(); Optional getNetworkBestBlockNumber(); - - boolean isSyncComplete(); } diff --git a/modAionImpl/src/org/aion/zero/impl/sync/Act.java b/modAionImpl/src/org/aion/zero/impl/sync/Act.java index 0223db178e..867baf0cfb 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/Act.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/Act.java @@ -22,4 +22,8 @@ public final class Act { public static final byte REQUEST_TRIE_DATA = 8; public static final byte RESPONSE_TRIE_DATA = 9; + + public static final byte REQUEST_BLOCKS = 12; + + public static final byte RESPONSE_BLOCKS = 13; } diff --git a/modAionImpl/src/org/aion/zero/impl/sync/FastSyncManager.java b/modAionImpl/src/org/aion/zero/impl/sync/FastSyncManager.java index 7e0fa4b712..ea0b248091 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/FastSyncManager.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/FastSyncManager.java @@ -1,11 +1,34 @@ package org.aion.zero.impl.sync; +import static org.aion.p2p.V1Constants.BLOCKS_REQUEST_MAXIMUM_BATCH_SIZE; + +import com.google.common.annotations.VisibleForTesting; import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Objects; import java.util.Set; +import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicBoolean; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.log.AionLoggerFactory; +import org.aion.log.LogEnum; +import org.aion.mcf.valid.BlockHeaderValidator; +import org.aion.p2p.INode; +import org.aion.p2p.impl1.P2pMgr; +import org.aion.types.ByteArrayWrapper; +import org.aion.zero.impl.AionBlockchainImpl; +import org.aion.zero.impl.sync.msg.RequestBlocks; +import org.aion.zero.impl.sync.msg.ResponseBlocks; +import org.aion.zero.impl.types.AionBlock; +import org.aion.zero.types.A0BlockHeader; +import org.apache.commons.collections4.map.LRUMap; +import org.slf4j.Logger; /** * Directs behavior for fast sync functionality. @@ -14,15 +37,56 @@ */ public final class FastSyncManager { + // TODO: ensure correct behavior when disabled private boolean enabled; + // TODO: ensure correct behavior when complete private final AtomicBoolean complete = new AtomicBoolean(false); + private final AtomicBoolean completeBlocks = new AtomicBoolean(false); + + private final AionBlockchainImpl chain; + private final BlockHeaderValidator blockHeaderValidator; + private final P2pMgr p2pMgr; + + // TODO: consider adding a FAST_SYNC log as well + private static final Logger log = AionLoggerFactory.getLogger(LogEnum.SYNC.name()); + + private AionBlock pivot = null; + + Map importedBlockHashes = + Collections.synchronizedMap(new LRUMap<>(4096)); + Map receivedBlockHashes = + Collections.synchronizedMap(new LRUMap<>(1000)); + + BlockingQueue downloadedBlocks = new LinkedBlockingQueue<>(); + Map receivedBlocks = new HashMap<>(); private final Map importedTrieNodes = new ConcurrentHashMap<>(); - public FastSyncManager() { - this.enabled = false; + public FastSyncManager( + AionBlockchainImpl chain, + BlockHeaderValidator blockHeaderValidator, + final P2pMgr p2pMgr) { + this.enabled = true; + this.chain = chain; + this.blockHeaderValidator = blockHeaderValidator; + this.p2pMgr = p2pMgr; } + @VisibleForTesting + void setPivot(AionBlock pivot) { + Objects.requireNonNull(pivot); + + this.pivot = pivot; + } + + public AionBlock getPivot() { + return pivot; + } + + // TODO: shutdown pool + ExecutorService executors = + Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + public void addImportedNode(ByteArrayWrapper key, byte[] value, DatabaseType dbType) { if (enabled) { importedTrieNodes.put(key, value); @@ -97,10 +161,31 @@ private void ensureCompleteness() { complete.set(true); } - private boolean isCompleteBlockData() { - // TODO: block requests should be made backwards from pivot - // TODO: requests need to be based on hash instead of level - return false; + public boolean isCompleteBlockData() { + if (completeBlocks.get()) { + // all checks have already passed + return true; + } else if (pivot == null) { + // the pivot was not initialized yet + return false; + } else if (chain.getBlockStore().getChainBlockByNumber(1L) == null) { + // checks for first block for fast fail if incomplete + return false; + } else if (chain.findMissingAncestor(pivot) != null) { // long check done last + // full check from pivot returned block + // i.e. the chain was incomplete at some point + return false; + } else { + // making the pivot the current best block + chain.setBestBlock(pivot); + + // walk through the chain to update the total difficulty + chain.getBlockStore().pruneAndCorrect(); + chain.getBlockStore().flush(); + + completeBlocks.set(true); + return true; + } } private boolean isCompleteReceiptData() { @@ -135,4 +220,107 @@ public void updateRequests( ensureCompleteness(); } } + + /** + * Processes a block response by checking the proof-of-work. Adds valid blocks to the import + * queue. + * + * @param peerId the numerical identifier of the peer who sent the response + * @param displayId the display identifier of the peer who sent the response + * @param response the response with blocks to be processed + */ + public void validateAndAddBlocks(int peerId, String displayId, ResponseBlocks response) { + if (!executors.isShutdown()) { + executors.submit( + new TaskValidateAndAddBlocks( + peerId, + displayId, + response, + blockHeaderValidator, + downloadedBlocks, + importedBlockHashes, + receivedBlockHashes, + log)); + } + } + + public void addToImportedBlocks(ByteArrayWrapper hash) { + this.importedBlockHashes.put(hash, null); // TODO: is there something useful I can add? + this.receivedBlockHashes.remove(hash); + } + + public BlocksWrapper takeFilteredBlocks(ByteArrayWrapper requiredHash, long requiredLevel) { + // first check the map + if (receivedBlocks.containsKey(requiredHash)) { + return receivedBlocks.remove(requiredHash); + } else if (receivedBlockHashes.containsKey(requiredHash)) { + // retrieve the batch that contains the block + ByteArrayWrapper wrapperHash = receivedBlockHashes.get(requiredHash); + return receivedBlocks.remove(wrapperHash); + } + + // process queue data + try { + while (!downloadedBlocks.isEmpty()) { + BlocksWrapper wrapper = downloadedBlocks.remove(); + + if (wrapper != null) { + wrapper.getBlocks() + .removeIf(b -> importedBlockHashes.containsKey(b.getHashWrapper())); + if (!wrapper.getBlocks().isEmpty()) { + ByteArrayWrapper firstHash = wrapper.getBlocks().get(0).getHashWrapper(); + if (firstHash.equals(requiredHash)) { + return wrapper; + } else { + // determine if the block is in the middle of the batch + boolean isRequred = false; + for (AionBlock block : wrapper.getBlocks()) { + ByteArrayWrapper hash = block.getHashWrapper(); + receivedBlockHashes.put(hash, firstHash); + if (hash.equals(requiredHash)) { + isRequred = true; + break; + } + } + if (isRequred) { + return wrapper; + } else { + receivedBlocks.put(firstHash, wrapper); + } + } + } + } + } + } catch (NoSuchElementException e) { + log.debug("The empty check should have prevented this exception.", e); + } + + // couldn't find the data, so need to request it + makeBlockRequests(requiredHash, requiredLevel); + + return null; + } + + private void makeBlockRequests(ByteArrayWrapper requiredHash, long requiredLevel) { + // make request for the needed hash + RequestBlocks request = + new RequestBlocks(requiredHash.getData(), BLOCKS_REQUEST_MAXIMUM_BATCH_SIZE, true); + + // TODO: improve peer selection + // TODO: request that level plus further blocks + INode peer = p2pMgr.getRandom(); + p2pMgr.send(peer.getIdHash(), peer.getIdShort(), request); + + // send an extra request ahead of time + if (requiredLevel - BLOCKS_REQUEST_MAXIMUM_BATCH_SIZE > 0) { + peer = p2pMgr.getRandom(); + request = + new RequestBlocks( + requiredLevel - BLOCKS_REQUEST_MAXIMUM_BATCH_SIZE, + BLOCKS_REQUEST_MAXIMUM_BATCH_SIZE, + true); + + p2pMgr.send(peer.getIdHash(), peer.getIdShort(), request); + } + } } diff --git a/modAionImpl/src/org/aion/zero/impl/sync/SyncMgr.java b/modAionImpl/src/org/aion/zero/impl/sync/SyncMgr.java index 8e0f6e398e..0eaac62834 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/SyncMgr.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/SyncMgr.java @@ -1,5 +1,7 @@ package org.aion.zero.impl.sync; +import static org.aion.util.string.StringUtils.getNodeIdShort; + import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; @@ -17,10 +19,6 @@ import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.Hex; -import org.aion.base.util.Utils; import org.aion.evtmgr.IEvent; import org.aion.evtmgr.IEventMgr; import org.aion.evtmgr.impl.evt.EventConsensus; @@ -29,6 +27,9 @@ import org.aion.mcf.config.StatsType; import org.aion.mcf.valid.BlockHeaderValidator; import org.aion.p2p.IP2pMgr; +import org.aion.types.ByteArrayWrapper; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.conversions.Hex; import org.aion.zero.impl.AionBlockchainImpl; import org.aion.zero.impl.blockchain.ChainConfiguration; import org.aion.zero.impl.types.AionBlock; @@ -133,9 +134,9 @@ public void updateNetworkStatus( _remoteBestBlockNumber, this.networkStatus.getTargetBestBlockHash().isEmpty() ? "" - : Utils.getNodeIdShort( + : getNodeIdShort( this.networkStatus.getTargetBestBlockHash()), - Utils.getNodeIdShort(remoteBestBlockHash), + getNodeIdShort(remoteBestBlockHash), this.networkStatus.getTargetApiVersion(), (int) _apiVersion, this.networkStatus.getTargetPeerCount(), diff --git a/modAionImpl/src/org/aion/zero/impl/sync/SyncStats.java b/modAionImpl/src/org/aion/zero/impl/sync/SyncStats.java index 8d65a8a793..b596c2cadc 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/SyncStats.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/SyncStats.java @@ -3,14 +3,16 @@ import com.google.common.annotations.VisibleForTesting; import java.util.Collection; import java.util.Collections; -import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -import java.util.stream.Collectors; import org.aion.mcf.config.StatsType; +import org.aion.zero.impl.sync.statistics.BlockType; +import org.aion.zero.impl.sync.statistics.RequestStatsTracker; +import org.aion.zero.impl.sync.statistics.RequestType; import org.aion.zero.impl.sync.statistics.ResponseStatsTracker; -import org.apache.commons.collections4.map.LRUMap; +import org.aion.zero.impl.sync.statistics.TopLeechesStatsTracker; +import org.aion.zero.impl.sync.statistics.TopSeedsStatsTracker; import org.apache.commons.lang3.tuple.Pair; /** @author chris */ @@ -23,25 +25,17 @@ public final class SyncStats { private final Lock blockAverageLock = new ReentrantLock(); private final boolean averageEnabled; - // Access to this resource is managed by the {@link #requestsLock}. - private final Map requestsToPeers; - private final Lock requestsLock; - private final boolean requestsEnabled; + private final RequestStatsTracker requestTracker; + private final boolean requestEnabled; - // Access to these resources is managed by the {@link #seedsLock}. - private final Map blocksByPeer; - private final Map importedByPeer; - private final Map storedByPeer; - private final Lock seedsLock; - private final boolean seedEnabled; + private final TopSeedsStatsTracker seedsTracker; + private final boolean seedsEnabled; - // @implNote Access to this resource is managed by the {@link #leechesLock}. - private final Map blockRequestsByPeer; - private final Lock leechesLock; + private final TopLeechesStatsTracker leechesTracker; private final boolean leechesEnabled; private final ResponseStatsTracker responseTracker; - private final boolean responsesEnabled; + private final boolean responseEnabled; /** * @param enabled all stats are enabled when {@code true}, all stats are disabled otherwise @@ -57,51 +51,41 @@ public final class SyncStats { } SyncStats( - long _startBlock, + long startBlock, boolean averageEnabled, Collection showStatistics, int maxActivePeers) { this.start = System.currentTimeMillis(); - this.startBlock = _startBlock; + this.startBlock = startBlock; this.avgBlocksPerSec = 0; this.averageEnabled = averageEnabled; - requestsEnabled = showStatistics.contains(StatsType.REQUESTS); - if (requestsEnabled) { - requestsToPeers = new LRUMap<>(maxActivePeers); - requestsLock = new ReentrantLock(); + requestEnabled = showStatistics.contains(StatsType.REQUESTS); + if (requestEnabled) { + requestTracker = new RequestStatsTracker(maxActivePeers); } else { - requestsToPeers = null; - requestsLock = null; + requestTracker = null; } - seedEnabled = showStatistics.contains(StatsType.SEEDS); - if (seedEnabled) { - blocksByPeer = new LRUMap<>(maxActivePeers); - importedByPeer = new LRUMap<>(maxActivePeers); - storedByPeer = new LRUMap<>(maxActivePeers); - seedsLock = new ReentrantLock(); + seedsEnabled = showStatistics.contains(StatsType.SEEDS); + if (seedsEnabled) { + seedsTracker = new TopSeedsStatsTracker(maxActivePeers); } else { - blocksByPeer = null; - importedByPeer = null; - storedByPeer = null; - seedsLock = null; + seedsTracker = null; } leechesEnabled = showStatistics.contains(StatsType.LEECHES); if (leechesEnabled) { - blockRequestsByPeer = new LRUMap<>(maxActivePeers); - leechesLock = new ReentrantLock(); + leechesTracker = new TopLeechesStatsTracker(maxActivePeers); } else { - blockRequestsByPeer = null; - leechesLock = null; + leechesTracker = null; } - this.responsesEnabled = showStatistics.contains(StatsType.RESPONSES); - if (this.responsesEnabled) { - this.responseTracker = new ResponseStatsTracker(maxActivePeers); + responseEnabled = showStatistics.contains(StatsType.RESPONSES); + if (responseEnabled) { + responseTracker = new ResponseStatsTracker(maxActivePeers); } else { - this.responseTracker = null; + responseTracker = null; } } @@ -127,7 +111,7 @@ void update(long _blockNumber) { double getAvgBlocksPerSec() { blockAverageLock.lock(); try { - return this.avgBlocksPerSec; + return avgBlocksPerSec; } finally { blockAverageLock.unlock(); } @@ -140,30 +124,8 @@ void update(long _blockNumber) { * @param type the type of request added */ public void updateTotalRequestsToPeer(String nodeId, RequestType type) { - if (requestsEnabled) { - requestsLock.lock(); - try { - RequestCounter current = requestsToPeers.get(nodeId); - - if (current == null) { - current = new RequestCounter(type); - requestsToPeers.put(nodeId, current); - } else { - switch (type) { - case STATUS: - current.incStatus(); - break; - case HEADERS: - current.incHeaders(); - break; - case BODIES: - current.incBodies(); - break; - } - } - } finally { - requestsLock.unlock(); - } + if (requestEnabled) { + requestTracker.updateTotalRequestsToPeer(nodeId, type); } } @@ -174,158 +136,82 @@ public void updateTotalRequestsToPeer(String nodeId, RequestType type) { * @return a hash map in descending order containing peers with underlying percentage of * requests made by the node */ + @VisibleForTesting Map getPercentageOfRequestsToPeers() { - if (requestsEnabled) { - requestsLock.lock(); - - try { - Map percentageReq = new LinkedHashMap<>(); - - float totalReq = 0f; - - // if there are any values the total will be != 0 after this - for (RequestCounter rc : requestsToPeers.values()) { - totalReq += rc.getTotal(); - } - - // resources are locked so the requestsToPeers map is unchanged - // if we enter this loop the totalReq is not equal to 0 - for (Map.Entry entry : requestsToPeers.entrySet()) { - percentageReq.put(entry.getKey(), entry.getValue().getTotal() / totalReq); - } - - return percentageReq.entrySet().stream() - .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) - .collect( - Collectors.toMap( - Map.Entry::getKey, - Map.Entry::getValue, - (e1, e2) -> e2, - LinkedHashMap::new)); - } finally { - requestsLock.unlock(); - } + if (requestEnabled) { + return requestTracker.getPercentageOfRequestsToPeers(); } else { - return Collections.emptyMap(); - } - } - - /** - * Updates the total number of blocks received from each seed peer - * - * @param nodeId peer node display Id - * @param totalBlocks total number of blocks received - */ - public void updatePeerTotalBlocks(String nodeId, int totalBlocks) { - if (seedEnabled) { - seedsLock.lock(); - try { - if (blocksByPeer.putIfAbsent(nodeId, totalBlocks) != null) { - blocksByPeer.computeIfPresent(nodeId, (key, value) -> value + totalBlocks); - } - } finally { - seedsLock.unlock(); - } + return null; } } /** - * Obtains a map of seed peers ordered by the total number of imported blocks + * Returns a log stream containing statistics about the percentage of requests made to each peer + * with respect to the total number of requests made. * - * @return map of total imported blocks by peer and sorted in descending order + * @return log stream with requests statistical data */ - Map getTotalBlocksByPeer() { - if (seedEnabled) { - seedsLock.lock(); - try { - return blocksByPeer.entrySet().stream() - .filter(entry -> entry.getValue() > 0) - .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) - .collect( - Collectors.toMap( - Map.Entry::getKey, - Map.Entry::getValue, - (e1, e2) -> e2, - LinkedHashMap::new)); - } finally { - seedsLock.unlock(); - } + public String dumpRequestStats() { + if (requestEnabled) { + return requestTracker.dumpRequestStats(); } else { - return Collections.emptyMap(); + return ""; } } /** - * Updates the total number of blocks imported from each seed peer + * Updates the total number of blocks received/imported/stored from each seed peer * * @param nodeId peer node display Id - * @param importedBlocks total number of blocks imported + * @param blocks total number of blocks + * @param type type of the block: received, imported, stored */ - public void updatePeerImportedBlocks(String nodeId, int importedBlocks) { - if (seedEnabled) { - seedsLock.lock(); - try { - if (importedByPeer.putIfAbsent(nodeId, importedBlocks) != null) { - importedByPeer.computeIfPresent(nodeId, (key, value) -> value + importedBlocks); - } - } finally { - seedsLock.unlock(); - } + public void updatePeerBlocks(String nodeId, int blocks, BlockType type) { + if (seedsEnabled) { + seedsTracker.updatePeerBlocksByType(nodeId, blocks, type); } } /** - * Obtains the total number of blocks imported from the given seed peer + * Obtains a map of seed peers ordered by the total number of imported blocks * - * @return number of total imported blocks by peer + * @return map of total blocks receivedby peer and sorted in descending order */ - long getImportedBlocksByPeer(String _nodeId) { - if (seedEnabled) { - seedsLock.lock(); - try { - return this.importedByPeer.getOrDefault(_nodeId, 0); - } finally { - seedsLock.unlock(); - } + @VisibleForTesting + Map getReceivedBlocksByPeer() { + if (seedsEnabled) { + return seedsTracker.getReceivedBlocksByPeer(); } else { - return 0L; + return null; } } /** - * Updates the total number of blocks stored from each seed peer + * Obtains the total number of blocks received/imported/stored from the given seed peer * - * @param nodeId peer node display Id - * @param storedBlocks total number of blocks stored + * @return number of total blocks of given type by peer */ - public void updatePeerStoredBlocks(String nodeId, int storedBlocks) { - if (seedEnabled) { - seedsLock.lock(); - try { - if (storedByPeer.putIfAbsent(nodeId, storedBlocks) != null) { - storedByPeer.computeIfPresent(nodeId, (key, value) -> value + storedBlocks); - } - } finally { - seedsLock.unlock(); - } + @VisibleForTesting + long getBlocksByPeer(String nodeId, BlockType type) { + if (seedsEnabled) { + return seedsTracker.getBlocksByPeer(nodeId, type); + } else { + return 0L; } } /** - * Obtains the total number of blocks stored from the given seed peer + * Returns a log stream containing a list of peers ordered by the total number of blocks + * received from each peer used to determine who is providing the majority of blocks, i.e. top + * seeds. * - * @return number of total stored blocks by peer + * @return log stream with peers statistical data on seeds */ - long getStoredBlocksByPeer(String _nodeId) { - if (seedEnabled) { - seedsLock.lock(); - try { - return this.storedByPeer.getOrDefault(_nodeId, 0); - } finally { - seedsLock.unlock(); - } + public String dumpTopSeedsStats() { + if (seedsEnabled) { + return seedsTracker.dumpTopSeedsStats(); } else { - return 0L; + return ""; } } @@ -337,15 +223,7 @@ long getStoredBlocksByPeer(String _nodeId) { */ public void updateTotalBlockRequestsByPeer(String nodeId, int totalBlocks) { if (leechesEnabled) { - leechesLock.lock(); - try { - if (blockRequestsByPeer.putIfAbsent(nodeId, totalBlocks) != null) { - blockRequestsByPeer.computeIfPresent( - nodeId, (key, value) -> value + totalBlocks); - } - } finally { - leechesLock.unlock(); - } + leechesTracker.updateTotalBlockRequestsByPeer(nodeId, totalBlocks); } } @@ -354,65 +232,59 @@ public void updateTotalBlockRequestsByPeer(String nodeId, int totalBlocks) { * * @return map of total requested blocks by peer and sorted in descending order */ + @VisibleForTesting Map getTotalBlockRequestsByPeer() { if (leechesEnabled) { - leechesLock.lock(); - try { - return blockRequestsByPeer.entrySet().stream() - .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) - .collect( - Collectors.toMap( - Map.Entry::getKey, - Map.Entry::getValue, - (e1, e2) -> e2, - LinkedHashMap::new)); - } finally { - leechesLock.unlock(); - } + return leechesTracker.getTotalBlockRequestsByPeer(); } else { return Collections.emptyMap(); } } - public void updateStatusRequest(String displayId, long requestTime) { - if (responsesEnabled) { - responseTracker.updateStatusRequest(displayId, requestTime); - } - } - - public void updateHeadersRequest(String displayId, long requestTime) { - if (responsesEnabled) { - responseTracker.updateHeadersRequest(displayId, requestTime); - } - } - - public void updateBodiesRequest(String displayId, long requestTime) { - if (responsesEnabled) { - responseTracker.updateBodiesRequest(displayId, requestTime); - } - } - - public void updateStatusResponse(String displayId, long responseTime) { - if (responsesEnabled) { - responseTracker.updateStatusResponse(displayId, responseTime); + /** + * Obtain log stream containing a list of peers ordered by the total number of blocks requested + * by each peer used to determine who is requesting the majority of blocks, i.e. top leeches. + * + * @return log stream with peers statistical data on leeches + */ + public String dumpTopLeechesStats() { + if (leechesEnabled) { + return leechesTracker.dumpTopLeechesStats(); + } else { + return ""; } } - public void updateHeadersResponse(String displayId, long responseTime) { - if (responsesEnabled) { - responseTracker.updateHeadersResponse(displayId, responseTime); + /** + * Log the time of a request sent to a peer. + * + * @param displayId peer display identifier + * @param requestTime time when the request was sent in nanoseconds + * @param requestType type of request + */ + public void updateRequestTime(String displayId, long requestTime, RequestType requestType) { + if (responseEnabled) { + responseTracker.updateRequestTime(displayId, requestTime, requestType); } } - public void updateBodiesResponse(String displayId, long responseTime) { - if (responsesEnabled) { - responseTracker.updateBodiesResponse(displayId, responseTime); + /** + * Log the time of a response received from a peer and update the computed average time and + * number of data points. + * + * @param displayId peer display identifier + * @param responseTime time when the response was received in nanoseconds * @param requestType + * @param requestType type of request + */ + public void updateResponseTime(String displayId, long responseTime, RequestType requestType) { + if (responseEnabled) { + responseTracker.updateResponseTime(displayId, responseTime, requestType); } } @VisibleForTesting Map>> getResponseStats() { - if (responsesEnabled) { + if (responseEnabled) { return responseTracker.getResponseStats(); } else { return null; @@ -426,7 +298,7 @@ Map>> getResponseStats() { * @return log stream with requests statistical data */ public String dumpResponseStats() { - if (responsesEnabled) { + if (responseEnabled) { return responseTracker.dumpResponseStats(); } else { return ""; diff --git a/modAionImpl/src/org/aion/zero/impl/sync/TaskDropImportedBlocks.java b/modAionImpl/src/org/aion/zero/impl/sync/TaskDropImportedBlocks.java index daf9780b22..1b233e2975 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/TaskDropImportedBlocks.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/TaskDropImportedBlocks.java @@ -3,7 +3,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; import org.aion.zero.impl.AionBlockchainImpl; import org.aion.zero.impl.types.AionBlock; import org.slf4j.Logger; diff --git a/modAionImpl/src/org/aion/zero/impl/sync/TaskFastImportBlocks.java b/modAionImpl/src/org/aion/zero/impl/sync/TaskFastImportBlocks.java new file mode 100644 index 0000000000..9b8278c5c9 --- /dev/null +++ b/modAionImpl/src/org/aion/zero/impl/sync/TaskFastImportBlocks.java @@ -0,0 +1,161 @@ +package org.aion.zero.impl.sync; + +import java.util.List; +import java.util.stream.Collectors; +import org.aion.mcf.core.FastImportResult; +import org.aion.types.ByteArrayWrapper; +import org.aion.zero.impl.AionBlockchainImpl; +import org.aion.zero.impl.SystemExitCodes; +import org.aion.zero.impl.types.AionBlock; +import org.apache.commons.lang3.tuple.Pair; +import org.slf4j.Logger; + +/** + * Task for importing blocks into the repository when running fast sync. The blocks are processed + * different from {@link TaskImportBlocks} because fewer consensus validations are applied when + * running fast sync. Also, the blocks are imported in reverse order starting from the oldest + * ancestor back to the first block. + * + * @author Alexandra Roatis + */ +final class TaskFastImportBlocks implements Runnable { + + private final AionBlockchainImpl chain; + private final FastSyncManager fastSyncMgr; + private long requiredLevel; + private ByteArrayWrapper requiredHash; + private final Logger log; + + TaskFastImportBlocks( + final AionBlockchainImpl chain, final FastSyncManager fastSyncMgr, final Logger log) { + this.chain = chain; + this.fastSyncMgr = fastSyncMgr; + this.log = log; + this.requiredLevel = 0; + this.requiredHash = null; + } + + @Override + public void run() { + // TODO: determine correct priority when full fast sync is added + Thread.currentThread().setPriority(Thread.NORM_PRIORITY); + while (!fastSyncMgr.isComplete()) { + if (fastSyncMgr.isCompleteBlockData()) { + // the block data is complete, but fast sync may still fail and reset pivot + requiredLevel = 0; + requiredHash = null; + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + if (!fastSyncMgr.isComplete()) { + log.error( + "Fast import blocks thread interrupted without shutdown request.", + e); + } + return; + } + } else { + if (requiredLevel == 0 || requiredHash == null) { + AionBlock pivot = fastSyncMgr.getPivot(); + if (pivot != null) { + requiredLevel = pivot.getNumber(); + requiredHash = pivot.getHashWrapper(); + } else { + // wait for pivot to be set + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + if (!fastSyncMgr.isComplete()) { + log.error( + "Fast import blocks thread interrupted without shutdown request.", + e); + } + return; + } + } + } else { + BlocksWrapper bw = fastSyncMgr.takeFilteredBlocks(requiredHash, requiredLevel); + if (bw == null) { + continue; + } + + // filter blocks just in case they don't start at the correct place + List batch = + bw.getBlocks().stream() + .filter(b -> b.getNumber() <= requiredLevel) + .collect(Collectors.toList()); // TODO: probably remove + + // process batch and update the peer state + FastImportResult importResult; + AionBlock lastImported = null; + + for (AionBlock b : batch) { + if (b.getNumber() > requiredLevel) { + continue; + } + try { + long t1 = System.currentTimeMillis(); + importResult = this.chain.tryFastImport(b); + long t2 = System.currentTimeMillis(); + if (log.isInfoEnabled()) { + log.info( + "", + bw.getDisplayId(), + b.getShortHash(), + b.getNumber(), + b.getTransactionsList().size(), + importResult, + t2 - t1); + } + + if (importResult.isSuccessful()) { + lastImported = b; + fastSyncMgr.addToImportedBlocks(b.getHashWrapper()); + } else if (importResult.isKnown()) { + lastImported = null; // to not update required incorrectly below + + Pair pair = chain.findMissingAncestor(b); + + if (pair != null) { + requiredLevel = pair.getRight(); + requiredHash = pair.getLeft(); + // check the last one in the batch + if (batch.get(batch.size() - 1).getNumber() > requiredLevel) { + break; // no need to continue importing + } else { + continue; + } + } else { + // might be complete, exit current loop + break; + } + } + } catch (Exception e) { + log.error(" ", e); + + if (e.getMessage() != null + && e.getMessage().contains("No space left on device")) { + log.error("Shutdown due to lack of disk space.", e); + System.exit(SystemExitCodes.OUT_OF_DISK_SPACE); + } + break; + } + } + + // update the required hash + if (lastImported != null) { + requiredLevel = lastImported.getNumber() - 1; + requiredHash = lastImported.getParentHashWrapper(); + } + } + } + } + + if (log.isDebugEnabled()) { + log.debug( + "Thread [" + + Thread.currentThread().getName() + + "] performing fast sync block imports was shutdown."); + } + } +} diff --git a/modAionImpl/src/org/aion/zero/impl/sync/TaskGetBodies.java b/modAionImpl/src/org/aion/zero/impl/sync/TaskGetBodies.java index 911a13512e..75e7926503 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/TaskGetBodies.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/TaskGetBodies.java @@ -9,6 +9,7 @@ import org.aion.p2p.IP2pMgr; import org.aion.zero.impl.sync.PeerState.State; import org.aion.zero.impl.sync.msg.ReqBlocksBodies; +import org.aion.zero.impl.sync.statistics.RequestType; import org.aion.zero.types.A0BlockHeader; import org.slf4j.Logger; @@ -87,7 +88,7 @@ public void run() { new ReqBlocksBodies( headers.stream().map(k -> k.getHash()).collect(Collectors.toList()))); stats.updateTotalRequestsToPeer(displayId, RequestType.BODIES); - stats.updateBodiesRequest(displayId, System.nanoTime()); + stats.updateRequestTime(displayId, System.nanoTime(), RequestType.BODIES); headersWithBodiesRequested.put(idHash, hw); diff --git a/modAionImpl/src/org/aion/zero/impl/sync/TaskGetHeaders.java b/modAionImpl/src/org/aion/zero/impl/sync/TaskGetHeaders.java index b19c81d542..a0c72d211d 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/TaskGetHeaders.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/TaskGetHeaders.java @@ -17,6 +17,7 @@ import org.aion.p2p.INode; import org.aion.p2p.IP2pMgr; import org.aion.zero.impl.sync.msg.ReqBlocksHeaders; +import org.aion.zero.impl.sync.statistics.RequestType; import org.slf4j.Logger; /** @author chris */ @@ -172,7 +173,7 @@ public void run() { ReqBlocksHeaders rbh = new ReqBlocksHeaders(from, size); this.p2p.send(node.getIdHash(), node.getIdShort(), rbh); stats.updateTotalRequestsToPeer(node.getIdShort(), RequestType.STATUS); - stats.updateHeadersRequest(node.getIdShort(), System.nanoTime()); + stats.updateRequestTime(node.getIdShort(), System.nanoTime(), RequestType.HEADERS); // update timestamp state.setLastHeaderRequest(now); diff --git a/modAionImpl/src/org/aion/zero/impl/sync/TaskGetStatus.java b/modAionImpl/src/org/aion/zero/impl/sync/TaskGetStatus.java index 22f3cc0685..573e5c9a40 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/TaskGetStatus.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/TaskGetStatus.java @@ -4,6 +4,7 @@ import org.aion.p2p.INode; import org.aion.p2p.IP2pMgr; import org.aion.zero.impl.sync.msg.ReqStatus; +import org.aion.zero.impl.sync.statistics.RequestType; import org.slf4j.Logger; /** @author chris long run */ @@ -46,7 +47,8 @@ public void run() { // System.out.println("requesting-status from-node=" + n.getIdShort()); p2p.send(node.getIdHash(), node.getIdShort(), reqStatus); stats.updateTotalRequestsToPeer(node.getIdShort(), RequestType.STATUS); - stats.updateStatusRequest(node.getIdShort(), System.nanoTime()); + stats.updateRequestTime( + node.getIdShort(), System.nanoTime(), RequestType.STATUS); } Thread.sleep(interval); } catch (Exception e) { diff --git a/modAionImpl/src/org/aion/zero/impl/sync/TaskImportBlocks.java b/modAionImpl/src/org/aion/zero/impl/sync/TaskImportBlocks.java index 72a7e4af22..74c55aac8f 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/TaskImportBlocks.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/TaskImportBlocks.java @@ -3,7 +3,6 @@ import static org.aion.p2p.P2pConstant.COEFFICIENT_NORMAL_PEERS; import static org.aion.p2p.P2pConstant.LARGE_REQUEST_SIZE; import static org.aion.p2p.P2pConstant.MAX_NORMAL_PEERS; -import static org.aion.p2p.P2pConstant.MIN_NORMAL_PEERS; import static org.aion.zero.impl.sync.PeerState.Mode.BACKWARD; import static org.aion.zero.impl.sync.PeerState.Mode.FORWARD; import static org.aion.zero.impl.sync.PeerState.Mode.LIGHTNING; @@ -23,12 +22,13 @@ import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; -import org.aion.base.util.ByteArrayWrapper; import org.aion.mcf.core.ImportResult; import org.aion.p2p.P2pConstant; +import org.aion.types.ByteArrayWrapper; import org.aion.zero.impl.AionBlockchainImpl; import org.aion.zero.impl.db.AionBlockStore; import org.aion.zero.impl.sync.PeerState.Mode; +import org.aion.zero.impl.sync.statistics.BlockType; import org.aion.zero.impl.types.AionBlock; import org.slf4j.Logger; @@ -257,7 +257,7 @@ private PeerState processBatch(PeerState givenState, List batch, Stri if (importResult.isStored()) { importedBlockHashes.put(ByteArrayWrapper.wrap(b.getHash()), true); - this.syncStats.updatePeerImportedBlocks(displayId, 1); + this.syncStats.updatePeerBlocks(displayId, 1, BlockType.IMPORTED); if (last <= b.getNumber()) { last = b.getNumber() + 1; @@ -280,7 +280,8 @@ private PeerState processBatch(PeerState givenState, List batch, Stri // if any block results in NO_PARENT, all subsequent blocks will too if (importResult == ImportResult.NO_PARENT) { - executors.submit(new TaskStorePendingBlocks(chain, batch, displayId, syncStats, log)); + executors.submit( + new TaskStorePendingBlocks(chain, batch, displayId, syncStats, log)); if (log.isDebugEnabled()) { log.debug( @@ -313,13 +314,9 @@ private PeerState processBatch(PeerState givenState, List batch, Stri } case NORMAL: { - // requiring a minimum number of normal states - if (countStates(getBestBlockNumber(), NORMAL, peerStates.values()) - > MIN_NORMAL_PEERS) { - // switch to backward mode - state.setMode(BACKWARD); - state.setBase(b.getNumber()); - } + // switch to backward mode + state.setMode(BACKWARD); + state.setBase(b.getNumber()); break; } case BACKWARD: @@ -455,12 +452,10 @@ static PeerState attemptLightningJump( countStates(best, NORMAL, states) + countStates(best, THUNDER, states); long fastStates = countStates(best, LIGHTNING, states); - // requiring a minimum number of normal states - if (normalStates > MIN_NORMAL_PEERS - // the fast vs normal states balance depends on the give coefficient - && (fastStates < COEFFICIENT_NORMAL_PEERS * normalStates - // with a maximum number of normal states - || normalStates > MAX_NORMAL_PEERS)) { + // the fast vs normal states balance depends on the give coefficient + if (fastStates < COEFFICIENT_NORMAL_PEERS * normalStates + // with a maximum number of normal states + || normalStates > MAX_NORMAL_PEERS) { // select the base to be used long nextBase = selectBase(best, state.getLastBestBlock(), baseSet, chain); @@ -581,7 +576,7 @@ private ImportResult importBlock(AionBlock b, String displayId, PeerState state) log.info("Compacting state database due to slow IO time."); } t1 = System.currentTimeMillis(); - //this.chain.compactState(); + this.chain.compactState(); t2 = System.currentTimeMillis(); if (log.isInfoEnabled()) { log.info("Compacting state completed in {} ms.", t2 - t1); diff --git a/modAionImpl/src/org/aion/zero/impl/sync/TaskImportTrieData.java b/modAionImpl/src/org/aion/zero/impl/sync/TaskImportTrieData.java index e69530355b..f38e8685f9 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/TaskImportTrieData.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/TaskImportTrieData.java @@ -4,9 +4,9 @@ import java.util.Map.Entry; import java.util.concurrent.BlockingQueue; import java.util.stream.Collectors; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.Hex; +import org.aion.types.ByteArrayWrapper; import org.aion.mcf.trie.TrieNodeResult; +import org.aion.util.conversions.Hex; import org.aion.zero.impl.AionBlockchainImpl; import org.slf4j.Logger; diff --git a/modAionImpl/src/org/aion/zero/impl/sync/TaskShowStatus.java b/modAionImpl/src/org/aion/zero/impl/sync/TaskShowStatus.java index e2a2cf186f..5129af2444 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/TaskShowStatus.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/TaskShowStatus.java @@ -8,10 +8,10 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; -import org.aion.base.util.Hex; import org.aion.mcf.config.StatsType; import org.aion.p2p.INode; import org.aion.p2p.IP2pMgr; +import org.aion.util.conversions.Hex; import org.aion.zero.impl.AionBlockchainImpl; import org.aion.zero.impl.types.AionBlock; import org.slf4j.Logger; @@ -38,6 +38,7 @@ final class TaskShowStatus implements Runnable { private final IP2pMgr p2p; private final Map peerStates; + private final Set showStatistics; TaskShowStatus( @@ -64,7 +65,7 @@ final class TaskShowStatus implements Runnable { @Override public void run() { Thread.currentThread().setPriority(Thread.MIN_PRIORITY); - String requestedInfo; + String requestedStats; while (this.start.get()) { @@ -72,37 +73,37 @@ public void run() { p2pLOG.info(status); if (showStatistics.contains(StatsType.PEER_STATES)) { - requestedInfo = dumpPeerStateInfo(p2p.getActiveNodes().values()); - if (!requestedInfo.isEmpty()) { - p2pLOG.info(requestedInfo); + requestedStats = dumpPeerStateInfo(p2p.getActiveNodes().values()); + if (!requestedStats.isEmpty()) { + p2pLOG.info(requestedStats); } } if (showStatistics.contains(StatsType.REQUESTS)) { - requestedInfo = dumpRequestsInfo(); - if (!requestedInfo.isEmpty()) { - p2pLOG.info(requestedInfo); + requestedStats = stats.dumpRequestStats(); + if (!requestedStats.isEmpty()) { + p2pLOG.info(requestedStats); } } if (showStatistics.contains(StatsType.SEEDS)) { - requestedInfo = dumpTopSeedsInfo(); - if (!requestedInfo.isEmpty()) { - p2pLOG.info(requestedInfo); + requestedStats = stats.dumpTopSeedsStats(); + if (!requestedStats.isEmpty()) { + p2pLOG.info(requestedStats); } } if (showStatistics.contains(StatsType.LEECHES)) { - requestedInfo = dumpTopLeechesInfo(); - if (!requestedInfo.isEmpty()) { - p2pLOG.info(requestedInfo); + requestedStats = stats.dumpTopLeechesStats(); + if (!requestedStats.isEmpty()) { + p2pLOG.info(requestedStats); } } if (showStatistics.contains(StatsType.RESPONSES)) { - requestedInfo = stats.dumpResponseStats(); - if (!requestedInfo.isEmpty()) { - p2pLOG.info(requestedInfo); + requestedStats = stats.dumpResponseStats(); + if (!requestedStats.isEmpty()) { + p2pLOG.info(requestedStats); } } @@ -121,25 +122,25 @@ public void run() { String status = getStatus(); p2pLOG.debug(status); - requestedInfo = dumpPeerStateInfo(p2p.getActiveNodes().values()); - if (!requestedInfo.isEmpty()) { - p2pLOG.debug(requestedInfo); + requestedStats = dumpPeerStateInfo(p2p.getActiveNodes().values()); + if (!requestedStats.isEmpty()) { + p2pLOG.debug(requestedStats); } - requestedInfo = dumpRequestsInfo(); - if (!requestedInfo.isEmpty()) { - p2pLOG.debug(requestedInfo); + requestedStats = stats.dumpRequestStats(); + if (!requestedStats.isEmpty()) { + p2pLOG.debug(requestedStats); } - requestedInfo = dumpTopSeedsInfo(); - if (!requestedInfo.isEmpty()) { - p2pLOG.debug(requestedInfo); + requestedStats = stats.dumpTopSeedsStats(); + if (!requestedStats.isEmpty()) { + p2pLOG.debug(requestedStats); } - requestedInfo = dumpTopLeechesInfo(); - if (!requestedInfo.isEmpty()) { - p2pLOG.debug(requestedInfo); + requestedStats = stats.dumpTopLeechesStats(); + if (!requestedStats.isEmpty()) { + p2pLOG.debug(requestedStats); } - requestedInfo = stats.dumpResponseStats(); - if (!requestedInfo.isEmpty()) { - p2pLOG.debug(requestedInfo); + requestedStats = stats.dumpResponseStats(); + if (!requestedStats.isEmpty()) { + p2pLOG.debug(requestedStats); } p2pLOG.debug("sync-ss shutdown"); @@ -169,94 +170,7 @@ private String getStatus() { + ""; } - /** - * Returns a log stream containing statistics about the percentage of requests made to each peer - * with respect to the total number of requests made. - * - * @return log stream with requests statistical data - */ - private String dumpRequestsInfo() { - Map reqToPeers = this.stats.getPercentageOfRequestsToPeers(); - - StringBuilder sb = new StringBuilder(); - - if (!reqToPeers.isEmpty()) { - - sb.append("\n====== sync-requests-to-peers ======\n"); - sb.append(String.format(" %9s %20s\n", "peer", "% requests")); - sb.append("------------------------------------\n"); - - reqToPeers.forEach( - (nodeId, percReq) -> - sb.append( - String.format( - " id:%6s %20s\n", - nodeId, String.format("%.2f", percReq * 100) + " %"))); - } - - return sb.toString(); - } - - /** - * Returns a log stream containing a list of peers ordered by the total number of blocks - * received from each peer used to determine who is providing the majority of blocks, i.e. top - * seeds. - * - * @return log stream with peers statistical data on seeds - */ - private String dumpTopSeedsInfo() { - Map totalBlocksByPeer = this.stats.getTotalBlocksByPeer(); - - StringBuilder sb = new StringBuilder(); - - if (!totalBlocksByPeer.isEmpty()) { - - sb.append( - "\n============================= sync-top-seeds ==============================\n"); - sb.append( - String.format( - " %9s %20s %19s %19s\n", - "peer", "total blocks", "imported blocks", "stored blocks")); - sb.append( - "---------------------------------------------------------------------------\n"); - totalBlocksByPeer.forEach( - (nodeId, totalBlocks) -> - sb.append( - String.format( - " id:%6s %20s %19s %19s\n", - nodeId, - totalBlocks, - this.stats.getImportedBlocksByPeer(nodeId), - this.stats.getStoredBlocksByPeer(nodeId)))); - } - - return sb.toString(); - } - - /** - * Obtain log stream containing a list of peers ordered by the total number of blocks requested - * by each peer used to determine who is requesting the majority of blocks, i.e. top leeches. - * - * @return log stream with peers statistical data on leeches - */ - private String dumpTopLeechesInfo() { - Map totalBlockReqByPeer = this.stats.getTotalBlockRequestsByPeer(); - - StringBuilder sb = new StringBuilder(); - if (!totalBlockReqByPeer.isEmpty()) { - - sb.append("\n========= sync-top-leeches =========\n"); - sb.append(String.format(" %9s %20s\n", "peer", "total blocks")); - sb.append("------------------------------------\n"); - - totalBlockReqByPeer.forEach( - (nodeId, totalBlocks) -> - sb.append(String.format(" id:%6s %20s\n", nodeId, totalBlocks))); - } - - return sb.toString(); - } private String dumpPeerStateInfo(Collection filtered) { List sorted = new ArrayList<>(); diff --git a/modAionImpl/src/org/aion/zero/impl/sync/TaskStorePendingBlocks.java b/modAionImpl/src/org/aion/zero/impl/sync/TaskStorePendingBlocks.java index 07342b2fa5..dc64b9c0cd 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/TaskStorePendingBlocks.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/TaskStorePendingBlocks.java @@ -2,6 +2,7 @@ import java.util.List; import org.aion.zero.impl.AionBlockchainImpl; +import org.aion.zero.impl.sync.statistics.BlockType; import org.aion.zero.impl.types.AionBlock; import org.slf4j.Logger; @@ -38,7 +39,7 @@ public void run() { Thread.currentThread().setName("sync-save:" + first.getNumber()); int stored = chain.storePendingBlockRange(batch); - this.syncStats.updatePeerStoredBlocks(displayId, stored); + this.syncStats.updatePeerBlocks(displayId, stored, BlockType.STORED); // log operation if (log.isDebugEnabled()) { diff --git a/modAionImpl/src/org/aion/zero/impl/sync/TaskValidateAndAddBlocks.java b/modAionImpl/src/org/aion/zero/impl/sync/TaskValidateAndAddBlocks.java new file mode 100644 index 0000000000..538553a2bb --- /dev/null +++ b/modAionImpl/src/org/aion/zero/impl/sync/TaskValidateAndAddBlocks.java @@ -0,0 +1,135 @@ +package org.aion.zero.impl.sync; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.BlockingQueue; +import org.aion.mcf.valid.BlockHeaderValidator; +import org.aion.types.ByteArrayWrapper; +import org.aion.util.bytes.ByteUtil; +import org.aion.zero.impl.sync.msg.ResponseBlocks; +import org.aion.zero.impl.types.AionBlock; +import org.aion.zero.types.A0BlockHeader; +import org.slf4j.Logger; + +/** + * Validates received blocks. If they follow the required rule set they are added to the queue for + * importing and the map of received hashes. + * + * @author Alexandra Roatis + */ +public class TaskValidateAndAddBlocks implements Runnable { + + private final int peerId; + private final String displayId; + private final ResponseBlocks response; + private final BlockHeaderValidator blockHeaderValidator; + private final BlockingQueue downloadedBlocks; + private final Map importedBlockHashes; + private final Map receivedBlockHashes; + private final Logger log; + + TaskValidateAndAddBlocks( + final int peerId, + final String displayId, + final ResponseBlocks response, + final BlockHeaderValidator blockHeaderValidator, + final BlockingQueue downloadedBlocks, + final Map importedBlockHashes, + final Map receivedBlockHashes, + final Logger log) { + this.peerId = peerId; + this.displayId = displayId; + this.response = response; + this.blockHeaderValidator = blockHeaderValidator; + this.downloadedBlocks = downloadedBlocks; + this.importedBlockHashes = importedBlockHashes; + this.receivedBlockHashes = receivedBlockHashes; + this.log = log; + } + + @Override + public void run() { + // TODO: re-evaluate priority when full functionality is implemented + Thread.currentThread().setPriority(Thread.NORM_PRIORITY); + AionBlock firstBlock = response.getBlocks().get(0); + Thread.currentThread().setName("check-" + displayId + "-" + firstBlock.getShortHash()); + + // log start of operation + if (log.isDebugEnabled()) { + log.debug( + "Starting block validation from peer={}, start-block={}, batch-size={}.", + displayId, + firstBlock.getShortHash(), + response.getBlocks().size()); + } + + List filtered = new ArrayList<>(); + List batchHashes = new ArrayList<>(); + + A0BlockHeader currentHeader, previousHeader = null; + for (AionBlock currentBlock : response.getBlocks()) { + ByteArrayWrapper hash = currentBlock.getHashWrapper(); + if (importedBlockHashes.containsKey(hash) // exclude imported + || receivedBlockHashes.containsKey(hash)) { // exclude known hashes + previousHeader = currentBlock.getHeader(); + continue; + } + currentHeader = currentBlock.getHeader(); + + // ignore batch if any invalidated header + // TODO: we could do partial evaluations here (as per fast sync specs) + if (!this.blockHeaderValidator.validate(currentHeader, log)) { + if (log.isDebugEnabled()) { + log.debug( + "", + currentHeader.getNumber(), + currentHeader.getHash(), + displayId, + peerId); + } + if (log.isTraceEnabled()) { + log.debug("", currentHeader.toString()); + } + return; + } + + // ignore batch if not ordered correctly + if (previousHeader != null + && (currentHeader.getNumber() != (previousHeader.getNumber() - 1) + || !Arrays.equals( + previousHeader.getParentHash(), currentHeader.getHash()))) { + log.debug( + "", + currentHeader.getNumber(), + previousHeader.getNumber() - 1, + ByteUtil.toHexString(previousHeader.getParentHash()), + ByteUtil.toHexString(currentHeader.getHash()), + displayId, + peerId); + return; + } + + filtered.add(currentBlock); + previousHeader = currentHeader; + batchHashes.add(hash); + } + + if (!filtered.isEmpty()) { + ByteArrayWrapper first = batchHashes.get(0); + downloadedBlocks.offer(new BlocksWrapper(peerId, displayId, filtered)); + batchHashes.forEach(k -> receivedBlockHashes.put(k, first)); + } + + // log end of operation + if (log.isDebugEnabled()) { + log.debug( + "Completed block validation from peer={}, start-block={}, batch-size={} with filtered-size={}.", + displayId, + firstBlock.getShortHash(), + response.getBlocks().size(), + filtered.size()); + } + } +} diff --git a/modAionImpl/src/org/aion/zero/impl/sync/TrieNodeWrapper.java b/modAionImpl/src/org/aion/zero/impl/sync/TrieNodeWrapper.java index f329334332..a342e74865 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/TrieNodeWrapper.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/TrieNodeWrapper.java @@ -2,7 +2,7 @@ import java.util.Map; import java.util.Objects; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; import org.aion.zero.impl.sync.msg.ResponseTrieData; /** diff --git a/modAionImpl/src/org/aion/zero/impl/sync/handler/BlockPropagationHandler.java b/modAionImpl/src/org/aion/zero/impl/sync/handler/BlockPropagationHandler.java index 60d68763d1..2816af32e3 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/handler/BlockPropagationHandler.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/handler/BlockPropagationHandler.java @@ -3,7 +3,7 @@ import java.math.BigInteger; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.aion.mcf.blockchain.IPendingStateInternal; @@ -15,6 +15,7 @@ import org.aion.zero.impl.sync.SyncStats; import org.aion.zero.impl.sync.msg.BroadcastNewBlock; import org.aion.zero.impl.sync.msg.ResStatus; +import org.aion.zero.impl.sync.statistics.BlockType; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.types.A0BlockHeader; import org.apache.commons.collections4.map.LRUMap; @@ -118,7 +119,7 @@ public void propagateNewBlock(final AionBlock block) { } public PropStatus processIncomingBlock( - final int nodeId, final String _displayId, final AionBlock block) { + final int nodeId, final String displayId, final AionBlock block) { if (block == null) return PropStatus.DROPPED; ByteArrayWrapper hashWrapped = new ByteArrayWrapper(block.getHash()); @@ -146,7 +147,7 @@ public PropStatus processIncomingBlock( if (log.isInfoEnabled()) { log.info( "", - _displayId, + displayId, block.getShortHash(), block.getNumber(), block.getTransactionsList().size(), @@ -154,7 +155,7 @@ public PropStatus processIncomingBlock( } else if (log.isDebugEnabled()) { log.debug( "", - _displayId, + displayId, block.getShortHash(), block.getNumber(), block.getTransactionsList().size(), @@ -163,8 +164,7 @@ public PropStatus processIncomingBlock( } boolean stored = blockchain.storePendingStatusBlock(block); if (stored) { - this.syncStats.updatePeerStoredBlocks(_displayId, 1); - this.syncStats.updatePeerTotalBlocks(_displayId, 1); + this.syncStats.updatePeerBlocks(displayId, 1, BlockType.STORED); } if (log.isDebugEnabled()) { @@ -180,14 +180,13 @@ public PropStatus processIncomingBlock( long t2 = System.currentTimeMillis(); if (result.isStored()) { - this.syncStats.updatePeerImportedBlocks(_displayId, 1); - this.syncStats.updatePeerTotalBlocks(_displayId, 1); + this.syncStats.updatePeerBlocks(displayId, 1, BlockType.IMPORTED); } if (log.isInfoEnabled()) { log.info( "", - _displayId, + displayId, block.getShortHash(), block.getNumber(), block.getTransactionsList().size(), @@ -196,7 +195,7 @@ public PropStatus processIncomingBlock( } else if (log.isDebugEnabled()) { log.debug( "", - _displayId, + displayId, block.getShortHash(), block.getNumber(), block.getTransactionsList().size(), diff --git a/modAionImpl/src/org/aion/zero/impl/sync/handler/BroadcastNewBlockHandler.java b/modAionImpl/src/org/aion/zero/impl/sync/handler/BroadcastNewBlockHandler.java index 58a3fbb780..af7fbcc754 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/handler/BroadcastNewBlockHandler.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/handler/BroadcastNewBlockHandler.java @@ -1,10 +1,10 @@ package org.aion.zero.impl.sync.handler; -import org.aion.base.util.ByteUtil; import org.aion.p2p.Ctrl; import org.aion.p2p.Handler; import org.aion.p2p.IP2pMgr; import org.aion.p2p.Ver; +import org.aion.util.bytes.ByteUtil; import org.aion.zero.impl.sync.Act; import org.aion.zero.impl.sync.msg.BroadcastNewBlock; import org.aion.zero.impl.types.AionBlock; diff --git a/modAionImpl/src/org/aion/zero/impl/sync/handler/BroadcastTxHandler.java b/modAionImpl/src/org/aion/zero/impl/sync/handler/BroadcastTxHandler.java index f2ca37158d..1baa948bd7 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/handler/BroadcastTxHandler.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/handler/BroadcastTxHandler.java @@ -6,13 +6,13 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; +import org.aion.types.ByteArrayWrapper; import org.aion.mcf.blockchain.IPendingStateInternal; import org.aion.p2p.Ctrl; import org.aion.p2p.Handler; import org.aion.p2p.IP2pMgr; import org.aion.p2p.Ver; +import org.aion.util.bytes.ByteUtil; import org.aion.zero.impl.sync.Act; import org.aion.zero.impl.sync.msg.BroadcastTx; import org.aion.zero.impl.valid.TXValidator; diff --git a/modAionImpl/src/org/aion/zero/impl/sync/handler/ReqBlocksBodiesHandler.java b/modAionImpl/src/org/aion/zero/impl/sync/handler/ReqBlocksBodiesHandler.java index 14e0aeb775..4b5f4e60e4 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/handler/ReqBlocksBodiesHandler.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/handler/ReqBlocksBodiesHandler.java @@ -4,13 +4,13 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; +import org.aion.types.ByteArrayWrapper; import org.aion.p2p.Ctrl; import org.aion.p2p.Handler; import org.aion.p2p.IP2pMgr; import org.aion.p2p.P2pConstant; import org.aion.p2p.Ver; +import org.aion.util.bytes.ByteUtil; import org.aion.zero.impl.core.IAionBlockchain; import org.aion.zero.impl.sync.Act; import org.aion.zero.impl.sync.SyncMgr; diff --git a/modAionImpl/src/org/aion/zero/impl/sync/handler/RequestBlocksHandler.java b/modAionImpl/src/org/aion/zero/impl/sync/handler/RequestBlocksHandler.java new file mode 100644 index 0000000000..a83531c52f --- /dev/null +++ b/modAionImpl/src/org/aion/zero/impl/sync/handler/RequestBlocksHandler.java @@ -0,0 +1,152 @@ +package org.aion.zero.impl.sync.handler; + +import java.util.Arrays; +import java.util.List; +import org.aion.p2p.Ctrl; +import org.aion.p2p.Handler; +import org.aion.p2p.IP2pMgr; +import org.aion.p2p.V1Constants; +import org.aion.p2p.Ver; +import org.aion.util.conversions.Hex; +import org.aion.zero.impl.core.IAionBlockchain; +import org.aion.zero.impl.sync.Act; +import org.aion.zero.impl.sync.msg.RequestBlocks; +import org.aion.zero.impl.sync.msg.ResponseBlocks; +import org.aion.zero.impl.types.AionBlock; +import org.slf4j.Logger; + +/** + * Handler for block range requests from the network. + * + * @author Alexandra Roatis + */ +public final class RequestBlocksHandler extends Handler { + + private final Logger log; + + private final IAionBlockchain chain; + + private final IP2pMgr p2p; + + /** + * Constructor. + * + * @param log logger for reporting execution information + * @param chain the blockchain used by the application + * @param p2p peer manager used to submit messages + */ + public RequestBlocksHandler(final Logger log, final IAionBlockchain chain, final IP2pMgr p2p) { + super(Ver.V1, Ctrl.SYNC, Act.REQUEST_BLOCKS); + this.log = log; + this.chain = chain; + this.p2p = p2p; + } + + @Override + public void receive(int peerId, String displayId, final byte[] message) { + if (message == null || message.length == 0) { + this.log.debug("", displayId); + return; + } + + RequestBlocks request = RequestBlocks.decode(message); + + if (request != null) { + if (request.isNumber()) { + // process block requests by number + long start = request.getStartHeight(); + int count = + Math.min(request.getCount(), V1Constants.BLOCKS_REQUEST_MAXIMUM_BATCH_SIZE); + boolean descending = request.isDescending(); + + if (log.isDebugEnabled()) { + this.log.debug( + "", + start, + count, + descending ? "DESC" : "ASC"); + } + + List blockList = null; + try { + // retrieve blocks from block store depending on requested order + if (descending) { + blockList = chain.getBlocksByRange(start, start - count + 1); + } else { + blockList = chain.getBlocksByRange(start, start + count - 1); + } + } catch (Exception e) { + this.log.error("", e); + } + + if (blockList != null) { + // generate response with retrieved blocks + // TODO: check the message size and ensure that it fits predefined limits + ResponseBlocks response = new ResponseBlocks(blockList); + // reply to request + this.p2p.send(peerId, displayId, response); + } + } else { + // process block requests by hash + byte[] startHash = request.getStartHash(); + int count = + Math.min(request.getCount(), V1Constants.BLOCKS_REQUEST_MAXIMUM_BATCH_SIZE); + boolean descending = request.isDescending(); + + if (log.isDebugEnabled()) { + this.log.debug( + "", + Hex.toHexString(startHash), + count, + descending ? "DESC" : "ASC"); + } + + // check if block exists + AionBlock block = chain.getBlockByHash(startHash); + + if (block != null) { + long start = block.getNumber(); + List blockList = null; + try { + // retrieve blocks from block store depending on requested order + if (descending) { + blockList = chain.getBlocksByRange(start, start - count + 1); + } else { + blockList = chain.getBlocksByRange(start, start + count - 1); + } + } catch (Exception e) { + this.log.error("", e); + } + + if (blockList != null && blockList.contains(block)) { + // generate response with retrieved blocks + // TODO: check the message size and ensure that it fits predefined limits + ResponseBlocks response = new ResponseBlocks(blockList); + // reply to request + this.p2p.send(peerId, displayId, response); + } else { + // retrieving multiple blocks failed + // or the requested block was on a side chain + + // generate response with single block + ResponseBlocks response = new ResponseBlocks(List.of(block)); + // reply to request + this.p2p.send(peerId, displayId, response); + } + } + } + } else { + this.log.error( + "", + message.length, + displayId); + + if (log.isTraceEnabled()) { + this.log.trace( + "", + Arrays.toString(message), + displayId); + } + } + } +} diff --git a/modAionImpl/src/org/aion/zero/impl/sync/handler/RequestTrieDataHandler.java b/modAionImpl/src/org/aion/zero/impl/sync/handler/RequestTrieDataHandler.java index ccbc2b3567..f13fc97ef2 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/handler/RequestTrieDataHandler.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/handler/RequestTrieDataHandler.java @@ -5,7 +5,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.Map; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; import org.aion.p2p.Ctrl; import org.aion.p2p.Handler; import org.aion.p2p.IP2pMgr; @@ -102,13 +102,14 @@ public void receive(int peerId, String displayId, final byte[] message) { this.p2p.send(peerId, displayId, response); } } else { - this.log.error("", message.length, peerId); + this.log.error( + "", message.length, displayId); if (log.isTraceEnabled()) { this.log.trace( "", Arrays.toString(message), - peerId); + displayId); } } } diff --git a/modAionImpl/src/org/aion/zero/impl/sync/handler/ResBlocksBodiesHandler.java b/modAionImpl/src/org/aion/zero/impl/sync/handler/ResBlocksBodiesHandler.java index 028a3bf451..2ec6d8820e 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/handler/ResBlocksBodiesHandler.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/handler/ResBlocksBodiesHandler.java @@ -1,12 +1,14 @@ package org.aion.zero.impl.sync.handler; import java.util.List; -import org.aion.base.util.ByteUtil; import org.aion.p2p.Ctrl; import org.aion.p2p.Handler; import org.aion.p2p.IP2pMgr; import org.aion.p2p.Ver; +import org.aion.util.bytes.ByteUtil; import org.aion.zero.impl.sync.Act; +import org.aion.zero.impl.sync.statistics.BlockType; +import org.aion.zero.impl.sync.statistics.RequestType; import org.aion.zero.impl.sync.SyncMgr; import org.aion.zero.impl.sync.msg.ResBlocksBodies; import org.slf4j.Logger; @@ -44,13 +46,15 @@ public void receive(int _nodeIdHashcode, String _displayId, final byte[] _msgByt } } else { - this.syncMgr.getSyncStats().updateBodiesResponse(_displayId, System.nanoTime()); + this.syncMgr + .getSyncStats() + .updateResponseTime(_displayId, System.nanoTime(), RequestType.BODIES); if (bodies.isEmpty()) { p2pMgr.errCheck(_nodeIdHashcode, _displayId); log.error("", _displayId); } else { - syncMgr.getSyncStats().updatePeerTotalBlocks(_displayId, bodies.size()); + syncMgr.getSyncStats().updatePeerBlocks(_displayId, bodies.size(), BlockType.RECEIVED); syncMgr.validateAndAddBlocks(_nodeIdHashcode, _displayId, bodies); } } diff --git a/modAionImpl/src/org/aion/zero/impl/sync/handler/ResBlocksHeadersHandler.java b/modAionImpl/src/org/aion/zero/impl/sync/handler/ResBlocksHeadersHandler.java index 8301153cb5..0957d84be7 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/handler/ResBlocksHeadersHandler.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/handler/ResBlocksHeadersHandler.java @@ -1,12 +1,13 @@ package org.aion.zero.impl.sync.handler; import java.util.List; -import org.aion.base.util.ByteUtil; import org.aion.p2p.Ctrl; import org.aion.p2p.Handler; import org.aion.p2p.IP2pMgr; import org.aion.p2p.Ver; +import org.aion.util.bytes.ByteUtil; import org.aion.zero.impl.sync.Act; +import org.aion.zero.impl.sync.statistics.RequestType; import org.aion.zero.impl.sync.SyncMgr; import org.aion.zero.impl.sync.msg.ResBlocksHeaders; import org.aion.zero.types.A0BlockHeader; @@ -35,7 +36,9 @@ public void receive(int _nodeIdHashcode, String _displayId, final byte[] _msgByt ResBlocksHeaders resHeaders = ResBlocksHeaders.decode(_msgBytes); if (resHeaders != null) { - this.syncMgr.getSyncStats().updateHeadersResponse(_displayId, System.nanoTime()); + this.syncMgr + .getSyncStats() + .updateResponseTime(_displayId, System.nanoTime(), RequestType.HEADERS); List headers = resHeaders.getHeaders(); if (headers != null && headers.size() > 0) { diff --git a/modAionImpl/src/org/aion/zero/impl/sync/handler/ResStatusHandler.java b/modAionImpl/src/org/aion/zero/impl/sync/handler/ResStatusHandler.java index 1f32edf4c1..5a64955b49 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/handler/ResStatusHandler.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/handler/ResStatusHandler.java @@ -1,13 +1,15 @@ package org.aion.zero.impl.sync.handler; import java.math.BigInteger; -import org.aion.base.util.ByteUtil; import org.aion.p2p.Ctrl; import org.aion.p2p.Handler; import org.aion.p2p.INode; import org.aion.p2p.IP2pMgr; import org.aion.p2p.Ver; +import org.aion.util.bytes.ByteUtil; import org.aion.zero.impl.sync.Act; +import org.aion.zero.impl.sync.statistics.BlockType; +import org.aion.zero.impl.sync.statistics.RequestType; import org.aion.zero.impl.sync.SyncMgr; import org.aion.zero.impl.sync.msg.ResStatus; import org.slf4j.Logger; @@ -41,8 +43,10 @@ public void receive(int _nodeIdHashcode, String _displayId, final byte[] _msgByt } } - this.syncMgr.getSyncStats().updateStatusResponse(_displayId, System.nanoTime()); - this.syncMgr.getSyncStats().updatePeerTotalBlocks(_displayId, 1); + this.syncMgr + .getSyncStats() + .updateResponseTime(_displayId, System.nanoTime(), RequestType.STATUS); + this.syncMgr.getSyncStats().updatePeerBlocks(_displayId, 1, BlockType.RECEIVED); INode node = this.p2pMgr.getActiveNodes().get(_nodeIdHashcode); if (node != null && rs != null) { diff --git a/modAionImpl/src/org/aion/zero/impl/sync/handler/ResponseBlocksHandler.java b/modAionImpl/src/org/aion/zero/impl/sync/handler/ResponseBlocksHandler.java new file mode 100644 index 0000000000..edd9d898a5 --- /dev/null +++ b/modAionImpl/src/org/aion/zero/impl/sync/handler/ResponseBlocksHandler.java @@ -0,0 +1,73 @@ +package org.aion.zero.impl.sync.handler; + +import java.util.Arrays; +import org.aion.p2p.Ctrl; +import org.aion.p2p.Handler; +import org.aion.p2p.IP2pMgr; +import org.aion.p2p.Ver; +import org.aion.zero.impl.sync.Act; +import org.aion.zero.impl.sync.FastSyncManager; +import org.aion.zero.impl.sync.msg.ResponseBlocks; +import org.slf4j.Logger; + +/** + * Handler for block range responses from the network. + * + * @author Alexandra Roatis + */ +public final class ResponseBlocksHandler extends Handler { + + private final Logger log; + + private final FastSyncManager fastSyncMgr; + + private final IP2pMgr p2pMgr; + + /** + * Constructor. + * + * @param log logger for reporting execution information + * @param fastSyncMgr sync manager that can validate blocks and pass them further for importing + * @param p2pMgr p2p manager that can check for errors with the peer identifiers + */ + public ResponseBlocksHandler( + final Logger log, final FastSyncManager fastSyncMgr, final IP2pMgr p2pMgr) { + super(Ver.V1, Ctrl.SYNC, Act.RESPONSE_BLOCKS); + this.log = log; + this.fastSyncMgr = fastSyncMgr; + this.p2pMgr = p2pMgr; + } + + @Override + public void receive(int peerId, String displayId, final byte[] message) { + if (message == null || message.length == 0) { + p2pMgr.errCheck(peerId, displayId); + log.debug("", displayId); + return; + } + + ResponseBlocks response = ResponseBlocks.decode(message); + + if (response != null) { + if (log.isDebugEnabled()) { + log.debug("", response, displayId); + } + + // checks PoW and adds correct blocks to import list + fastSyncMgr.validateAndAddBlocks(peerId, displayId, response); + } else { + p2pMgr.errCheck(peerId, displayId); + log.error( + "", + message.length, + displayId); + + if (log.isTraceEnabled()) { + log.trace( + "", + Arrays.toString(message), + displayId); + } + } + } +} diff --git a/modAionImpl/src/org/aion/zero/impl/sync/handler/ResponseTrieDataHandler.java b/modAionImpl/src/org/aion/zero/impl/sync/handler/ResponseTrieDataHandler.java index 45bc198aab..823d114f57 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/handler/ResponseTrieDataHandler.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/handler/ResponseTrieDataHandler.java @@ -49,13 +49,14 @@ public void receive(int peerId, String displayId, final byte[] message) { states.add(new TrieNodeWrapper(peerId, displayId, response)); } else { - this.log.error("", message.length, peerId); + this.log.error( + "", message.length, displayId); if (log.isTraceEnabled()) { this.log.trace( "", Arrays.toString(message), - peerId); + displayId); } } } diff --git a/modAionImpl/src/org/aion/zero/impl/sync/msg/BroadcastNewBlock.java b/modAionImpl/src/org/aion/zero/impl/sync/msg/BroadcastNewBlock.java index ca97001026..ceed7962f1 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/msg/BroadcastNewBlock.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/msg/BroadcastNewBlock.java @@ -1,6 +1,6 @@ package org.aion.zero.impl.sync.msg; -import org.aion.base.type.IBlock; +import org.aion.interfaces.block.Block; import org.aion.p2p.Ctrl; import org.aion.p2p.Msg; import org.aion.p2p.Ver; @@ -11,9 +11,9 @@ public final class BroadcastNewBlock extends Msg { @SuppressWarnings("rawtypes") - private final IBlock block; + private final Block block; - public BroadcastNewBlock(@SuppressWarnings("rawtypes") final IBlock __newblock) { + public BroadcastNewBlock(@SuppressWarnings("rawtypes") final Block __newblock) { super(Ver.V0, Ctrl.SYNC, Act.BROADCAST_BLOCK); this.block = __newblock; } diff --git a/modAionImpl/src/org/aion/zero/impl/sync/msg/BroadcastTx.java b/modAionImpl/src/org/aion/zero/impl/sync/msg/BroadcastTx.java index 48a04f68e8..d6b281db68 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/msg/BroadcastTx.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/msg/BroadcastTx.java @@ -2,7 +2,7 @@ import java.util.ArrayList; import java.util.List; -import org.aion.base.type.ITransaction; +import org.aion.interfaces.tx.Transaction; import org.aion.p2p.Ctrl; import org.aion.p2p.Msg; import org.aion.p2p.Ver; @@ -14,9 +14,9 @@ /** @author chris */ public final class BroadcastTx extends Msg { - private final List txl; + private final List txl; - public BroadcastTx(final List _txl) { + public BroadcastTx(final List _txl) { super(Ver.V0, Ctrl.SYNC, Act.BROADCAST_TX); this.txl = _txl; } @@ -27,7 +27,7 @@ public BroadcastTx(final List _txl) { @Override public byte[] encode() { List encodedTx = new ArrayList<>(); - for (ITransaction tx : txl) { + for (Transaction tx : txl) { encodedTx.add(tx.getEncoded()); } diff --git a/modAionImpl/src/org/aion/zero/impl/sync/msg/RequestBlocks.java b/modAionImpl/src/org/aion/zero/impl/sync/msg/RequestBlocks.java new file mode 100644 index 0000000000..b90519dd50 --- /dev/null +++ b/modAionImpl/src/org/aion/zero/impl/sync/msg/RequestBlocks.java @@ -0,0 +1,207 @@ +package org.aion.zero.impl.sync.msg; + +import static org.aion.p2p.V1Constants.HASH_SIZE; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Objects; +import org.aion.p2p.Ctrl; +import org.aion.p2p.Msg; +import org.aion.p2p.V1Constants; +import org.aion.p2p.Ver; +import org.aion.rlp.RLP; +import org.aion.rlp.RLPList; +import org.aion.zero.impl.sync.Act; + +/** + * Request message for a range of blocks. Allows making the request either by hash or by number. + * Also, the range can be requested in ascending or descending order. + * + * @author Alexandra Roatis + */ +public final class RequestBlocks extends Msg { + + private final Long startHeight; // using Long to be able to set it to null + private final byte[] startHash; + private final boolean isNumber; + private final int count; + private final boolean isDescending; + + /** + * Constructor for block range requests by height. + * + * @param startHeight the height of the first block in the requested range + * @param count the number of requested blocks in the range + * @param isDescending boolean value indicating the order of the blocks: + *
      + *
    • {@code true} indicates that parent blocks are requested (i.e. with descending + * heights); + *
    • {@code false} is used to request child blocks (i.e. with ascending heights); + *
    + */ + public RequestBlocks(final long startHeight, final int count, final boolean isDescending) { + super(Ver.V1, Ctrl.SYNC, Act.REQUEST_BLOCKS); + + this.startHeight = startHeight > 0 ? startHeight : 1L; // defaults to 1 when incorrect + this.isNumber = true; + this.startHash = null; + this.count = count > 0 ? count : 1; // defaults to 1 when given incorrect values + this.isDescending = isDescending; + } + + /** + * Constructor for block range requests by block hash. + * + * @param startHash the hash of the first block in the requested range + * @param count the number of requested blocks in the range + * @param isDescending boolean value indicating the order of the blocks: + *
      + *
    • {@code true} indicates that parent blocks are requested (i.e. with descending + * heights); + *
    • {@code false} is used to request child blocks (i.e. with ascending heights); + *
    + * + * @throws NullPointerException when the startHash parameter is null + * @throws IllegalArgumentException when the startHash parameter is not a hash (i.e. has the + * correct number of elements) + */ + public RequestBlocks(final byte[] startHash, final int count, final boolean isDescending) { + super(Ver.V1, Ctrl.SYNC, Act.REQUEST_BLOCKS); + + Objects.requireNonNull(startHash); + if (startHash.length != V1Constants.HASH_SIZE) { + throw new IllegalArgumentException( + "The given value " + + Arrays.toString(startHash) + + " is not a correct block hash."); + } + + this.startHeight = null; + this.isNumber = false; + this.startHash = startHash; + this.count = count > 0 ? count : 1; // defaults to 1 when given incorrect values + this.isDescending = isDescending; + } + + /** + * Decodes a message into a block range request. + * + * @param message a {@code byte} array representing a request for a trie node. + * @return the decoded trie node request if valid or {@code null} when the decoding encounters + * invalid input + * @implNote Ensures that the components are not {@code null}. + */ + public static RequestBlocks decode(final byte[] message) { + if (message == null || message.length == 0) { + return null; + } else { + RLPList list = RLP.decode2(message); + if (list.get(0) instanceof RLPList) { + list = (RLPList) list.get(0); + } else { + return null; + } + + if (list.size() != 4) { + return null; + } else { + // decode the requested type (number or hash) + byte value = new BigInteger(1, list.get(0).getRLPData()).byteValue(); + if (value < 0 || value > 1) { + return null; + } + boolean isNumber = value == 1; + + // decode the number of blocks requested + int count = new BigInteger(1, list.get(2).getRLPData()).intValue(); + if (count <= 0) { + return null; + } + + // decode the requested ordering of the block range + value = new BigInteger(1, list.get(3).getRLPData()).byteValue(); + if (value < 0 || value > 1) { + return null; + } + boolean descending = value == 1; + + if (isNumber) { + // decode the start block + long start = new BigInteger(1, list.get(1).getRLPData()).longValue(); + if (start <= 0) { + return null; + } + // number based request + return new RequestBlocks(start, count, descending); + } else { + byte[] start = list.get(1).getRLPData(); + if (start.length != HASH_SIZE) { + return null; + } + // hash based request + return new RequestBlocks(start, count, descending); + } + } + } + } + + @Override + public byte[] encode() { + return RLP.encodeList( + RLP.encodeByte(isNumber ? (byte) 1 : (byte) 0), + isNumber + ? RLP.encode(startHeight) // encodeLong has non-standard encoding + : RLP.encodeElement(startHash), + RLP.encodeInt(count), + RLP.encodeByte(isDescending ? (byte) 1 : (byte) 0)); + } + + public boolean isNumber() { + return isNumber; + } + + /** + * Returns the height of the first block in the requested range. + * + * @return the height of the first block in the requested range + * @implNote The height is set to {@code null} when the hash was used in creating the request. + * It should only be requested when {@link #isNumber()} is {@code true}. + */ + public Long getStartHeight() { + return startHeight; + } + + /** + * Returns the hash of the first block in the requested range. + * + * @return the hash of the first block in the requested range + * @implNote The hash is set to {@code null} when the height was used in creating the request. + * It should only be requested when {@link #isNumber()} is {@code false}. + */ + public byte[] getStartHash() { + return startHash; + } + + /** + * Returns the number of requested blocks in the range. + * + * @return the number of requested blocks in the range + */ + public int getCount() { + return count; + } + + /** + * Returns a boolean value indicating the order of the blocks defined as: + * + *
      + *
    • {@code true} indicates that parent blocks are requested (i.e. with descending heights); + *
    • {@code false} is used to request child blocks (i.e. with ascending heights); + *
    + * + * @return a boolean value indicating the order of the blocks + */ + public boolean isDescending() { + return isDescending; + } +} diff --git a/modAionImpl/src/org/aion/zero/impl/sync/msg/RequestTrieData.java b/modAionImpl/src/org/aion/zero/impl/sync/msg/RequestTrieData.java index a5f30d8bc2..d109566546 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/msg/RequestTrieData.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/msg/RequestTrieData.java @@ -7,9 +7,11 @@ import java.util.Objects; import org.aion.p2p.Ctrl; import org.aion.p2p.Msg; +import org.aion.p2p.V1Constants; import org.aion.p2p.Ver; import org.aion.rlp.RLP; import org.aion.rlp.RLPList; +import org.aion.util.conversions.Hex; import org.aion.zero.impl.sync.Act; import org.aion.zero.impl.sync.DatabaseType; @@ -31,7 +33,8 @@ public final class RequestTrieData extends Msg { * @param limit the maximum number of key-value pairs to be retrieved by the search inside the * trie for referenced nodes * @throws NullPointerException if either of the given parameters is {@code null} - * @throws IllegalArgumentException if the given limit is negative + * @throws IllegalArgumentException if the given limit is negative or the given node key is not + * a valid hash */ public RequestTrieData(final byte[] nodeKey, final DatabaseType dbType, final int limit) { super(Ver.V1, Ctrl.SYNC, Act.REQUEST_TRIE_DATA); @@ -46,6 +49,14 @@ public RequestTrieData(final byte[] nodeKey, final DatabaseType dbType, final in "The RequestTrieData object must be built with a positive limit."); } + // ensure hash has valid size + if (nodeKey.length != V1Constants.HASH_SIZE) { + throw new IllegalArgumentException( + "The given value " + + Hex.toHexString(nodeKey) + + " is not a correct block hash."); + } + this.nodeKey = nodeKey; this.dbType = dbType; this.limit = limit; @@ -63,7 +74,13 @@ public static RequestTrieData decode(final byte[] message) { if (message == null || message.length == 0) { return null; } else { - RLPList list = (RLPList) RLP.decode2(message).get(0); + RLPList list = RLP.decode2(message); + if (list.get(0) instanceof RLPList) { + list = (RLPList) list.get(0); + } else { + return null; + } + if (list.size() != TRIE_DATA_REQUEST_COMPONENTS) { return null; } else { diff --git a/modAionImpl/src/org/aion/zero/impl/sync/msg/ResponseBlocks.java b/modAionImpl/src/org/aion/zero/impl/sync/msg/ResponseBlocks.java new file mode 100644 index 0000000000..b0a21cb1bd --- /dev/null +++ b/modAionImpl/src/org/aion/zero/impl/sync/msg/ResponseBlocks.java @@ -0,0 +1,116 @@ +package org.aion.zero.impl.sync.msg; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import org.aion.p2p.Ctrl; +import org.aion.p2p.Msg; +import org.aion.p2p.Ver; +import org.aion.rlp.RLP; +import org.aion.rlp.RLPElement; +import org.aion.rlp.RLPList; +import org.aion.zero.impl.sync.Act; +import org.aion.zero.impl.types.AionBlock; + +/** + * Response message to a request for a block range. + * + * @author Alexandra Roatis + */ +public final class ResponseBlocks extends Msg { + + private final List blocks; + + /** + * Constructor for block range responses. + * + * @param blocks a list of blocks representing the response to a requested range + * @implNote The given blocks are purposefully not deep copied to minimize resource + * instantiation. This is a reasonable choice given that these objects are created to be + * encoded and transmitted over the network and therefore there is the expectation that they + * will not be utilized further. + */ + public ResponseBlocks(final List blocks) { + super(Ver.V1, Ctrl.SYNC, Act.RESPONSE_BLOCKS); + + // ensure input is not null + Objects.requireNonNull(blocks); + + this.blocks = blocks; + } + + /** + * Decodes a message into a block range response. + * + * @param message a {@code byte} array representing a response to a block range request. + * @return the decoded block range response + * @implNote The decoder returns {@code null} when given an empty message. + */ + public static ResponseBlocks decode(final byte[] message) { + if (message == null || message.length == 0) { + return null; + } else { + RLPList list = RLP.decode2(message); + if (list.get(0) instanceof RLPList) { + list = (RLPList) list.get(0); + } else { + return null; + } + + List blocks = new ArrayList<>(); + AionBlock current; + for (RLPElement encoded : list) { + try { // preventative try-catch: it's unlikely that exceptions can pass up to here + current = AionBlock.fromRLP(encoded.getRLPData(), true); + } catch (Exception e) { + return null; + } + if (current == null) { + return null; + } else { + blocks.add(current); + } + } + return new ResponseBlocks(blocks); + } + } + + @Override + public byte[] encode() { + byte[][] toEncode = new byte[this.blocks.size()][]; + + int i = 0; + for (AionBlock block : blocks) { + toEncode[i] = block.getEncoded(); + i++; + } + + return RLP.encodeList(toEncode); + } + + /** + * Returns the list of blocks representing the response to a requested block range. + * + * @return the list of blocks representing the response to a requested block range + */ + public List getBlocks() { + return blocks; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ResponseBlocks that = (ResponseBlocks) o; + return Objects.equals(blocks, that.blocks); + } + + @Override + public int hashCode() { + return Objects.hash(blocks); + } +} diff --git a/modAionImpl/src/org/aion/zero/impl/sync/msg/ResponseTrieData.java b/modAionImpl/src/org/aion/zero/impl/sync/msg/ResponseTrieData.java index 9009de4007..e001312614 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/msg/ResponseTrieData.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/msg/ResponseTrieData.java @@ -9,13 +9,13 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; -import org.aion.base.util.ByteArrayWrapper; import org.aion.p2p.Ctrl; import org.aion.p2p.Msg; import org.aion.p2p.Ver; import org.aion.rlp.RLP; import org.aion.rlp.RLPElement; import org.aion.rlp.RLPList; +import org.aion.types.ByteArrayWrapper; import org.aion.zero.impl.sync.Act; import org.aion.zero.impl.sync.DatabaseType; @@ -97,7 +97,13 @@ public static ResponseTrieData decode(final byte[] message) { if (message == null || message.length == 0) { return null; } else { - RLPList list = (RLPList) RLP.decode2(message).get(0); + RLPList list = RLP.decode2(message); + if (list.get(0) instanceof RLPList) { + list = (RLPList) list.get(0); + } else { + return null; + } + if (list.size() != TRIE_DATA_RESPONSE_COMPONENTS) { return null; } else { diff --git a/modAionImpl/src/org/aion/zero/impl/sync/statistics/BlockType.java b/modAionImpl/src/org/aion/zero/impl/sync/statistics/BlockType.java new file mode 100644 index 0000000000..b1d559215c --- /dev/null +++ b/modAionImpl/src/org/aion/zero/impl/sync/statistics/BlockType.java @@ -0,0 +1,10 @@ +package org.aion.zero.impl.sync.statistics; + +/** + * Used for tracking different types of TopSeedsStats. + */ +public enum BlockType { + RECEIVED, + IMPORTED, + STORED +} diff --git a/modAionImpl/src/org/aion/zero/impl/sync/RequestCounter.java b/modAionImpl/src/org/aion/zero/impl/sync/statistics/RequestCounter.java similarity index 56% rename from modAionImpl/src/org/aion/zero/impl/sync/RequestCounter.java rename to modAionImpl/src/org/aion/zero/impl/sync/statistics/RequestCounter.java index 1da0409c13..ba04ce2cf1 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/RequestCounter.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/statistics/RequestCounter.java @@ -1,4 +1,4 @@ -package org.aion.zero.impl.sync; +package org.aion.zero.impl.sync.statistics; /** * Used for tracking different types of requests made to peers. @@ -10,6 +10,9 @@ public class RequestCounter { private long status = 0; private long headers = 0; private long bodies = 0; + private long blocks = 0; + private long receipts = 0; + private long trieData = 0; private long total = 0; public RequestCounter(RequestType type) { @@ -23,6 +26,15 @@ public RequestCounter(RequestType type) { case BODIES: incBodies(); break; + case BLOCKS: + incBlocks(); + break; + case RECEIPTS: + incRecepts(); + break; + case TRIE_DATA: + incTrieData(); + break; } } @@ -38,6 +50,18 @@ public long getBodies() { return bodies; } + public long getBlocks() { + return blocks; + } + + public long getReceipts() { + return receipts; + } + + public long getTrieData() { + return trieData; + } + public long getTotal() { return total; } @@ -56,4 +80,19 @@ public void incBodies() { this.bodies++; this.total++; } + + public void incBlocks() { + this.blocks++; + this.total++; + } + + public void incRecepts() { + this.receipts++; + this.total++; + } + + public void incTrieData() { + this.trieData++; + this.total++; + } } diff --git a/modAionImpl/src/org/aion/zero/impl/sync/statistics/RequestStatsTracker.java b/modAionImpl/src/org/aion/zero/impl/sync/statistics/RequestStatsTracker.java new file mode 100644 index 0000000000..29d4f48d81 --- /dev/null +++ b/modAionImpl/src/org/aion/zero/impl/sync/statistics/RequestStatsTracker.java @@ -0,0 +1,125 @@ +package org.aion.zero.impl.sync.statistics; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; +import org.apache.commons.collections4.map.LRUMap; + +public class RequestStatsTracker { + + private final Map requestsToPeers; + private final Lock requestLock; + + public RequestStatsTracker(int maxActivePeers) { + this.requestsToPeers = new LRUMap<>(maxActivePeers); + this.requestLock = new ReentrantLock(); + } + + /** + * Updates the total requests made to a peer. + * + * @param nodeId peer node display id + * @param type the type of request added + */ + public void updateTotalRequestsToPeer(String nodeId, RequestType type) { + requestLock.lock(); + try { + RequestCounter current = requestsToPeers.get(nodeId); + + if (current == null) { + current = new RequestCounter(type); + requestsToPeers.put(nodeId, current); + } else { + switch (type) { + case STATUS: + current.incStatus(); + break; + case HEADERS: + current.incHeaders(); + break; + case BODIES: + current.incBodies(); + break; + case BLOCKS: + current.incBlocks(); + break; + case RECEIPTS: + current.incRecepts(); + break; + case TRIE_DATA: + current.incTrieData(); + break; + } + } + } finally { + requestLock.unlock(); + } + } + + /** + * Calculates the percentage of requests made to each peer with respect to the total number of + * requests made. + * + * @return a hash map in descending order containing peers with underlying percentage of + * requests made by the node + */ + public Map getPercentageOfRequestsToPeers() { + requestLock.lock(); + try { + Map percentageReq = new LinkedHashMap<>(); + float totalReq = 0f; + + // if there are any values the total will be != 0 after this + for (RequestCounter rc : requestsToPeers.values()) { + totalReq += rc.getTotal(); + } + // resources are locked so the requestsToPeers map is unchanged + // if we enter this loop the totalReq is not equal to 0 + for (Map.Entry entry : requestsToPeers.entrySet()) { + percentageReq.put(entry.getKey(), entry.getValue().getTotal() / totalReq); + } + + return percentageReq.entrySet().stream() + .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) + .collect( + Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (e1, e2) -> e2, + LinkedHashMap::new)); + } finally { + requestLock.unlock(); + } + } + + /** + * Returns a log stream containing statistics about the percentage of requests made to each peer + * with respect to the total number of requests made. + * + * @return log stream with requests statistical data + */ + public String dumpRequestStats() { + Map reqToPeers = this.getPercentageOfRequestsToPeers(); + + StringBuilder sb = new StringBuilder(); + + if (!reqToPeers.isEmpty()) { + + sb.append("\n====== sync-requests-to-peers ======\n"); + sb.append(String.format(" %9s %20s\n", "peer", "% requests")); + sb.append("------------------------------------\n"); + + reqToPeers.forEach( + (nodeId, percReq) -> + sb.append( + String.format( + " id:%6s %20s\n", + nodeId, String.format("%.2f", percReq * 100) + " %"))); + } + + return sb.toString(); + } +} diff --git a/modAionImpl/src/org/aion/zero/impl/sync/RequestType.java b/modAionImpl/src/org/aion/zero/impl/sync/statistics/RequestType.java similarity index 62% rename from modAionImpl/src/org/aion/zero/impl/sync/RequestType.java rename to modAionImpl/src/org/aion/zero/impl/sync/statistics/RequestType.java index 56da4cb6d6..b8abbd84d5 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/RequestType.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/statistics/RequestType.java @@ -1,4 +1,4 @@ -package org.aion.zero.impl.sync; +package org.aion.zero.impl.sync.statistics; /** * Used for tracking different types of requests made to peers. @@ -8,5 +8,8 @@ public enum RequestType { STATUS, HEADERS, - BODIES + BODIES, + BLOCKS, + RECEIPTS, + TRIE_DATA } diff --git a/modAionImpl/src/org/aion/zero/impl/sync/statistics/ResponseStatsTracker.java b/modAionImpl/src/org/aion/zero/impl/sync/statistics/ResponseStatsTracker.java index beaeb2f000..ee1123450e 100644 --- a/modAionImpl/src/org/aion/zero/impl/sync/statistics/ResponseStatsTracker.java +++ b/modAionImpl/src/org/aion/zero/impl/sync/statistics/ResponseStatsTracker.java @@ -1,7 +1,11 @@ package org.aion.zero.impl.sync.statistics; +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumMap; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.locks.Lock; @@ -17,157 +21,141 @@ * @author Beidou Zhang */ public class ResponseStatsTracker { - - // tracks status messages - private final ResponseStats status; - private final Lock lockStatus; - - // track headers messages - private final ResponseStats headers; - private final Lock lockHeaders; - - // track bodies messages - private final ResponseStats bodies; - private final Lock lockBodies; + // track status, headers and bodes messages + private final EnumMap stats = new EnumMap<>(RequestType.class); + private final EnumMap locks = new EnumMap<>(RequestType.class); public ResponseStatsTracker(int maxActivePeers) { - // instantiate objects for gathering stats - this.status = new ResponseStats(maxActivePeers); - this.headers = new ResponseStats(maxActivePeers); - this.bodies = new ResponseStats(maxActivePeers); + for (RequestType type : RequestType.values()) { + // instantiate objects for gathering stats + this.stats.put(type, new ResponseStats(maxActivePeers)); + // instantiate locks + this.locks.put(type, new ReentrantLock()); + } + } - // instantiate locks - this.lockStatus = new ReentrantLock(); - this.lockHeaders = new ReentrantLock(); - this.lockBodies = new ReentrantLock(); + public void updateRequestTime(String displayId, long requestTime, RequestType requestType) { + Lock responseLock = locks.get(requestType); + responseLock.lock(); + try { + stats.get(requestType).updateRequestTime(displayId, requestTime); + } finally { + responseLock.unlock(); + } + } + + public void updateResponseTime(String displayId, long responseTime, RequestType requestType) { + Lock responseLock = locks.get(requestType); + responseLock.lock(); + try { + stats.get(requestType).updateResponseTime(displayId, responseTime); + } finally { + responseLock.unlock(); + } } public Map>> getResponseStats() { - // acquire lock for all resources - lockBodies.lock(); - lockHeaders.lock(); - lockStatus.lock(); + // acquire lock for all resources, unlock in reverse order + List lockTypes = Arrays.asList(RequestType.values()); + lockTypes.forEach(type -> locks.get(type).lock()); try { - Map> statusStats = this.status.getResponseStatsByPeers(); - Map> headersStats = - this.headers.getResponseStatsByPeers(); - Map> bodiesStats = this.bodies.getResponseStatsByPeers(); + boolean empty = true; + EnumMap>> responseStats = + new EnumMap<>(RequestType.class); + EnumMap> overallStats = + new EnumMap<>(RequestType.class); + Set peers = new HashSet<>(); + + for (RequestType type : RequestType.values()) { + Map> stats = + this.stats.get(type).getResponseStatsByPeers(); + responseStats.put(type, stats); + + if (!stats.isEmpty()) { + peers.addAll(stats.keySet()); + empty = false; + } - // skip if there's nothing to show - if (statusStats.isEmpty() && headersStats.isEmpty() && bodiesStats.isEmpty()) { - return null; + // used to calculate overall stats + overallStats.put(type, Pair.of(0d, 0)); } - Map>> responseStats = new LinkedHashMap<>(); - - Pair statusOverall = Pair.of(0d, 0); - Pair headersOverall = Pair.of(0d, 0); - Pair bodiesOverall = Pair.of(0d, 0); + if (empty) return null; - // used in computing averages - int count; - - // making sure to grab all peers - Set peers = new HashSet<>(statusStats.keySet()); - peers.addAll(headersStats.keySet()); - peers.addAll(bodiesStats.keySet()); + Map>> processedStats = new LinkedHashMap<>(); + Pair statOverall; + int overallCount; for (String nodeId : peers) { - Map> peerStats = new LinkedHashMap<>(); - Pair status = statusStats.getOrDefault(nodeId, Pair.of(0d, 0)); - Pair headers = headersStats.getOrDefault(nodeId, Pair.of(0d, 0)); - Pair bodies = bodiesStats.getOrDefault(nodeId, Pair.of(0d, 0)); - - count = status.getRight() + headers.getRight() + bodies.getRight(); - Pair avgStats; - // ensuring there are entries - if (count > 0) { - avgStats = - Pair.of( - (status.getLeft() * status.getRight() - + headers.getLeft() * headers.getRight() - + bodies.getLeft() * bodies.getRight()) - / count, - count); - } else { - avgStats = Pair.of(0d, 0); + // used in computing averages for each peer + int count = 0; + Pair avgStats = Pair.of(0d, 0); // average for each peer + + for (RequestType type : RequestType.values()) { + Pair stat = + responseStats.get(type).getOrDefault(nodeId, Pair.of(0d, 0)); + + // add different types of stats to current peer + peerStats.put(type.toString().toLowerCase(), stat); + // calculate average stats for current peer + count += stat.getRight(); + if (count > 0) { + avgStats = + Pair.of( + (avgStats.getLeft() * avgStats.getRight() + + stat.getLeft() * stat.getRight()) + / count, + count); + } // do nothing if count is 0 + + // update overall stats for current request type + statOverall = overallStats.getOrDefault(type, Pair.of(0d, 0)); + overallCount = statOverall.getRight() + stat.getRight(); + if (overallCount > 0) { + overallStats.put( + type, + Pair.of( + (statOverall.getLeft() * statOverall.getRight() + + stat.getLeft() * stat.getRight()) + / overallCount, + overallCount)); + } // do nothing if count is 0 } - peerStats.put("all", avgStats); - peerStats.put("status", status); - peerStats.put("headers", headers); - peerStats.put("bodies", bodies); - responseStats.put(nodeId, peerStats); + processedStats.put(nodeId, peerStats); + } - // adding to overall status - count = statusOverall.getRight() + status.getRight(); - // ensuring there are entries - if (count > 0) { - statusOverall = - Pair.of( - (statusOverall.getLeft() * statusOverall.getRight() - + status.getLeft() * status.getRight()) - / count, - count); - } // nothing to do if count == 0 + Pair avgOverall = Pair.of(0d, 0); + overallCount = 0; + Map> overall = new LinkedHashMap<>(); - // adding to overall headers - count = headersOverall.getRight() + headers.getRight(); - // ensuring there are entries - if (count > 0) { - headersOverall = - Pair.of( - (headersOverall.getLeft() * headersOverall.getRight() - + headers.getLeft() * headers.getRight()) - / count, - count); - } // nothing to do if count == 0 + for (RequestType type : RequestType.values()) { + statOverall = overallStats.get(type); + overall.put(type.toString().toLowerCase(), statOverall); - // adding to overall headers - count = bodiesOverall.getRight() + bodies.getRight(); - // ensuring there are entries - if (count > 0) { - bodiesOverall = + // calculate overall average stats + overallCount += statOverall.getRight(); + if (overallCount > 0) { + avgOverall = Pair.of( - (bodiesOverall.getLeft() * bodiesOverall.getRight() - + bodies.getLeft() * bodies.getRight()) - / count, - count); - } // nothing to do if count == 0 - } - - count = statusOverall.getRight() + headersOverall.getRight() + bodiesOverall.getRight(); - Pair avgOverall; - // ensuring there are entries - if (count > 0) { - avgOverall = - Pair.of( - (statusOverall.getLeft() * statusOverall.getRight() - + headersOverall.getLeft() - * headersOverall.getRight() - + bodiesOverall.getLeft() - * bodiesOverall.getRight()) - / count, - count); - } else { - avgOverall = Pair.of(0d, 0); + (avgOverall.getLeft() * avgOverall.getRight() + + statOverall.getLeft() + * statOverall.getRight()) + / overallCount, + overallCount); + } } + overall.put("all", avgOverall); + processedStats.put("overall", overall); - Map> overallStats = new LinkedHashMap<>(); - overallStats.put("all", avgOverall); - overallStats.put("status", statusOverall); - overallStats.put("headers", headersOverall); - overallStats.put("bodies", bodiesOverall); - responseStats.put("overall", overallStats); + return processedStats; - return responseStats; } finally { - // unlock in reverse order - lockStatus.unlock(); - lockHeaders.unlock(); - lockBodies.unlock(); + // unlock all locks in reverse order + Collections.reverse(lockTypes); + lockTypes.forEach(type -> locks.get(type).unlock()); } } @@ -187,84 +175,51 @@ public String dumpResponseStats() { "----------------------------------------------------------------------------\n"); Map> peerStats = responseStats.get("overall"); + sb.append( + String.format( + " «overall» %20s %16s ms %19d\n", + "«all»", + String.format("%.0f", peerStats.get("all").getLeft() / 1_000_000), + peerStats.get("all").getRight())); for (String type : peerStats.keySet()) { - sb.append( - String.format( - " «overall» %20s %16s ms %19d\n", - "«" + type + "»", - String.format("%.0f", peerStats.get(type).getLeft() / 1_000_000), - peerStats.get(type).getRight())); + if (type != "all") { + sb.append( + String.format( + " «overall» %20s %16s ms %19d\n", + "«" + type + "»", + String.format( + "%.0f", peerStats.get(type).getLeft() / 1_000_000), + peerStats.get(type).getRight())); + } } + for (String nodeId : responseStats.keySet()) { if (nodeId != "overall") { peerStats = responseStats.get(nodeId); + sb.append( + String.format( + " id:%6s %20s %16s ms %19d\n", + nodeId, + "«all»", + String.format( + "%.0f", peerStats.get("all").getLeft() / 1_000_000), + peerStats.get("all").getRight())); for (String type : peerStats.keySet()) { - sb.append( - String.format( - " id:%6s %20s %16s ms %19d\n", - nodeId, - "«" + type + "»", - String.format( - "%.0f", peerStats.get(type).getLeft() / 1_000_000), - peerStats.get(type).getRight())); + if (type != "all") { + sb.append( + String.format( + " id:%6s %20s %16s ms %19d\n", + nodeId, + "«" + type + "»", + String.format( + "%.0f", + peerStats.get(type).getLeft() / 1_000_000), + peerStats.get(type).getRight())); + } } } } } return sb.toString(); } - - public void updateStatusRequest(String displayId, long requestTime) { - lockStatus.lock(); - try { - status.updateRequestTime(displayId, requestTime); - } finally { - lockStatus.unlock(); - } - } - - public void updateHeadersRequest(String displayId, long requestTime) { - lockHeaders.lock(); - try { - headers.updateRequestTime(displayId, requestTime); - } finally { - lockHeaders.unlock(); - } - } - - public void updateBodiesRequest(String displayId, long requestTime) { - lockBodies.lock(); - try { - bodies.updateRequestTime(displayId, requestTime); - } finally { - lockBodies.unlock(); - } - } - - public void updateStatusResponse(String displayId, long responseTime) { - lockStatus.lock(); - try { - status.updateResponseTime(displayId, responseTime); - } finally { - lockStatus.unlock(); - } - } - - public void updateHeadersResponse(String displayId, long responseTime) { - lockHeaders.lock(); - try { - headers.updateResponseTime(displayId, responseTime); - } finally { - lockHeaders.unlock(); - } - } - - public void updateBodiesResponse(String displayId, long responseTime) { - lockBodies.lock(); - try { - bodies.updateResponseTime(displayId, responseTime); - } finally { - lockBodies.unlock(); - } - } } diff --git a/modAionImpl/src/org/aion/zero/impl/sync/statistics/TopLeechesStatsTracker.java b/modAionImpl/src/org/aion/zero/impl/sync/statistics/TopLeechesStatsTracker.java new file mode 100644 index 0000000000..83c92e459f --- /dev/null +++ b/modAionImpl/src/org/aion/zero/impl/sync/statistics/TopLeechesStatsTracker.java @@ -0,0 +1,82 @@ +package org.aion.zero.impl.sync.statistics; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; +import org.apache.commons.collections4.map.LRUMap; + +public class TopLeechesStatsTracker { + private final Map blockRequestsByPeer; + private final Lock leechesLock; + + public TopLeechesStatsTracker(int maxActivePeers) { + this.blockRequestsByPeer = new LRUMap<>(maxActivePeers); + this.leechesLock = new ReentrantLock(); + } + + /** + * Updates the total block requests made by a peer. + * + * @param nodeId peer node display Id + * @param totalBlocks total number of blocks requested + */ + public void updateTotalBlockRequestsByPeer(String nodeId, int totalBlocks) { + leechesLock.lock(); + try { + if (blockRequestsByPeer.putIfAbsent(nodeId, totalBlocks) != null) { + blockRequestsByPeer.computeIfPresent(nodeId, (key, value) -> value + totalBlocks); + } + } finally { + leechesLock.unlock(); + } + } + + /** + * Obtains a map of peers ordered by the total number of requested blocks to the node + * + * @return map of total requested blocks by peer and sorted in descending order + */ + public Map getTotalBlockRequestsByPeer() { + leechesLock.lock(); + try { + return blockRequestsByPeer.entrySet().stream() + .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) + .collect( + Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (e1, e2) -> e2, + LinkedHashMap::new)); + } finally { + leechesLock.unlock(); + } + } + + /** + * Obtain log stream containing a list of peers ordered by the total number of blocks requested + * by each peer used to determine who is requesting the majority of blocks, i.e. top leeches. + * + * @return log stream with peers statistical data on leeches + */ + public String dumpTopLeechesStats() { + Map totalBlockReqByPeer = this.getTotalBlockRequestsByPeer(); + + StringBuilder sb = new StringBuilder(); + + if (!totalBlockReqByPeer.isEmpty()) { + + sb.append("\n========= sync-top-leeches =========\n"); + sb.append(String.format(" %9s %20s\n", "peer", "total blocks")); + sb.append("------------------------------------\n"); + + totalBlockReqByPeer.forEach( + (nodeId, totalBlocks) -> + sb.append(String.format(" id:%6s %20s\n", nodeId, totalBlocks))); + } + + return sb.toString(); + } +} diff --git a/modAionImpl/src/org/aion/zero/impl/sync/statistics/TopSeedsStatsTracker.java b/modAionImpl/src/org/aion/zero/impl/sync/statistics/TopSeedsStatsTracker.java new file mode 100644 index 0000000000..6e420a14f4 --- /dev/null +++ b/modAionImpl/src/org/aion/zero/impl/sync/statistics/TopSeedsStatsTracker.java @@ -0,0 +1,117 @@ +package org.aion.zero.impl.sync.statistics; + +import java.util.Collections; +import java.util.EnumMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; +import org.apache.commons.collections4.map.LRUMap; + +public class TopSeedsStatsTracker { + + private final EnumMap> blocksByPeer = + new EnumMap<>(BlockType.class); + private final Lock seedsLock; + + public TopSeedsStatsTracker(int maxActivePeers) { + // instantiate objects for gathering stats + for (BlockType type : BlockType.values()) { + blocksByPeer.put(type, new LRUMap<>(maxActivePeers)); + } + seedsLock = new ReentrantLock(); + } + + /** + * Updates the total number of blocks received/imported/stored from each seed peer + * + * @param nodeId peer node display Id + * @param blocks total number of blocks + * @param type type of the block: received, imported, stored + */ + public void updatePeerBlocksByType(String nodeId, int blocks, BlockType type) { + seedsLock.lock(); + try { + + if (blocksByPeer.get(type).putIfAbsent(nodeId, blocks) != null) { + blocksByPeer.get(type).computeIfPresent(nodeId, (key, value) -> value + blocks); + } + + } finally { + seedsLock.unlock(); + } + } + + /** + * Obtains a map of seed peers ordered by the total number of imported blocks + * + * @return map of total blocks received by peer and sorted in descending order + */ + public Map getReceivedBlocksByPeer() { + seedsLock.lock(); + try { + return blocksByPeer.get(BlockType.RECEIVED).entrySet().stream() + .filter(entry -> entry.getValue() > 0) + .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) + .collect( + Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (e1, e2) -> e2, + LinkedHashMap::new)); + } finally { + seedsLock.unlock(); + } + } + + /** + * Obtains the total number of blocks received/imported/stored from the given seed peer + * + * @return number of total blocks of given type by peer + */ + public long getBlocksByPeer(String _nodeId, BlockType type) { + seedsLock.lock(); + try { + return blocksByPeer.get(type).getOrDefault(_nodeId, 0); + } finally { + seedsLock.unlock(); + } + } + + /** + * Returns a log stream containing a list of peers ordered by the total number of blocks + * received from each peer used to determine who is providing the majority of blocks, i.e. top + * seeds. + * + * @return log stream with peers statistical data on seeds + */ + public String dumpTopSeedsStats() { + Map receivedBlocksByPeer = this.getReceivedBlocksByPeer(); + + StringBuilder sb = new StringBuilder(); + + if (!receivedBlocksByPeer.isEmpty()) { + + sb.append( + "\n============================= sync-top-seeds ==============================\n"); + sb.append( + String.format( + " %9s %20s %19s %19s\n", + "peer", "received blocks", "imported blocks", "stored blocks")); + sb.append( + "---------------------------------------------------------------------------\n"); + receivedBlocksByPeer.forEach( + (nodeId, receivedBlocks) -> + sb.append( + String.format( + " id:%6s %20s %19s %19s\n", + nodeId, + receivedBlocks, + this.getBlocksByPeer(nodeId, BlockType.IMPORTED), + this.getBlocksByPeer(nodeId, BlockType.STORED)))); + } + + return sb.toString(); + } +} diff --git a/modAionImpl/src/org/aion/zero/impl/types/AionBlock.java b/modAionImpl/src/org/aion/zero/impl/types/AionBlock.java index 4b001aac68..71130f12e1 100644 --- a/modAionImpl/src/org/aion/zero/impl/types/AionBlock.java +++ b/modAionImpl/src/org/aion/zero/impl/types/AionBlock.java @@ -4,8 +4,6 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.Hex; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.aion.mcf.trie.Trie; @@ -14,7 +12,10 @@ import org.aion.rlp.RLP; import org.aion.rlp.RLPElement; import org.aion.rlp.RLPList; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.conversions.Hex; import org.aion.zero.exceptions.HeaderStructureException; import org.aion.zero.types.A0BlockHeader; import org.aion.zero.types.AionTransaction; @@ -277,6 +278,38 @@ public List getTransactionsList() { return transactionsList; } + // used to reduce the number of times we create equal wrapper objects + private ByteArrayWrapper hashWrapper = null; + private ByteArrayWrapper parentHashWrapper = null; + + /** + * Returns a {@link ByteArrayWrapper} instance of the block's hash. + * + * @return a {@link ByteArrayWrapper} instance of the block's hash + * @implNote Not safe when the block is mutable. Use this only for sync where the block's hash + * cannot change during execution. + */ + public ByteArrayWrapper getHashWrapper() { + if (hashWrapper == null) { + hashWrapper = ByteArrayWrapper.wrap(getHash()); + } + return hashWrapper; + } + + /** + * Returns a {@link ByteArrayWrapper} instance of the block's parent hash. + * + * @return a {@link ByteArrayWrapper} instance of the block's parent hash + * @implNote Not safe when the block is mutable. Use this only for sync where the block's parent + * hash cannot change during execution. + */ + public ByteArrayWrapper getParentHashWrapper() { + if (parentHashWrapper == null) { + parentHashWrapper = ByteArrayWrapper.wrap(getParentHash()); + } + return parentHashWrapper; + } + /** * Facilitates the "finalization" of the block, after processing the necessary transactions. * This will be called during block creation and is considered the last step conducted by the @@ -473,6 +506,44 @@ public static AionBlock createBlockFromNetwork(A0BlockHeader header, byte[] body return block; } + public static AionBlock fromRLP(byte[] rlpEncoded, boolean isUnsafe) { + RLPList params = RLP.decode2(rlpEncoded); + + // ensuring the expected types list before type casting + if (params.get(0) instanceof RLPList) { + RLPList blockRLP = (RLPList) params.get(0); + + if (blockRLP.get(0) instanceof RLPList && blockRLP.get(1) instanceof RLPList) { + + // Parse Header + RLPList headerRLP = (RLPList) blockRLP.get(0); + A0BlockHeader header; + try { + header = A0BlockHeader.fromRLP(headerRLP, isUnsafe); + } catch (Exception e) { + return null; + } + if (header == null) { + return null; + } + + AionBlock block = new AionBlock(); + block.header = header; + block.parsed = true; + + // Parse Transactions + RLPList transactions = (RLPList) blockRLP.get(1); + if (!block.parseTxs(header.getTxTrieRoot(), transactions)) { + return null; + } + + return block; + } + } + // not an AionBlock encoding + return null; + } + public void setCumulativeDifficulty(BigInteger _td) { td = _td; } diff --git a/modAionImpl/src/org/aion/zero/impl/types/AionBlockSummary.java b/modAionImpl/src/org/aion/zero/impl/types/AionBlockSummary.java index 81af2b34bd..32f7355684 100644 --- a/modAionImpl/src/org/aion/zero/impl/types/AionBlockSummary.java +++ b/modAionImpl/src/org/aion/zero/impl/types/AionBlockSummary.java @@ -3,9 +3,9 @@ import java.math.BigInteger; import java.util.List; import java.util.Map; -import org.aion.base.type.IBlockSummary; +import org.aion.interfaces.block.BlockSummary; import org.aion.mcf.types.AbstractBlockSummary; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; import org.aion.zero.types.AionTransaction; import org.aion.zero.types.AionTxExecSummary; import org.aion.zero.types.AionTxReceipt; @@ -18,7 +18,7 @@ */ public class AionBlockSummary extends AbstractBlockSummary - implements IBlockSummary { + implements BlockSummary { public AionBlockSummary( IAionBlock block, diff --git a/modAionImpl/src/org/aion/zero/impl/types/RetValidPreBlock.java b/modAionImpl/src/org/aion/zero/impl/types/RetValidPreBlock.java index 0e238c33ef..14941dffe0 100644 --- a/modAionImpl/src/org/aion/zero/impl/types/RetValidPreBlock.java +++ b/modAionImpl/src/org/aion/zero/impl/types/RetValidPreBlock.java @@ -3,7 +3,8 @@ import java.math.BigInteger; import java.util.List; import java.util.Map; -import org.aion.vm.api.interfaces.Address; + +import org.aion.types.Address; import org.aion.zero.types.AionTransaction; import org.aion.zero.types.AionTxExecSummary; import org.aion.zero.types.AionTxReceipt; diff --git a/modAionImpl/src/org/aion/zero/impl/valid/AionDifficultyRule.java b/modAionImpl/src/org/aion/zero/impl/valid/AionDifficultyRule.java index ea279dbc3e..23c06907e4 100644 --- a/modAionImpl/src/org/aion/zero/impl/valid/AionDifficultyRule.java +++ b/modAionImpl/src/org/aion/zero/impl/valid/AionDifficultyRule.java @@ -1,22 +1,22 @@ package org.aion.zero.impl.valid; -import static org.aion.base.util.BIUtil.isEqual; +import static org.aion.util.biginteger.BIUtil.isEqual; import java.math.BigInteger; import java.util.List; import org.aion.mcf.blockchain.IChainCfg; import org.aion.mcf.core.IDifficultyCalculator; import org.aion.mcf.valid.GrandParentDependantBlockHeaderRule; +import org.aion.zero.impl.types.AionBlock; import org.aion.zero.types.A0BlockHeader; import org.aion.zero.types.AionTransaction; -import org.aion.zero.types.IAionBlock; /** Checks block's difficulty against calculated difficulty value */ public class AionDifficultyRule extends GrandParentDependantBlockHeaderRule { private IDifficultyCalculator diffCalc; - public AionDifficultyRule(IChainCfg configuration) { + public AionDifficultyRule(IChainCfg configuration) { this.diffCalc = configuration.getDifficultyCalculator(); } diff --git a/modAionImpl/src/org/aion/zero/impl/valid/TXValidator.java b/modAionImpl/src/org/aion/zero/impl/valid/TXValidator.java index e67d438580..94e4314d6d 100644 --- a/modAionImpl/src/org/aion/zero/impl/valid/TXValidator.java +++ b/modAionImpl/src/org/aion/zero/impl/valid/TXValidator.java @@ -5,12 +5,12 @@ import java.util.Collections; import java.util.Map; -import org.aion.base.type.Hash256; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.ISignature; import org.aion.crypto.SignatureFac; import org.aion.log.LogEnum; -import org.aion.mcf.vm.types.DataWord; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Hash256; import org.aion.zero.types.AionTransaction; import org.apache.commons.collections4.map.LRUMap; import org.slf4j.Logger; @@ -40,7 +40,7 @@ public static boolean isInCache(ByteArrayWrapper hash) { public static boolean isValid0(AionTransaction tx) { byte[] check = tx.getNonce(); - if (check == null || check.length > DataWord.BYTES) { + if (check == null || check.length > DataWordImpl.BYTES) { LOG.error("invalid tx nonce!"); return false; } @@ -52,7 +52,7 @@ public static boolean isValid0(AionTransaction tx) { } check = tx.getValue(); - if (check == null || check.length > DataWord.BYTES) { + if (check == null || check.length > DataWordImpl.BYTES) { LOG.error("invalid tx value!"); return false; } diff --git a/modAionImpl/src/org/aion/zero/impl/valid/TransactionTypeValidator.java b/modAionImpl/src/org/aion/zero/impl/valid/TransactionTypeValidator.java index c0d2e01fa4..f450ca7e42 100644 --- a/modAionImpl/src/org/aion/zero/impl/valid/TransactionTypeValidator.java +++ b/modAionImpl/src/org/aion/zero/impl/valid/TransactionTypeValidator.java @@ -1,7 +1,6 @@ package org.aion.zero.impl.valid; -// import static org.aion.mcf.valid.TransactionTypeRule.isValidAVMTransactionType; -// import static org.aion.mcf.valid.TransactionTypeRule.isValidFVMTransactionType; +import static org.aion.mcf.valid.TransactionTypeRule.isValidTransactionType; /** * Validator for the type field of transactions allowed by the network. The transaction types @@ -21,11 +20,10 @@ public static void enableAvmCheck(boolean enableAVM) { } public static boolean isValid(byte type) { - /* TODO: re-enable when the fork point is established - // the type must be either valid for the FVM - // or for the AVM when the AVM is enabled - return isValidFVMTransactionType(type) || (avmEnabled && isValidAVMTransactionType(type)); - */ return true; } + + public static boolean isValidAfterFork(byte type) { + return isValidTransactionType(type); + } } diff --git a/modAionImpl/test/org/aion/db/AionContractDetailsTest.java b/modAionImpl/test/org/aion/db/AionContractDetailsTest.java deleted file mode 100644 index 2a7fb9957d..0000000000 --- a/modAionImpl/test/org/aion/db/AionContractDetailsTest.java +++ /dev/null @@ -1,349 +0,0 @@ -package org.aion.db; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.db.IContractDetails; -import org.aion.base.db.IPruneConfig; -import org.aion.base.db.IRepositoryConfig; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; -import org.aion.db.impl.DBVendor; -import org.aion.db.impl.DatabaseFactory; -import org.aion.mcf.config.CfgPrune; -import org.aion.mcf.vm.types.DataWord; -import org.aion.vm.api.interfaces.Address; -import org.aion.zero.db.AionContractDetailsImpl; -import org.aion.zero.impl.db.AionRepositoryImpl; -import org.aion.zero.impl.db.ContractDetailsAion; -import org.apache.commons.lang3.RandomUtils; -import org.junit.Test; - -public class AionContractDetailsTest { - - private static final int IN_MEMORY_STORAGE_LIMIT = - 1000000; // CfgAion.inst().getDb().getDetailsInMemoryStorageLimit(); - - protected IRepositoryConfig repoConfig = - new IRepositoryConfig() { - @Override - public String getDbPath() { - return ""; - } - - @Override - public IPruneConfig getPruneConfig() { - return new CfgPrune(false); - } - - @Override - public IContractDetails contractDetailsImpl() { - return ContractDetailsAion.createForTesting(0, 1000000).getDetails(); - } - - @Override - public Properties getDatabaseConfig(String db_name) { - Properties props = new Properties(); - props.setProperty(DatabaseFactory.Props.DB_TYPE, DBVendor.MOCKDB.toValue()); - props.setProperty(DatabaseFactory.Props.ENABLE_HEAP_CACHE, "false"); - return props; - } - }; - - private static IContractDetails deserialize( - byte[] rlp, IByteArrayKeyValueDatabase externalStorage) { - AionContractDetailsImpl result = new AionContractDetailsImpl(); - result.setExternalStorageDataSource(externalStorage); - result.decode(rlp); - - return result; - } - - @Test - public void test_1() throws Exception { - - byte[] code = ByteUtil.hexStringToBytes("60016002"); - - byte[] key_1 = ByteUtil.hexStringToBytes("111111"); - byte[] val_1 = ByteUtil.hexStringToBytes("aaaaaa"); - - byte[] key_2 = ByteUtil.hexStringToBytes("222222"); - byte[] val_2 = ByteUtil.hexStringToBytes("bbbbbb"); - - AionContractDetailsImpl contractDetails = - new AionContractDetailsImpl( - -1, // CfgAion.inst().getDb().getPrune(), - 1000000 // CfgAion.inst().getDb().getDetailsInMemoryStorageLimit() - ); - contractDetails.setCode(code); - contractDetails.put(new DataWord(key_1).toWrapper(), new DataWord(val_1).toWrapper()); - contractDetails.put(new DataWord(key_2).toWrapper(), new DataWord(val_2).toWrapper()); - - byte[] data = contractDetails.getEncoded(); - - AionContractDetailsImpl contractDetails_ = new AionContractDetailsImpl(data); - - assertEquals(ByteUtil.toHexString(code), ByteUtil.toHexString(contractDetails_.getCode())); - - assertEquals( - ByteUtil.toHexString(val_1), - ByteUtil.toHexString( - contractDetails_ - .get(new DataWord(key_1).toWrapper()) - .getNoLeadZeroesData())); - - assertEquals( - ByteUtil.toHexString(val_2), - ByteUtil.toHexString( - contractDetails_ - .get(new DataWord(key_2).toWrapper()) - .getNoLeadZeroesData())); - } - - @Test - public void test_2() throws Exception { - - byte[] code = - ByteUtil.hexStringToBytes( - "7c0100000000000000000000000000000000000000000000000000000000600035046333d546748114610065578063430fe5f01461007c5780634d432c1d1461008d578063501385b2146100b857806357eb3b30146100e9578063dbc7df61146100fb57005b6100766004356024356044356102f0565b60006000f35b61008760043561039e565b60006000f35b610098600435610178565b8073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b6100c96004356024356044356101a0565b8073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b6100f1610171565b8060005260206000f35b610106600435610133565b8360005282602052816040528073ffffffffffffffffffffffffffffffffffffffff1660605260806000f35b5b60006020819052908152604090208054600182015460028301546003909301549192909173ffffffffffffffffffffffffffffffffffffffff1684565b5b60015481565b5b60026020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081206002015481908302341080156101fe575073ffffffffffffffffffffffffffffffffffffffff8516600090815260208190526040812054145b8015610232575073ffffffffffffffffffffffffffffffffffffffff85166000908152602081905260409020600101548390105b61023b57610243565b3391506102e8565b6101966103ca60003973ffffffffffffffffffffffffffffffffffffffff3381166101965285166101b68190526000908152602081905260408120600201546101d6526101f68490526102169080f073ffffffffffffffffffffffffffffffffffffffff8616600090815260208190526040902060030180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905591508190505b509392505050565b73ffffffffffffffffffffffffffffffffffffffff33166000908152602081905260408120548190821461032357610364565b60018054808201909155600090815260026020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555b50503373ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090209081556001810192909255600290910155565b3373ffffffffffffffffffffffffffffffffffffffff166000908152602081905260409020600201555600608061019660043960048051602451604451606451600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000908116909517815560018054909516909317909355600355915561013390819061006390396000f3007c0100000000000000000000000000000000000000000000000000000000600035046347810fe381146100445780637e4a1aa81461005557806383d2421b1461006957005b61004f6004356100ab565b60006000f35b6100636004356024356100fc565b60006000f35b61007460043561007a565b60006000f35b6001543373ffffffffffffffffffffffffffffffffffffffff9081169116146100a2576100a8565b60078190555b50565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905550565b6001543373ffffffffffffffffffffffffffffffffffffffff9081169116146101245761012f565b600582905560068190555b505056"); - Address address = AionAddress.wrap(RandomUtils.nextBytes(Address.SIZE)); - - byte[] key_0 = ByteUtil.hexStringToBytes("18d63b70aa690ad37cb50908746c9a55"); - byte[] val_0 = ByteUtil.hexStringToBytes("00000000000000000000000000000064"); - - byte[] key_1 = ByteUtil.hexStringToBytes("18d63b70aa690ad37cb50908746c9a56"); - byte[] val_1 = ByteUtil.hexStringToBytes("0000000000000000000000000000000c"); - - byte[] key_2 = ByteUtil.hexStringToBytes("5a448d1967513482947d1d3f6104316f"); - - byte[] key_3 = ByteUtil.hexStringToBytes("5a448d1967513482947d1d3f61043171"); - byte[] val_3 = ByteUtil.hexStringToBytes("00000000000000000000000000000014"); - - byte[] key_4 = ByteUtil.hexStringToBytes("18d63b70aa690ad37cb50908746c9a54"); - - byte[] key_5 = ByteUtil.hexStringToBytes("5a448d1967513482947d1d3f61043170"); - byte[] val_5 = ByteUtil.hexStringToBytes("00000000000000000000000000000078"); - - byte[] key_6 = ByteUtil.hexStringToBytes("c83a08bbccc01a0644d599ccd2a7c2e0"); - byte[] val_6 = ByteUtil.hexStringToBytes("8fbec874791c4e3f9f48a59a44686efe"); - - byte[] key_7 = ByteUtil.hexStringToBytes("5aa541c6c03f602a426f04ae47508bb8"); - byte[] val_7 = ByteUtil.hexStringToBytes("7a657031000000000000000000000000"); - - byte[] key_8 = ByteUtil.hexStringToBytes("5aa541c6c03f602a426f04ae47508bb9"); - byte[] val_8 = ByteUtil.hexStringToBytes("000000000000000000000000000000c8"); - - byte[] key_9 = ByteUtil.hexStringToBytes("5aa541c6c03f602a426f04ae47508bba"); - byte[] val_9 = ByteUtil.hexStringToBytes("0000000000000000000000000000000a"); - - byte[] key_10 = ByteUtil.hexStringToBytes("00000000000000000000000000000001"); - byte[] val_10 = ByteUtil.hexStringToBytes("00000000000000000000000000000003"); - - byte[] key_11 = ByteUtil.hexStringToBytes("5aa541c6c03f602a426f04ae47508bbb"); - byte[] val_11 = ByteUtil.hexStringToBytes("194bcfc3670d8a1613e5b0c790036a35"); - - byte[] key_12 = ByteUtil.hexStringToBytes("aee92919b8c3389af86ef24535e8a28c"); - byte[] val_12 = ByteUtil.hexStringToBytes("cfe293a85bef5915e1a7acb37bf0c685"); - - byte[] key_13 = ByteUtil.hexStringToBytes("65c996598dc972688b7ace676c89077b"); - byte[] val_13 = ByteUtil.hexStringToBytes("d6ee27e285f2de7b68e8db25cf1b1063"); - - AionContractDetailsImpl contractDetails = new AionContractDetailsImpl(); - contractDetails.setCode(code); - contractDetails.setAddress(address); - contractDetails.put(new DataWord(key_0).toWrapper(), new DataWord(val_0).toWrapper()); - contractDetails.put(new DataWord(key_1).toWrapper(), new DataWord(val_1).toWrapper()); - contractDetails.delete(new DataWord(key_2).toWrapper()); - contractDetails.put(new DataWord(key_3).toWrapper(), new DataWord(val_3).toWrapper()); - contractDetails.delete(new DataWord(key_4).toWrapper()); - contractDetails.put(new DataWord(key_5).toWrapper(), new DataWord(val_5).toWrapper()); - contractDetails.put(new DataWord(key_6).toWrapper(), new DataWord(val_6).toWrapper()); - contractDetails.put(new DataWord(key_7).toWrapper(), new DataWord(val_7).toWrapper()); - contractDetails.put(new DataWord(key_8).toWrapper(), new DataWord(val_8).toWrapper()); - contractDetails.put(new DataWord(key_9).toWrapper(), new DataWord(val_9).toWrapper()); - contractDetails.put(new DataWord(key_10).toWrapper(), new DataWord(val_10).toWrapper()); - contractDetails.put(new DataWord(key_11).toWrapper(), new DataWord(val_11).toWrapper()); - contractDetails.put(new DataWord(key_12).toWrapper(), new DataWord(val_12).toWrapper()); - contractDetails.put(new DataWord(key_13).toWrapper(), new DataWord(val_13).toWrapper()); - - byte[] data = contractDetails.getEncoded(); - - AionContractDetailsImpl contractDetails_ = new AionContractDetailsImpl(data); - - assertEquals(ByteUtil.toHexString(code), ByteUtil.toHexString(contractDetails_.getCode())); - - assertTrue(address.equals(contractDetails_.getAddress())); - - assertEquals( - ByteUtil.toHexString(val_1), - ByteUtil.toHexString( - contractDetails_.get(new DataWord(key_1).toWrapper()).getData())); - - assertNull(contractDetails_.get(new DataWord(key_2).toWrapper())); - - assertEquals( - ByteUtil.toHexString(val_3), - ByteUtil.toHexString( - contractDetails_.get(new DataWord(key_3).toWrapper()).getData())); - - assertNull(contractDetails_.get(new DataWord(key_4).toWrapper())); - - assertEquals( - ByteUtil.toHexString(val_5), - ByteUtil.toHexString( - contractDetails_.get(new DataWord(key_5).toWrapper()).getData())); - - assertEquals( - ByteUtil.toHexString(val_6), - ByteUtil.toHexString( - contractDetails_.get(new DataWord(key_6).toWrapper()).getData())); - - assertEquals( - ByteUtil.toHexString(val_7), - ByteUtil.toHexString( - contractDetails_.get(new DataWord(key_7).toWrapper()).getData())); - - assertEquals( - ByteUtil.toHexString(val_8), - ByteUtil.toHexString( - contractDetails_.get(new DataWord(key_8).toWrapper()).getData())); - - assertEquals( - ByteUtil.toHexString(val_9), - ByteUtil.toHexString( - contractDetails_.get(new DataWord(key_9).toWrapper()).getData())); - - assertEquals( - ByteUtil.toHexString(val_10), - ByteUtil.toHexString( - contractDetails_.get(new DataWord(key_10).toWrapper()).getData())); - - assertEquals( - ByteUtil.toHexString(val_11), - ByteUtil.toHexString( - contractDetails_.get(new DataWord(key_11).toWrapper()).getData())); - - assertEquals( - ByteUtil.toHexString(val_12), - ByteUtil.toHexString( - contractDetails_.get(new DataWord(key_12).toWrapper()).getData())); - - assertEquals( - ByteUtil.toHexString(val_13), - ByteUtil.toHexString( - contractDetails_.get(new DataWord(key_13).toWrapper()).getData())); - } - - @Test - public void testExternalStorageSerialization() { - Address address = AionAddress.wrap(RandomUtils.nextBytes(Address.SIZE)); - byte[] code = RandomUtils.nextBytes(512); - Map elements = new HashMap<>(); - - AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig); - IByteArrayKeyValueDatabase externalStorage = repository.getDetailsDatabase(); - - AionContractDetailsImpl original = new AionContractDetailsImpl(0, 1000000); - - original.setExternalStorageDataSource(externalStorage); - original.setAddress(address); - original.setCode(code); - original.externalStorage = true; - - for (int i = 0; i < IN_MEMORY_STORAGE_LIMIT / 64 + 10; i++) { - DataWord key = new DataWord(RandomUtils.nextBytes(16)); - DataWord value = new DataWord(RandomUtils.nextBytes(16)); - - elements.put(key, value); - original.put(key.toWrapper(), wrapValueForPut(value)); - } - - original.syncStorage(); - - byte[] rlp = original.getEncoded(); - - AionContractDetailsImpl deserialized = new AionContractDetailsImpl(); - deserialized.setExternalStorageDataSource(externalStorage); - deserialized.decode(rlp); - - assertEquals(deserialized.externalStorage, true); - assertTrue(address.equals(deserialized.getAddress())); - assertEquals(ByteUtil.toHexString(code), ByteUtil.toHexString(deserialized.getCode())); - - for (DataWord key : elements.keySet()) { - assertEquals( - elements.get(key).toWrapper(), - wrapValueFromGet(deserialized.get(key.toWrapper()))); - } - - DataWord deletedKey = elements.keySet().iterator().next(); - - deserialized.delete(deletedKey.toWrapper()); - deserialized.delete(new DataWord(RandomUtils.nextBytes(16)).toWrapper()); - } - - @Test - public void testExternalStorageTransition() { - Address address = AionAddress.wrap(RandomUtils.nextBytes(Address.SIZE)); - byte[] code = RandomUtils.nextBytes(512); - Map elements = new HashMap<>(); - - AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig); - IByteArrayKeyValueDatabase externalStorage = repository.getDetailsDatabase(); - - AionContractDetailsImpl original = new AionContractDetailsImpl(0, 1000000); - original.setExternalStorageDataSource(externalStorage); - original.setAddress(address); - original.setCode(code); - - for (int i = 0; i < IN_MEMORY_STORAGE_LIMIT / 64 + 10; i++) { - DataWord key = new DataWord(RandomUtils.nextBytes(16)); - DataWord value = new DataWord(RandomUtils.nextBytes(16)); - - elements.put(key, value); - original.put(key.toWrapper(), wrapValueForPut(value)); - } - - original.syncStorage(); - assertTrue(!externalStorage.isEmpty()); - - IContractDetails deserialized = deserialize(original.getEncoded(), externalStorage); - - // adds keys for in-memory storage limit overflow - for (int i = 0; i < 10; i++) { - DataWord key = new DataWord(RandomUtils.nextBytes(16)); - DataWord value = new DataWord(RandomUtils.nextBytes(16)); - - elements.put(key, value); - - deserialized.put(key.toWrapper(), wrapValueForPut(value)); - } - - deserialized.syncStorage(); - assertTrue(!externalStorage.isEmpty()); - - deserialized = deserialize(deserialized.getEncoded(), externalStorage); - - for (DataWord key : elements.keySet()) { - assertEquals( - elements.get(key).toWrapper(), - wrapValueFromGet(deserialized.get(key.toWrapper()))); - } - } - - private static ByteArrayWrapper wrapValueForPut(DataWord value) { - return (value.isZero()) - ? new ByteArrayWrapper(value.getData()) - : new ByteArrayWrapper(value.getNoLeadZeroesData()); - } - - private static ByteArrayWrapper wrapValueFromGet(ByteArrayWrapper value) { - return new ByteArrayWrapper(new DataWord(value.getData()).getData()); - } -} diff --git a/modAionImpl/test/org/aion/equihash/EquihashSolutionsGenerationTest210_9.java b/modAionImpl/test/org/aion/equihash/EquihashSolutionsGenerationTest210_9.java index d63b9bb827..b0edf1d8f7 100644 --- a/modAionImpl/test/org/aion/equihash/EquihashSolutionsGenerationTest210_9.java +++ b/modAionImpl/test/org/aion/equihash/EquihashSolutionsGenerationTest210_9.java @@ -375,7 +375,7 @@ public void testMine_wBlockData(AionBlock block) { // use real method for mine call when(spy.mine(block, header.getNonce())).thenCallRealMethod(); - Solution sol = spy.mine(block, block.getNonce()); + AionPowSolution sol = spy.mine(block, block.getNonce()); assertNotNull(sol); assertArrayEquals(header.getNonce(), sol.getNonce()); diff --git a/modAionImpl/test/org/aion/equihash/benchmark/BatchHeaderBenchmark.java b/modAionImpl/test/org/aion/equihash/benchmark/BatchHeaderBenchmark.java index 4bc2a19c0a..a9ab61e458 100644 --- a/modAionImpl/test/org/aion/equihash/benchmark/BatchHeaderBenchmark.java +++ b/modAionImpl/test/org/aion/equihash/benchmark/BatchHeaderBenchmark.java @@ -1,6 +1,6 @@ // package org.aion.equihash.benchmark; // -// import org.aion.base.type.AionAddress; +// import org.aion.types.Address; // import org.aion.base.util.ByteUtil; // import org.aion.equihash.EquiUtils; // import org.aion.equihash.OptimizedEquiValidator; diff --git a/modAionImpl/test/org/aion/zero/impl/AionHubTest.java b/modAionImpl/test/org/aion/zero/impl/AionHubTest.java index 17d99693d4..90426c19c0 100644 --- a/modAionImpl/test/org/aion/zero/impl/AionHubTest.java +++ b/modAionImpl/test/org/aion/zero/impl/AionHubTest.java @@ -8,7 +8,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.aion.base.db.IByteArrayKeyValueDatabase; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; import org.aion.log.AionLoggerFactory; import org.aion.mcf.core.ImportResult; import org.aion.mcf.trie.TrieImpl; @@ -19,7 +19,6 @@ import org.junit.After; import org.junit.BeforeClass; import org.junit.Test; - public class AionHubTest { private void checkHubNullity(AionHub hub) { @@ -155,7 +154,7 @@ public void MockHubInst_wStartRecovery() { // delete some world state root entries from the database TrieImpl trie = (TrieImpl) repo.getWorldState(); - IByteArrayKeyValueDatabase database = repo.getStateDatabase(); + ByteArrayKeyValueDatabase database = repo.getStateDatabase(); repo.flush(); for (byte[] key : statesToDelete) { diff --git a/modAionImpl/test/org/aion/zero/impl/BlockchainAccountStateBenchmark.java b/modAionImpl/test/org/aion/zero/impl/BlockchainAccountStateBenchmark.java index 22211fce14..d3b42e26e5 100644 --- a/modAionImpl/test/org/aion/zero/impl/BlockchainAccountStateBenchmark.java +++ b/modAionImpl/test/org/aion/zero/impl/BlockchainAccountStateBenchmark.java @@ -1,22 +1,30 @@ package org.aion.zero.impl; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import java.io.File; import java.math.BigInteger; -import java.nio.ByteBuffer; -import java.util.ArrayList; +import java.security.SecureRandom; import java.util.Arrays; import java.util.Collection; import java.util.List; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; +import java.util.Random; +import java.util.ArrayList; +import java.util.Collections; + +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.crypto.HashUtil; import org.aion.db.impl.DBVendor; import org.aion.db.utils.FileUtils; import org.aion.mcf.core.ImportResult; -import org.aion.vm.api.interfaces.Address; + +import org.aion.util.bytes.ByteUtil; +import org.aion.util.conversions.Hex; +import org.aion.zero.impl.db.AionContractDetailsImpl; + import org.aion.zero.impl.types.AionBlock; import org.aion.zero.impl.types.AionTxInfo; import org.aion.zero.types.AionTransaction; @@ -30,9 +38,13 @@ @RunWith(Parameterized.class) public class BlockchainAccountStateBenchmark { - public static String baseTestPath = "test_db"; + private Random random = new SecureRandom(); + + private String name; - public static String[] dbPaths = { + private static String baseTestPath = "test_db"; + + private static String[] dbPaths = { "level_db_state_test", "level_db_expansion_test", "h2_db_state_test", @@ -41,7 +53,7 @@ public class BlockchainAccountStateBenchmark { "rocks_db_expansion_test" }; - public static void resetFileState() { + private static void resetFileState() { File f = new File(baseTestPath); if (f.exists()) { FileUtils.deleteRecursively(f); @@ -124,8 +136,6 @@ public String getDbPath() { }); } - private String name; - private StandaloneBlockchain.Bundle bundle; public BlockchainAccountStateBenchmark(String name, StandaloneBlockchain.Bundle bundle) { @@ -157,13 +167,13 @@ public void testAccountState() { private static AionBlock createBundleAndCheck( StandaloneBlockchain bc, ECKey key, AionBlock parentBlock) { - BigInteger accountNonce = bc.getRepository().getNonce(new AionAddress(key.getAddress())); + BigInteger accountNonce = bc.getRepository().getNonce(new Address(key.getAddress())); List transactions = new ArrayList<>(); // create 400 transactions per bundle // byte[] nonce, Address to, byte[] value, byte[] data, long nrg, long nrgPrice for (int i = 0; i < 400; i++) { - Address destAddr = new AionAddress(HashUtil.h256(accountNonce.toByteArray())); + Address destAddr = new Address(HashUtil.h256(accountNonce.toByteArray())); AionTransaction sendTransaction = new AionTransaction( accountNonce.toByteArray(), @@ -192,7 +202,7 @@ private static AionBlock createBundleAndCheck( } private static final String STATE_EXPANSION_BYTECODE = - "0x605060405260006001600050909055341561001a5760006000fd5b61001f565b6101688061002e6000396000f30060506040526000356c01000000000000000000000000900463ffffffff16806331e658a514610049578063549262ba1461008957806361bc221a1461009f57610043565b60006000fd5b34156100555760006000fd5b610073600480808060100135903590916020019091929050506100c9565b6040518082815260100191505060405180910390f35b34156100955760006000fd5b61009d6100eb565b005b34156100ab5760006000fd5b6100b3610133565b6040518082815260100191505060405180910390f35b6000600050602052818160005260105260306000209050600091509150505481565b6001600060005060006001600050546000825281601001526020019081526010016000209050600050819090905550600160008181505480929190600101919050909055505b565b600160005054815600a165627a7a72305820c615f3373321aa7e9c05d9a69e49508147861fb2a54f2945fbbaa7d851125fe80029"; + "605060405234156100105760006000fd5b610015565b610146806100246000396000f30060506040526000356c01000000000000000000000000900463ffffffff16806326121ff0146100335761002d565b60006000fd5b341561003f5760006000fd5b610047610049565b005b6000600050805480600101828161006091906100b3565b91909060005260106000209050906002020160005b7e112233445566778899001122334455667788990011223344556677889900119091929091925091909060001916909091806001018390555550505b565b8154818355818115116100e25760020281600202836000526010600020905091820191016100e191906100e7565b5b505050565b61011791906100f1565b80821115610113576000818150806000905560010160009055506002016100f1565b5090565b905600a165627a7a72305820c4bdcf87b810c9e707e3df169b98d6a37a6e6f3356cc8c120ea06c64696f85c20029"; @Ignore @Test @@ -229,22 +239,23 @@ public void testExpandOneAccountStorage() throws InterruptedException { } } - public static Pair createContract( + private static Pair createContract( StandaloneBlockchain bc, ECKey key, AionBlock parentBlock) { - BigInteger accountNonce = bc.getRepository().getNonce(new AionAddress(key.getAddress())); + BigInteger accountNonce = bc.getRepository().getNonce(new Address(key.getAddress())); // deploy AionTransaction creationTx = new AionTransaction( accountNonce.toByteArray(), - AionAddress.EMPTY_ADDRESS(), + null, BigInteger.ZERO.toByteArray(), ByteUtil.hexStringToBytes(STATE_EXPANSION_BYTECODE), 1000000, 1); creationTx.sign(key); - AionBlock block = bc.createNewBlock(parentBlock, Arrays.asList(creationTx), true); + AionBlock block = + bc.createNewBlock(parentBlock, Collections.singletonList(creationTx), true); return Pair.of(block, creationTx.getTransactionHash()); } @@ -253,22 +264,29 @@ private static AionBlock createContractBundle( final ECKey key, final AionBlock parentBlock, final Address contractAddress) { - BigInteger accountNonce = bc.getRepository().getNonce(new AionAddress(key.getAddress())); + return createContractBundle(bc, key, parentBlock, contractAddress, 133); + } + + private static AionBlock createContractBundle( + final StandaloneBlockchain bc, + final ECKey key, + final AionBlock parentBlock, + final Address contractAddress, + final int repeat) { + + BigInteger accountNonce = bc.getRepository().getNonce(new Address(key.getAddress())); List transactions = new ArrayList<>(); - // command - ByteBuffer buf = ByteBuffer.allocate(4); - buf.put(HashUtil.keccak256("put()".getBytes()), 0, 4); + byte[] callData = Hex.decode("26121ff0"); - // create 400 transactions per bundle // byte[] nonce, Address to, byte[] value, byte[] data, long nrg, long nrgPrice - for (int i = 0; i < 133; i++) { + for (int i = 0; i < repeat; i++) { AionTransaction sendTransaction = new AionTransaction( accountNonce.toByteArray(), contractAddress, BigInteger.ZERO.toByteArray(), - buf.array(), + callData, 200000, 1); sendTransaction.sign(key); @@ -278,7 +296,7 @@ private static AionBlock createContractBundle( AionBlock block = bc.createNewBlock(parentBlock, transactions, true); - assertThat(block.getTransactionsList().size()).isEqualTo(133); + assertThat(block.getTransactionsList().size()).isEqualTo(repeat); // clear the trie bc.getRepository().flush(); @@ -291,4 +309,52 @@ private static AionBlock createContractBundle( assertThat(result).isEqualTo(ImportResult.IMPORTED_BEST); return block; } + + @Test + public void testExpandContractsStorage() throws InterruptedException { + try { + StandaloneBlockchain.Bundle bundle = this.bundle; + + StandaloneBlockchain bc = bundle.bc; + + int r = random.nextInt(bundle.privateKeys.size()); + ECKey key = bundle.privateKeys.get(r); + // deploy contract + Pair res = createContract(bc, key, bc.getGenesis()); + bc.tryToConnect(res.getLeft()); + AionTxInfo info = bc.getTransactionInfo(res.getRight()); + assertThat(info.getReceipt().isValid()).isTrue(); + + Address contractAddress = info.getReceipt().getTransaction().getContractAddress(); + + byte[] contractCode = + bc.getRepository() + .getCode(info.getReceipt().getTransaction().getContractAddress()); + + System.out.println("deployed contract code: " + ByteUtil.toHexString(contractCode)); + System.out.println("deployed at: " + contractAddress); + + AionContractDetailsImpl acdi = + new AionContractDetailsImpl( + bc.getRepository().getContractDetails(contractAddress).getEncoded()); + assertFalse(acdi.externalStorage); + + // around 350 tx to letting the contract storage from memory switch to the external + // storage. + for (int i = 0; i < 9; i++) { + createContractBundle(bc, key, bc.getBestBlock(), contractAddress, 50); + } + + acdi = + new AionContractDetailsImpl( + bc.getRepository().getContractDetails(contractAddress).getEncoded()); + assertTrue(acdi.externalStorage); + + } catch (Exception e) { + e.printStackTrace(); + } finally { + bundle.bc.getRepository().close(); + Thread.sleep(1000L); + } + } } diff --git a/modAionImpl/test/org/aion/zero/impl/BlockchainAccountStateTest.java b/modAionImpl/test/org/aion/zero/impl/BlockchainAccountStateTest.java index 101b177453..d564f10b93 100644 --- a/modAionImpl/test/org/aion/zero/impl/BlockchainAccountStateTest.java +++ b/modAionImpl/test/org/aion/zero/impl/BlockchainAccountStateTest.java @@ -5,11 +5,11 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.List; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.crypto.HashUtil; import org.aion.mcf.core.ImportResult; -import org.aion.vm.api.interfaces.Address; + import org.aion.zero.impl.types.AionBlock; import org.aion.zero.types.AionTransaction; import org.junit.Ignore; @@ -44,13 +44,13 @@ public void testAccountState() { private static AionBlock createBundleAndCheck( StandaloneBlockchain bc, ECKey key, AionBlock parentBlock) { - BigInteger accountNonce = bc.getRepository().getNonce(new AionAddress(key.getAddress())); + BigInteger accountNonce = bc.getRepository().getNonce(new Address(key.getAddress())); List transactions = new ArrayList<>(); // create 400 transactions per bundle // byte[] nonce, Address to, byte[] value, byte[] data, long nrg, long nrgPrice for (int i = 0; i < 400; i++) { - Address destAddr = new AionAddress(HashUtil.h256(accountNonce.toByteArray())); + Address destAddr = new Address(HashUtil.h256(accountNonce.toByteArray())); AionTransaction sendTransaction = new AionTransaction( accountNonce.toByteArray(), @@ -108,13 +108,13 @@ public void testExpandAccountStorage() { private static AionBlock createContractBundle( StandaloneBlockchain bc, ECKey key, AionBlock parentBlock) { - BigInteger accountNonce = bc.getRepository().getNonce(new AionAddress(key.getAddress())); + BigInteger accountNonce = bc.getRepository().getNonce(new Address(key.getAddress())); List transactions = new ArrayList<>(); // create 400 transactions per bundle // byte[] nonce, Address to, byte[] value, byte[] data, long nrg, long nrgPrice for (int i = 0; i < 400; i++) { - Address destAddr = new AionAddress(HashUtil.h256(accountNonce.toByteArray())); + Address destAddr = new Address(HashUtil.h256(accountNonce.toByteArray())); AionTransaction sendTransaction = new AionTransaction( accountNonce.toByteArray(), diff --git a/modAionImpl/test/org/aion/zero/impl/BlockchainConcurrentImportTest.java b/modAionImpl/test/org/aion/zero/impl/BlockchainConcurrentImportTest.java index 32b03aa83b..2c0017866e 100644 --- a/modAionImpl/test/org/aion/zero/impl/BlockchainConcurrentImportTest.java +++ b/modAionImpl/test/org/aion/zero/impl/BlockchainConcurrentImportTest.java @@ -17,10 +17,10 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import org.aion.base.type.Hash256; import org.aion.crypto.ECKey; import org.aion.log.AionLoggerFactory; import org.aion.mcf.core.ImportResult; +import org.aion.types.Hash256; import org.aion.zero.impl.db.AionBlockStore; import org.aion.zero.impl.db.AionRepositoryImpl; import org.aion.zero.impl.types.AionBlock; diff --git a/modAionImpl/test/org/aion/zero/impl/BlockchainDataRecoveryTest.java b/modAionImpl/test/org/aion/zero/impl/BlockchainDataRecoveryTest.java index 26acb67e03..5746efd391 100644 --- a/modAionImpl/test/org/aion/zero/impl/BlockchainDataRecoveryTest.java +++ b/modAionImpl/test/org/aion/zero/impl/BlockchainDataRecoveryTest.java @@ -7,13 +7,13 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.Hex; import org.aion.crypto.ECKey; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; import org.aion.log.AionLoggerFactory; import org.aion.mcf.core.ImportResult; import org.aion.mcf.trie.TrieImpl; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.conversions.Hex; import org.aion.zero.impl.db.AionRepositoryImpl; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.types.AionTransaction; @@ -76,7 +76,7 @@ public void testRecoverWorldStateWithPartialWorldState() { // delete some world state root entries from the database TrieImpl trie = (TrieImpl) repo.getWorldState(); - IByteArrayKeyValueDatabase database = repo.getStateDatabase(); + ByteArrayKeyValueDatabase database = repo.getStateDatabase(); // 1: direct recovery call @@ -155,7 +155,7 @@ public void testRecoverWorldStateWithStartFromGenesis() { // delete some world state root entries from the database TrieImpl trie = (TrieImpl) repo.getWorldState(); - IByteArrayKeyValueDatabase database = repo.getStateDatabase(); + ByteArrayKeyValueDatabase database = repo.getStateDatabase(); // 1: direct recovery call @@ -236,7 +236,7 @@ public void testRecoverWorldStateWithoutGenesis() { // delete some world state root entries from the database TrieImpl trie = (TrieImpl) repo.getWorldState(); - IByteArrayKeyValueDatabase database = repo.getStateDatabase(); + ByteArrayKeyValueDatabase database = repo.getStateDatabase(); // 1: direct recovery call @@ -367,7 +367,7 @@ public void testRecoverWorldState_wDeletedBlock() { // delete some world state root entries from the database TrieImpl trie = (TrieImpl) repo.getWorldState(); - IByteArrayKeyValueDatabase database = repo.getStateDatabase(); + ByteArrayKeyValueDatabase database = repo.getStateDatabase(); // 1: direct recovery call @@ -477,7 +477,7 @@ public void testRecoverIndexWithPartialIndex_MainChain() { assertThat(bestBlock.getNumber()).isEqualTo(NUMBER_OF_BLOCKS); // delete index entries from the database - IByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); + ByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); // 1: direct recovery call @@ -637,7 +637,7 @@ public void testRecoverIndexWithPartialIndex_ShorterSideChain() { assertThat(bestBlock.getHash()).isEqualTo(mainChainBlock.getHash()); // delete index entries from the database - IByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); + ByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); // 1: direct recovery call @@ -769,7 +769,7 @@ public void testRecoverIndexWithStartFromGenesis() { assertThat(bestBlock.getNumber()).isEqualTo(NUMBER_OF_BLOCKS); // delete index entries from the database - IByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); + ByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); // 1: direct recovery call @@ -881,7 +881,7 @@ public void testRecoverIndexWithoutGenesis() { AionBlock bestBlock = chain.getBestBlock(); assertThat(bestBlock.getNumber()).isEqualTo(NUMBER_OF_BLOCKS); - IByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); + ByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); // 1: direct recovery call @@ -958,7 +958,7 @@ public void testRecoverIndexWithStartFromGenesisWithoutSize() { assertThat(bestBlock.getNumber()).isEqualTo(NUMBER_OF_BLOCKS); // delete index entries from the database - IByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); + ByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); // 1: direct recovery call @@ -1127,7 +1127,7 @@ public void testRecoverIndex_wDeletedBlock() { repo.getBlockDatabase().delete(middle.getHash()); // delete index entries from the database - IByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); + ByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); // 1: direct recovery call diff --git a/modAionImpl/test/org/aion/zero/impl/BlockchainEnergyTest.java b/modAionImpl/test/org/aion/zero/impl/BlockchainEnergyTest.java index 38fef24bc1..8ecc0911de 100644 --- a/modAionImpl/test/org/aion/zero/impl/BlockchainEnergyTest.java +++ b/modAionImpl/test/org/aion/zero/impl/BlockchainEnergyTest.java @@ -6,10 +6,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; +import org.aion.types.Address; import org.aion.mcf.core.ImportResult; -import org.aion.vm.api.interfaces.Address; +import org.aion.util.bytes.ByteUtil; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.types.AionTransaction; import org.junit.Test; @@ -35,7 +34,7 @@ public void testConsistentEnergyUsage() { public void testEnergyUsageRecorded() { final int DEFAULT_TX_AMOUNT = 21000; final Address RECEIPT_ADDR = - AionAddress.wrap( + Address.wrap( "CAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFE"); StandaloneBlockchain.Bundle bundle = diff --git a/modAionImpl/test/org/aion/zero/impl/BlockchainForkingTest.java b/modAionImpl/test/org/aion/zero/impl/BlockchainForkingTest.java index 6951051449..79cf9aa8ad 100644 --- a/modAionImpl/test/org/aion/zero/impl/BlockchainForkingTest.java +++ b/modAionImpl/test/org/aion/zero/impl/BlockchainForkingTest.java @@ -5,10 +5,10 @@ import java.math.BigInteger; import java.util.Collections; import java.util.List; -import org.aion.base.util.BIUtil; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.ECKey; import org.aion.mcf.core.ImportResult; +import org.aion.util.biginteger.BIUtil; import org.aion.zero.impl.blockchain.ChainConfiguration; import org.aion.zero.impl.types.AionBlock; import org.junit.Test; diff --git a/modAionImpl/test/org/aion/zero/impl/BlockchainImplementationTest.java b/modAionImpl/test/org/aion/zero/impl/BlockchainImplementationTest.java index eaefd5bf81..a8c93c3e5f 100644 --- a/modAionImpl/test/org/aion/zero/impl/BlockchainImplementationTest.java +++ b/modAionImpl/test/org/aion/zero/impl/BlockchainImplementationTest.java @@ -2,17 +2,24 @@ import static com.google.common.truth.Truth.assertThat; import static org.aion.zero.impl.BlockchainTestUtils.generateRandomChain; +import static org.aion.zero.impl.BlockchainTestUtils.generateRandomChainWithoutTransactions; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import org.aion.base.util.ByteArrayWrapper; +import java.util.Optional; import org.aion.crypto.ECKey; +import org.aion.crypto.HashUtil; import org.aion.mcf.config.CfgPrune; +import org.aion.mcf.core.FastImportResult; import org.aion.mcf.core.ImportResult; +import org.aion.types.ByteArrayWrapper; +import org.aion.zero.exceptions.HeaderStructureException; import org.aion.zero.impl.db.AionRepositoryImpl; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.types.A0BlockHeader; import org.aion.zero.types.AionTransaction; +import org.apache.commons.lang3.tuple.Pair; import org.junit.Test; /** @@ -562,4 +569,151 @@ public static void assertStartFrom( assertThat(hashes.size()).isEqualTo(expected.size()); assertThat(hashes).isEqualTo(expected); } + + @Test + public void testFindMissingAncestor_withCompleteChain() { + StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder(); + StandaloneBlockchain.Bundle bundle = builder.withValidatorConfiguration("simple").build(); + + StandaloneBlockchain chain = bundle.bc; + + // populate chain at random + generateRandomChainWithoutTransactions(chain, 2, 1); + + AionBlock best = chain.getBestBlock(); + + assertThat(chain.findMissingAncestor(best)).isNull(); + } + + @Test + public void testFindMissingAncestor_withFirstMissing() { + StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder(); + StandaloneBlockchain.Bundle bundle = builder.withValidatorConfiguration("simple").build(); + + StandaloneBlockchain chain = bundle.bc; + + // populate chain at random + generateRandomChainWithoutTransactions(chain, 2, 1); + + AionBlock best = chain.getBestBlock(); + byte[] bestHash = best.getHash(); + + // delete the block from the db + chain.getRepository().getBlockDatabase().delete(bestHash); + + Pair pair = chain.findMissingAncestor(best); + assertThat(pair.getLeft()).isEqualTo(ByteArrayWrapper.wrap(bestHash)); + assertThat(pair.getRight()).isEqualTo(best.getNumber()); + } + + @Test + public void testFindMissingAncestor_withParentMissing() { + StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder(); + StandaloneBlockchain.Bundle bundle = builder.withValidatorConfiguration("simple").build(); + + StandaloneBlockchain chain = bundle.bc; + + // populate chain at random + generateRandomChainWithoutTransactions(chain, 2, 1); + + AionBlock best = chain.getBestBlock(); + byte[] parentHash = best.getParentHash(); + + // delete the block from the db + chain.getRepository().getBlockDatabase().delete(parentHash); + + Pair pair = chain.findMissingAncestor(best); + assertThat(pair.getLeft()).isEqualTo(ByteArrayWrapper.wrap(parentHash)); + assertThat(pair.getRight()).isEqualTo(best.getNumber() - 1); + } + + @Test + public void tryFastImport_withNullBlock() { + StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder(); + StandaloneBlockchain.Bundle bundle = builder.withValidatorConfiguration("simple").build(); + + StandaloneBlockchain chain = bundle.bc; + + // populate chain at random + generateRandomChainWithoutTransactions(chain, 1, 1); + + assertThat(chain.tryFastImport(null)).isEqualTo(FastImportResult.INVALID_BLOCK); + } + + @Test + public void tryFastImport_withIncorrectTimestamp() throws HeaderStructureException { + StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder(); + StandaloneBlockchain.Bundle bundle = builder.withValidatorConfiguration("simple").build(); + + StandaloneBlockchain chain = bundle.bc; + + // populate chain at random + generateRandomChainWithoutTransactions(chain, 1, 1); + + AionBlock parent = chain.getBestBlock(); + A0BlockHeader.Builder headerBuilder = + new A0BlockHeader.Builder() + .withVersion((byte) 1) + .withParentHash(parent.getHash()) + .withCoinbase(parent.getCoinbase()) + .withNumber(parent.getNumber() + 1) + .withTimestamp(2 * System.currentTimeMillis()) + .withExtraData(parent.getExtraData()) + .withTxTrieRoot(HashUtil.EMPTY_TRIE_HASH) + .withEnergyLimit(parent.getNrgLimit()); + AionBlock block = new AionBlock(headerBuilder.build(), Collections.emptyList()); + + assertThat(chain.tryFastImport(block)).isEqualTo(FastImportResult.INVALID_BLOCK); + } + + @Test + public void tryFastImport_withKnownBlock() { + StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder(); + StandaloneBlockchain.Bundle bundle = builder.withValidatorConfiguration("simple").build(); + + StandaloneBlockchain chain = bundle.bc; + + // populate chain at random + generateRandomChainWithoutTransactions(chain, 2, 1); + AionBlock best = chain.getBestBlock(); + + assertThat(chain.tryFastImport(best)).isEqualTo(FastImportResult.KNOWN); + } + + @Test + public void tryFastImport_withNoChild() { + StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder(); + StandaloneBlockchain.Bundle bundle = builder.withValidatorConfiguration("simple").build(); + + StandaloneBlockchain chain = bundle.bc; + + // populate chain at random + generateRandomChainWithoutTransactions(chain, 2, 1); + AionBlock best = chain.getBestBlock(); + + // delete the block from the db + chain.getRepository().getBlockDatabase().delete(best.getHash()); + + assertThat(chain.tryFastImport(best)).isEqualTo(FastImportResult.NO_CHILD); + } + + @Test + public void tryFastImport_withImported() { + StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder(); + StandaloneBlockchain.Bundle bundle = builder.withValidatorConfiguration("simple").build(); + + StandaloneBlockchain chain = bundle.bc; + + // populate chain at random + generateRandomChainWithoutTransactions(chain, 3, 1); + AionBlock best = chain.getBestBlock(); + + // save then delete the block from the db + AionBlock block = chain.getBlockByHash(best.getParentHash()); + chain.getRepository().getBlockDatabase().delete(best.getParentHash()); + + assertThat(chain.tryFastImport(block)).isEqualTo(FastImportResult.IMPORTED); + assertThat(chain.getRepository().getBlockDatabase().get(best.getParentHash())) + .isNotEqualTo(Optional.empty()); + } } diff --git a/modAionImpl/test/org/aion/zero/impl/BlockchainIndexIntegrityTest.java b/modAionImpl/test/org/aion/zero/impl/BlockchainIndexIntegrityTest.java index c14eaa226c..77ef4808e5 100644 --- a/modAionImpl/test/org/aion/zero/impl/BlockchainIndexIntegrityTest.java +++ b/modAionImpl/test/org/aion/zero/impl/BlockchainIndexIntegrityTest.java @@ -8,12 +8,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.util.ByteUtil; + +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; import org.aion.log.AionLoggerFactory; import org.aion.mcf.core.ImportResult; import org.aion.mcf.ds.DataSourceArray; import org.aion.mcf.ds.ObjectDataSource; +import org.aion.util.bytes.ByteUtil; import org.aion.zero.impl.db.AionBlockStore; import org.aion.zero.impl.db.AionRepositoryImpl; import org.aion.zero.impl.types.AionBlock; @@ -62,7 +63,7 @@ public void testIndexIntegrityWithoutGenesis() { chain.getRepository().flush(); AionRepositoryImpl repo = (AionRepositoryImpl) chain.getRepository(); - IByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); + ByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); // deleting the genesis index indexDatabase.delete(ByteUtil.intToBytes(0)); @@ -104,7 +105,7 @@ public void testIndexIntegrityWithoutLevel() { chain.getRepository().flush(); AionRepositoryImpl repo = (AionRepositoryImpl) chain.getRepository(); - IByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); + ByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); // deleting the level 2 index indexDatabase.delete(ByteUtil.intToBytes(2)); @@ -148,7 +149,7 @@ public void testIndexIntegrityWithRecovery() { chain.getRepository().flush(); AionRepositoryImpl repo = (AionRepositoryImpl) chain.getRepository(); - IByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); + ByteArrayKeyValueDatabase indexDatabase = repo.getIndexDatabase(); // corrupting the index at level 2 DataSourceArray> index = diff --git a/modAionImpl/test/org/aion/zero/impl/BlockchainIntegrationTest.java b/modAionImpl/test/org/aion/zero/impl/BlockchainIntegrationTest.java index 82d7e1e666..2050dddce7 100644 --- a/modAionImpl/test/org/aion/zero/impl/BlockchainIntegrationTest.java +++ b/modAionImpl/test/org/aion/zero/impl/BlockchainIntegrationTest.java @@ -5,17 +5,20 @@ import java.math.BigInteger; import java.util.Arrays; import java.util.Collections; -import org.aion.base.db.IRepository; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; import org.aion.crypto.ECKey; import org.aion.crypto.HashUtil; +import org.aion.interfaces.db.Repository; import org.aion.mcf.core.ImportResult; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; +import org.aion.util.bytes.ByteUtil; import org.aion.zero.impl.blockchain.ChainConfiguration; +import org.aion.zero.impl.db.ContractInformation; import org.aion.zero.impl.types.AionBlock; +import org.aion.zero.impl.types.AionBlockSummary; +import org.aion.mcf.tx.TransactionTypes; import org.aion.zero.types.AionTransaction; -import org.junit.Ignore; +import org.aion.zero.types.AionTxReceipt; +import org.apache.commons.lang3.tuple.Pair; import org.junit.Test; /** @@ -54,7 +57,7 @@ public void testSimpleBlockchainLoad() { StandaloneBlockchain.Bundle b = (new StandaloneBlockchain.Builder()).withDefaultAccounts().build(); for (ECKey k : b.privateKeys) { - assertThat(b.bc.getRepository().getBalance(AionAddress.wrap(k.getAddress()))) + assertThat(b.bc.getRepository().getBalance(Address.wrap(k.getAddress()))) .isNotEqualTo(BigInteger.ZERO); } assertThat(b.privateKeys.size()).isEqualTo(10); @@ -73,7 +76,7 @@ public void testCreateNewEmptyBlock() { public void testSimpleFailedTransactionInsufficientBalance() { // generate a recipient final Address receiverAddress = - AionAddress.wrap( + Address.wrap( ByteUtil.hexStringToBytes( "CAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFE")); @@ -108,7 +111,7 @@ public void testSimpleFailedTransactionInsufficientBalance() { public void testSimpleOneTokenBalanceTransfer() { // generate a recipient final Address receiverAddress = - AionAddress.wrap( + Address.wrap( ByteUtil.hexStringToBytes( "CAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFE")); @@ -121,7 +124,7 @@ public void testSimpleOneTokenBalanceTransfer() { final ECKey sender = bundle.privateKeys.get(0); final BigInteger senderInitialBalance = - bc.getRepository().getBalance(AionAddress.wrap(sender.getAddress())); + bc.getRepository().getBalance(Address.wrap(sender.getAddress())); AionTransaction tx = new AionTransaction( @@ -142,10 +145,10 @@ public void testSimpleOneTokenBalanceTransfer() { assertThat(connection).isEqualTo(ImportResult.IMPORTED_BEST); // to be sure, perform some DB tests - IRepository repo = bc.getRepository(); + Repository repo = bc.getRepository(); assertThat(repo.getBalance(receiverAddress)).isEqualTo(BigInteger.valueOf(100)); - assertThat(repo.getBalance(AionAddress.wrap(sender.getAddress()))) + assertThat(repo.getBalance(Address.wrap(sender.getAddress()))) .isEqualTo( senderInitialBalance .subtract(BigInteger.valueOf(21000)) @@ -174,7 +177,7 @@ public void testAppendIncorrectTimestampBlock() { public void testPruningEnabledBalanceTransfer() { // generate a recipient final Address receiverAddress = - AionAddress.wrap( + Address.wrap( ByteUtil.hexStringToBytes( "CAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFE")); @@ -224,14 +227,14 @@ public void testDeployCryptoKitties() { .withValidatorConfiguration("simple") .withDefaultAccounts() .build(); - StandaloneBlockchain bc = bundle.bc; + StandaloneBlockchain blockchain = bundle.bc; final ECKey sender = bundle.privateKeys.get(0); AionTransaction contractDeploymentTx = new AionTransaction( BigInteger.ZERO.toByteArray(), - AionAddress.EMPTY_ADDRESS(), + null, BigInteger.ZERO.toByteArray(), ByteUtil.hexStringToBytes(cryptoKittiesCode), 4699999L, @@ -240,8 +243,25 @@ public void testDeployCryptoKitties() { contractDeploymentTx.sign(sender); AionBlock block = - bc.createNewBlock(bc.getGenesis(), Arrays.asList(contractDeploymentTx), true); - assertThat(bc.tryToConnect(block)).isEqualTo(ImportResult.IMPORTED_BEST); + blockchain.createNewBlock( + blockchain.getGenesis(), Arrays.asList(contractDeploymentTx), true); + + Pair connectResult = + blockchain.tryToConnectAndFetchSummary(block); + AionTxReceipt receipt = connectResult.getRight().getReceipts().get(0); + + assertThat(connectResult.getLeft()).isEqualTo(ImportResult.IMPORTED_BEST); + assertThat(receipt.isSuccessful()).isTrue(); + + // ensure the contract information was saved + ContractInformation ci = + blockchain + .getRepository() + .getIndexedContractInformation(contractDeploymentTx.getContractAddress()); + assertThat(ci).isNotNull(); + assertThat(ci.getInceptionBlock()).isEqualTo(block.getNumber()); + assertThat(ci.getVmUsed()).isEqualTo(TransactionTypes.FVM_CREATE_CODE); + assertThat(ci.isComplete()).isEqualTo(true); } /** diff --git a/modAionImpl/test/org/aion/zero/impl/BlockchainRewardTest.java b/modAionImpl/test/org/aion/zero/impl/BlockchainRewardTest.java index 987ec84fda..ee4399d44e 100644 --- a/modAionImpl/test/org/aion/zero/impl/BlockchainRewardTest.java +++ b/modAionImpl/test/org/aion/zero/impl/BlockchainRewardTest.java @@ -6,7 +6,8 @@ import java.util.Collections; import org.aion.mcf.blockchain.IBlockConstants; import org.aion.mcf.core.ImportResult; -import org.aion.vm.api.interfaces.Address; + +import org.aion.types.Address; import org.aion.zero.api.BlockConstants; import org.aion.zero.impl.types.AionBlock; import org.junit.Ignore; diff --git a/modAionImpl/test/org/aion/zero/impl/BlockchainTestUtils.java b/modAionImpl/test/org/aion/zero/impl/BlockchainTestUtils.java index 414741bce7..3b766a7363 100644 --- a/modAionImpl/test/org/aion/zero/impl/BlockchainTestUtils.java +++ b/modAionImpl/test/org/aion/zero/impl/BlockchainTestUtils.java @@ -7,12 +7,12 @@ import java.util.List; import java.util.Map; import java.util.Random; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.crypto.HashUtil; import org.aion.mcf.core.ImportResult; -import org.aion.vm.api.interfaces.Address; + import org.aion.zero.impl.db.AionRepositoryImpl; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.types.AionTransaction; @@ -46,7 +46,7 @@ public static List generateTransactions( // get the current nonce for each account Map nonces = new HashMap<>(); for (ECKey key : accounts) { - nonces.put(key, repo.getNonce(new AionAddress(key.getAddress()))); + nonces.put(key, repo.getNonce(new Address(key.getAddress()))); } List transactions = new ArrayList<>(); @@ -59,7 +59,7 @@ public static List generateTransactions( // generate a random Aion account address byte[] aionBytes = HashUtil.h256(accountNonce.toByteArray()); aionBytes[0] = (byte) 0xa0; // the Aion prefix - Address destAddr = new AionAddress(aionBytes); + Address destAddr = new Address(aionBytes); AionTransaction newTx = new AionTransaction( accountNonce.toByteArray(), diff --git a/modAionImpl/test/org/aion/zero/impl/GenesisSpecificationTest.java b/modAionImpl/test/org/aion/zero/impl/GenesisSpecificationTest.java index 9a02d2c6a0..28ca2d3c64 100644 --- a/modAionImpl/test/org/aion/zero/impl/GenesisSpecificationTest.java +++ b/modAionImpl/test/org/aion/zero/impl/GenesisSpecificationTest.java @@ -6,11 +6,11 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; +import org.aion.types.Address; import org.aion.crypto.HashUtil; import org.aion.mcf.core.AccountState; -import org.aion.vm.api.interfaces.Address; + +import org.aion.util.bytes.ByteUtil; import org.aion.zero.exceptions.HeaderStructureException; import org.junit.Test; @@ -72,17 +72,17 @@ public void overrideGenesisBlockTest() throws HeaderStructureException { AccountState defaultAccountState = new AccountState(overrideValue, overrideValue); HashSet
    accountStateSet = new HashSet<>(); - accountStateSet.add(AionAddress.wrap(overrideHash)); + accountStateSet.add(Address.wrap(overrideHash)); genesisBuilder .withParentHash(overrideHash) - .withCoinbase(AionAddress.wrap(overrideAddress)) + .withCoinbase(Address.wrap(overrideAddress)) .withDifficulty(overrideValue.toByteArray()) .withEnergyLimit(overrideValue.longValue()) .withNonce(overrideHash) .withNumber(overrideValue.longValue()) .withTimestamp(overrideValue.longValue()) - .addPreminedAccount(AionAddress.wrap(overrideAddress), defaultAccountState); + .addPreminedAccount(Address.wrap(overrideAddress), defaultAccountState); AionGenesis genesis = genesisBuilder.build(); diff --git a/modAionImpl/test/org/aion/zero/impl/GenesisTestNetJsonTest.java b/modAionImpl/test/org/aion/zero/impl/GenesisTestNetJsonTest.java index e498b758c4..db2a43097e 100644 --- a/modAionImpl/test/org/aion/zero/impl/GenesisTestNetJsonTest.java +++ b/modAionImpl/test/org/aion/zero/impl/GenesisTestNetJsonTest.java @@ -7,10 +7,9 @@ import java.io.IOException; import java.math.BigInteger; import java.util.Map; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; +import org.aion.types.Address; import org.aion.mcf.core.AccountState; -import org.aion.vm.api.interfaces.Address; +import org.aion.util.bytes.ByteUtil; import org.aion.zero.exceptions.HeaderStructureException; import org.junit.BeforeClass; import org.junit.Test; @@ -51,32 +50,32 @@ public void testNetJsonLoad() throws Exception { Address[] accString = new Address[] { - AionAddress.wrap( + Address.wrap( "0xa0483412e8c8e769df037231d336e96f7f6d843cf7224c3d8fbe0ec7cdc12ac6"), - AionAddress.wrap( + Address.wrap( "0xa0353561f8b6b5a8b56d535647a4ddd7278e80c2494e3314d1f0605470f56925"), - AionAddress.wrap( + Address.wrap( "0xa0274c1858ca50576f4d4d18b719787b76bb454c33749172758a620555bf4586"), - AionAddress.wrap( + Address.wrap( "0xa06691a968e8fe22dc79b6dd503d44cb96d9a523ae265b63c6752389be90185d"), - AionAddress.wrap( + Address.wrap( "0xa0a95b372efe55c77a75364407f0403dfefd3131519ca980b2d92b1d2d7297a7"), - AionAddress.wrap( + Address.wrap( "0xa07262e1d026fca027e5f4f38668303b74a2bba8bd07470fa39d0f3b03f882f1"), - AionAddress.wrap( + Address.wrap( "0xa08f92c80e34c95b8b2e8cb208d47e3e6048b7e0ea44d866e33e865c365b1417"), - AionAddress.wrap( + Address.wrap( "0xa022045f22772463c94e08d1fd32f7b251d4c9cfd1c92e039f1517b906776283"), - AionAddress.wrap( + Address.wrap( "0xa04c282f636feff4d6b35174fc2d8e05c23df4b1d59508712712627184dd8a93"), - AionAddress.wrap( + Address.wrap( "0xa0f8654c63ae53598cf42435f53b1ebd9b7df6cbceba10af235aa2393f03034c"), - AionAddress.wrap( + Address.wrap( "0xa0f3defb01b531c5a28680eb928e79ea18bc155f1060e1d923d660d74883518b") }; Address tokenAddress = - new AionAddress( + new Address( "0xa02198c9192bb89e9b2e8536d96cbf287fde80625afcf1a5e5632e23c1260d61"); for (Address a : accString) { @@ -96,7 +95,7 @@ public void testNetJsonLoad() throws Exception { assertThat(genesis.getDifficultyBI()).isEqualTo(BigInteger.valueOf(16)); assertThat(genesis.getCoinbase()) .isEqualTo( - new AionAddress( + new Address( "0x0000000000000000000000000000000000000000000000000000000000000000")); assertThat(genesis.getTimestamp()).isEqualTo(1497536993L); assertThat(genesis.getParentHash()) diff --git a/modAionImpl/test/org/aion/zero/impl/MockRepositoryConfig.java b/modAionImpl/test/org/aion/zero/impl/MockRepositoryConfig.java index a86cd506e7..0025a19c35 100644 --- a/modAionImpl/test/org/aion/zero/impl/MockRepositoryConfig.java +++ b/modAionImpl/test/org/aion/zero/impl/MockRepositoryConfig.java @@ -1,18 +1,18 @@ package org.aion.zero.impl; import java.util.Properties; -import org.aion.base.db.IContractDetails; -import org.aion.base.db.IPruneConfig; -import org.aion.base.db.IRepositoryConfig; import org.aion.db.impl.DBVendor; import org.aion.db.impl.DatabaseFactory; +import org.aion.interfaces.db.ContractDetails; +import org.aion.interfaces.db.PruneConfig; +import org.aion.interfaces.db.RepositoryConfig; import org.aion.mcf.config.CfgPrune; import org.aion.zero.impl.db.ContractDetailsAion; -public class MockRepositoryConfig implements IRepositoryConfig { +public class MockRepositoryConfig implements RepositoryConfig { private DBVendor vendor = DBVendor.MOCKDB; - private IPruneConfig pruneConfig = new CfgPrune(false); + private PruneConfig pruneConfig = new CfgPrune(false); @Override public String getDbPath() { @@ -20,12 +20,12 @@ public String getDbPath() { } @Override - public IPruneConfig getPruneConfig() { + public PruneConfig getPruneConfig() { return pruneConfig; } @Override - public IContractDetails contractDetailsImpl() { + public ContractDetails contractDetailsImpl() { return ContractDetailsAion.createForTesting(0, 1000000).getDetails(); } @@ -41,7 +41,7 @@ public MockRepositoryConfig(DBVendor vendor) { this.vendor = vendor; } - public MockRepositoryConfig(IPruneConfig _pruneConfig) { + public MockRepositoryConfig(PruneConfig _pruneConfig) { this.pruneConfig = _pruneConfig; } } diff --git a/modAionImpl/test/org/aion/zero/impl/PendingStateTest.java b/modAionImpl/test/org/aion/zero/impl/PendingStateTest.java index 2aaede7a99..195cd00253 100644 --- a/modAionImpl/test/org/aion/zero/impl/PendingStateTest.java +++ b/modAionImpl/test/org/aion/zero/impl/PendingStateTest.java @@ -1,20 +1,32 @@ package org.aion.zero.impl; +import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import java.math.BigInteger; -import org.aion.base.type.AionAddress; +import java.util.Collections; +import org.aion.avm.core.dappreading.JarBuilder; +import org.aion.avm.core.util.CodeAndArguments; +import org.aion.avm.userlib.abi.ABIEncoder; import org.aion.crypto.ECKey; import org.aion.mcf.blockchain.TxResponse; -import org.aion.vm.api.interfaces.Address; +import org.aion.mcf.core.ImportResult; +import org.aion.mcf.tx.TransactionTypes; +import org.aion.types.Address; +import org.aion.vm.VirtualMachineProvider; import org.aion.zero.impl.config.CfgAion; +import org.aion.zero.impl.types.AionBlock; +import org.aion.zero.impl.types.AionBlockSummary; +import org.aion.zero.impl.vm.contracts.AvmHelloWorld; import org.aion.zero.types.AionTransaction; +import org.aion.zero.types.AionTxReceipt; +import org.apache.commons.lang3.tuple.Pair; import org.junit.Test; public class PendingStateTest { @Test - public void TestAddPendingTransactionSuccess() { + public void testAddPendingTransactionSuccess() { StandaloneBlockchain.Bundle bundle = new StandaloneBlockchain.Builder() @@ -27,7 +39,7 @@ public void TestAddPendingTransactionSuccess() { AionHub hub = AionHub.createForTesting(CfgAion.inst(), bc, bc.getRepository()); - Address to = new AionAddress(bundle.privateKeys.get(0).getAddress()); + Address to = new Address(bundle.privateKeys.get(0).getAddress()); ECKey signer = bundle.privateKeys.get(1); // Successful transaction @@ -47,7 +59,7 @@ public void TestAddPendingTransactionSuccess() { } @Test - public void TestAddPendingTransactionInvalidNrgPrice() { + public void testAddPendingTransactionInvalidNrgPrice() { StandaloneBlockchain.Bundle bundle = new StandaloneBlockchain.Builder() @@ -60,7 +72,7 @@ public void TestAddPendingTransactionInvalidNrgPrice() { AionHub hub = AionHub.createForTesting(CfgAion.inst(), bc, bc.getRepository()); - Address to = new AionAddress(bundle.privateKeys.get(0).getAddress()); + Address to = new Address(bundle.privateKeys.get(0).getAddress()); ECKey signer = bundle.privateKeys.get(1); // Invalid Nrg Price transaction @@ -78,4 +90,113 @@ public void TestAddPendingTransactionInvalidNrgPrice() { assertEquals( hub.getPendingState().addPendingTransaction(tx), TxResponse.INVALID_TX_NRG_PRICE); } + + @Test + public void testAddPendingTransaction_AVMContractDeploy_Success() { + StandaloneBlockchain.Bundle bundle = + new StandaloneBlockchain.Builder() + .withDefaultAccounts() + .withValidatorConfiguration("simple") + .withAvmEnabled() + .build(); + StandaloneBlockchain blockchain = bundle.bc; + ECKey deployerKey = bundle.privateKeys.get(0); + + CfgAion.inst().setGenesis(blockchain.getGenesis()); + VirtualMachineProvider.initializeAllVirtualMachines(); + + AionHub hub = + AionHub.createForTesting(CfgAion.inst(), blockchain, blockchain.getRepository()); + + // Successful transaction + byte[] jar = + new CodeAndArguments( + JarBuilder.buildJarForMainAndClassesAndUserlib(AvmHelloWorld.class), + new byte[0]) + .encodeToBytes(); + + AionTransaction transaction = + new AionTransaction( + BigInteger.ZERO.toByteArray(), + Address.wrap(deployerKey.getAddress()), + null, + BigInteger.ZERO.toByteArray(), + jar, + 5_000_000, + 10_000_000_000L, + TransactionTypes.AVM_CREATE_CODE); + transaction.sign(deployerKey); + + assertEquals(hub.getPendingState().addPendingTransaction(transaction), TxResponse.SUCCESS); + VirtualMachineProvider.shutdownAllVirtualMachines(); + } + + @Test + public void testAddPendingTransaction_AVMContractCall_Success() { + StandaloneBlockchain.Bundle bundle = + new StandaloneBlockchain.Builder() + .withDefaultAccounts() + .withValidatorConfiguration("simple") + .withAvmEnabled() + .build(); + StandaloneBlockchain blockchain = bundle.bc; + ECKey deployerKey = bundle.privateKeys.get(0); + + CfgAion.inst().setGenesis(blockchain.getGenesis()); + VirtualMachineProvider.initializeAllVirtualMachines(); + + // Successful transaction + byte[] jar = + new CodeAndArguments( + JarBuilder.buildJarForMainAndClassesAndUserlib(AvmHelloWorld.class), + new byte[0]) + .encodeToBytes(); + + AionTransaction transaction = + new AionTransaction( + BigInteger.ZERO.toByteArray(), + Address.wrap(deployerKey.getAddress()), + null, + BigInteger.ZERO.toByteArray(), + jar, + 5_000_000, + 10_000_000_000L, + TransactionTypes.AVM_CREATE_CODE); + transaction.sign(deployerKey); + + AionBlock block = + blockchain.createNewBlock( + blockchain.getBestBlock(), Collections.singletonList(transaction), false); + Pair connectResult = + blockchain.tryToConnectAndFetchSummary(block); + AionTxReceipt receipt = connectResult.getRight().getReceipts().get(0); + + // Check the block was imported, the contract has the Avm prefix, and deployment succeeded. + assertThat(connectResult.getLeft()).isEqualTo(ImportResult.IMPORTED_BEST); + // verify that the output is indeed the contract address + assertThat(transaction.getContractAddress().toBytes()) + .isEqualTo(receipt.getTransactionOutput()); + + AionHub hub = + AionHub.createForTesting(CfgAion.inst(), blockchain, blockchain.getRepository()); + + Address contract = Address.wrap(receipt.getTransactionOutput()); + + byte[] call = ABIEncoder.encodeOneString("sayHello"); + transaction = + new AionTransaction( + BigInteger.ONE.toByteArray(), + Address.wrap(deployerKey.getAddress()), + contract, + BigInteger.ZERO.toByteArray(), + call, + 2_000_000, + 10_000_000_000L, + TransactionTypes.DEFAULT); + + transaction.sign(deployerKey); + + assertEquals(hub.getPendingState().addPendingTransaction(transaction), TxResponse.SUCCESS); + VirtualMachineProvider.shutdownAllVirtualMachines(); + } } diff --git a/modAionImpl/test/org/aion/zero/impl/StandaloneBlockchainTest.java b/modAionImpl/test/org/aion/zero/impl/StandaloneBlockchainTest.java index b2843d0a2a..3f31be47db 100644 --- a/modAionImpl/test/org/aion/zero/impl/StandaloneBlockchainTest.java +++ b/modAionImpl/test/org/aion/zero/impl/StandaloneBlockchainTest.java @@ -4,7 +4,7 @@ import java.math.BigInteger; import java.util.Collections; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.zero.impl.types.AionBlock; import org.junit.Test; @@ -21,7 +21,7 @@ public void testStandaloneBlockchainGenerateAccounts() { assertThat(bundle.privateKeys.size()).isEqualTo(10); for (ECKey k : bundle.privateKeys) { - assertThat(bundle.bc.getRepository().getBalance(new AionAddress(k.getAddress()))) + assertThat(bundle.bc.getRepository().getBalance(new Address(k.getAddress()))) .isGreaterThan(BigInteger.ZERO); } } diff --git a/modAionImpl/test/org/aion/zero/impl/blockchain/AionTxExecSummaryTest.java b/modAionImpl/test/org/aion/zero/impl/blockchain/AionTxExecSummaryTest.java index 96496f86ae..a07ee791df 100644 --- a/modAionImpl/test/org/aion/zero/impl/blockchain/AionTxExecSummaryTest.java +++ b/modAionImpl/test/org/aion/zero/impl/blockchain/AionTxExecSummaryTest.java @@ -4,10 +4,10 @@ import java.math.BigInteger; import java.util.Collections; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.crypto.HashUtil; import org.aion.mcf.vm.types.Bloom; -import org.aion.vm.api.interfaces.Address; + import org.aion.zero.types.AionTransaction; import org.aion.zero.types.AionTxExecSummary; import org.aion.zero.types.AionTxReceipt; @@ -17,7 +17,7 @@ public class AionTxExecSummaryTest { private Address defaultAddress = - AionAddress.wrap("CAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFE"); + Address.wrap("CAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFE"); @Test public void testRLPEncoding() { diff --git a/modAionImpl/test/org/aion/zero/impl/blockchain/PendingTxCacheTest.java b/modAionImpl/test/org/aion/zero/impl/blockchain/PendingTxCacheTest.java index d2d3ea5b24..874f72e11d 100644 --- a/modAionImpl/test/org/aion/zero/impl/blockchain/PendingTxCacheTest.java +++ b/modAionImpl/test/org/aion/zero/impl/blockchain/PendingTxCacheTest.java @@ -7,12 +7,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.aion.base.type.AionAddress; -import org.aion.base.type.ITransaction; -import org.aion.base.util.ByteUtil; + +import org.aion.interfaces.tx.Transaction; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; -import org.aion.vm.api.interfaces.Address; + +import org.aion.util.bytes.ByteUtil; import org.aion.zero.types.AionTransaction; import org.junit.Before; import org.junit.Test; @@ -44,8 +45,8 @@ private List getMockTransaction(int startNonce, int num, int ke AionTransaction tx = new AionTransaction( BigInteger.valueOf(i).toByteArray(), - AionAddress.wrap(key.get(keyIndex).getAddress()), - AionAddress.wrap( + Address.wrap(key.get(keyIndex).getAddress()), + Address.wrap( "0000000000000000000000000000000000000000000000000000000000000001"), ByteUtil.hexStringToBytes("1"), ByteUtil.hexStringToBytes("1"), @@ -74,8 +75,8 @@ private List getMockBigTransaction( AionTransaction tx = new AionTransaction( BigInteger.valueOf(i).toByteArray(), - AionAddress.wrap(key.get(keyIndex).getAddress()), - AionAddress.wrap( + Address.wrap(key.get(keyIndex).getAddress()), + Address.wrap( "0000000000000000000000000000000000000000000000000000000000000001"), ByteUtil.hexStringToBytes("1"), ByteUtil.hexStringToBytes(data), @@ -95,7 +96,7 @@ public void addCacheTxTest() { PendingTxCache cache = new PendingTxCache(1); List txn = getMockTransaction(0, 10, 0); - for (ITransaction tx : txn) { + for (Transaction tx : txn) { cache.addCacheTx((AionTransaction) tx); } @@ -109,7 +110,7 @@ public void addCacheTxTest2() { List txn = getMockTransaction(0, 10, 0); txn.addAll(getMockTransaction(0, 10, 1)); - for (ITransaction tx : txn) { + for (Transaction tx : txn) { cache.addCacheTx((AionTransaction) tx); } @@ -140,14 +141,14 @@ public void addCacheTxTest4() { List txn = getMockTransaction(0, 10, 0); txn.addAll(getMockTransaction(5, 10, 0)); - for (ITransaction tx : txn) { + for (Transaction tx : txn) { cache.addCacheTx((AionTransaction) tx); } assertTrue(cache.cacheTxSize() == 15); Map cacheMap = - cache.getCacheTx(AionAddress.wrap(key.get(0).getAddress())); + cache.getCacheTx(Address.wrap(key.get(0).getAddress())); assertTrue(cacheMap.size() == 15); } @@ -159,20 +160,20 @@ public void flushTest1() { List txn = getMockTransaction(0, 10, 0); List newCache; - for (ITransaction tx : txn) { + for (Transaction tx : txn) { cache.addCacheTx((AionTransaction) tx); } assertTrue(cache.cacheTxSize() == 10); Map map = new HashMap<>(); - map.put(AionAddress.wrap(key.get(0).getAddress()), BigInteger.TWO); + map.put(Address.wrap(key.get(0).getAddress()), BigInteger.TWO); newCache = cache.flush(map); assertTrue(newCache.size() == 1); Map cacheMap = - cache.getCacheTx(AionAddress.wrap(key.get(0).getAddress())); + cache.getCacheTx(Address.wrap(key.get(0).getAddress())); assertTrue(cacheMap.size() == 8); } @@ -183,18 +184,18 @@ public void flushTest2() { List txn = getMockTransaction(0, 10, 0); - for (ITransaction tx : txn) { + for (Transaction tx : txn) { cache.addCacheTx((AionTransaction) tx); } assertTrue(cache.cacheTxSize() == 10); Map map = new HashMap<>(); - map.put(AionAddress.wrap(key.get(1).getAddress()), BigInteger.TWO); + map.put(Address.wrap(key.get(1).getAddress()), BigInteger.TWO); cache.flush(map); Map cacheMap = - cache.getCacheTx(AionAddress.wrap(key.get(0).getAddress())); + cache.getCacheTx(Address.wrap(key.get(0).getAddress())); assertTrue(cacheMap.size() == 10); } @@ -208,7 +209,7 @@ public void flushTest3() { int singleTxSize = txn.get(0).getEncoded().length; int txSize = 0; - for (ITransaction tx : txn) { + for (Transaction tx : txn) { cache.addCacheTx((AionTransaction) tx); txSize += tx.getEncoded().length; } @@ -216,13 +217,13 @@ public void flushTest3() { assertTrue(cache.cacheTxSize() == 10); Map map = new HashMap<>(); - map.put(AionAddress.wrap(key.get(0).getAddress()), BigInteger.TWO); + map.put(Address.wrap(key.get(0).getAddress()), BigInteger.TWO); cache.flush(map); assertTrue(cache.cacheSize() == (txSize - (singleTxSize << 1))); Map cacheMap = - cache.getCacheTx(AionAddress.wrap(key.get(0).getAddress())); + cache.getCacheTx(Address.wrap(key.get(0).getAddress())); assertTrue(cacheMap.size() == 8); } @@ -237,7 +238,7 @@ public void flushTest4() { int singleTxSize = txn.get(0).getEncoded().length; int txSize = 0; - for (ITransaction tx : txn) { + for (Transaction tx : txn) { cache.addCacheTx((AionTransaction) tx); txSize += tx.getEncoded().length; } @@ -245,17 +246,17 @@ public void flushTest4() { assertTrue(cache.cacheTxSize() == 20); Map map = new HashMap<>(); - map.put(AionAddress.wrap(key.get(0).getAddress()), BigInteger.TWO); - map.put(AionAddress.wrap(key.get(1).getAddress()), BigInteger.TWO); + map.put(Address.wrap(key.get(0).getAddress()), BigInteger.TWO); + map.put(Address.wrap(key.get(1).getAddress()), BigInteger.TWO); cache.flush(map); assertTrue(cache.cacheSize() == (txSize - (singleTxSize << 2))); Map cacheMap = - cache.getCacheTx(AionAddress.wrap(key.get(0).getAddress())); + cache.getCacheTx(Address.wrap(key.get(0).getAddress())); assertTrue(cacheMap.size() == 8); - cacheMap = cache.getCacheTx(AionAddress.wrap(key.get(1).getAddress())); + cacheMap = cache.getCacheTx(Address.wrap(key.get(1).getAddress())); assertTrue(cacheMap.size() == 8); } @@ -268,24 +269,24 @@ public void flushTest5() { List txn = getMockTransaction(0, input, 0); txn.addAll(getMockTransaction(0, input, 1)); - for (ITransaction tx : txn) { + for (Transaction tx : txn) { cache.addCacheTx((AionTransaction) tx); } assertTrue(cache.cacheTxSize() == 20000); Map map = new HashMap<>(); - map.put(AionAddress.wrap(key.get(0).getAddress()), BigInteger.valueOf(input + 1)); - map.put(AionAddress.wrap(key.get(1).getAddress()), BigInteger.valueOf(input + 1)); + map.put(Address.wrap(key.get(0).getAddress()), BigInteger.valueOf(input + 1)); + map.put(Address.wrap(key.get(1).getAddress()), BigInteger.valueOf(input + 1)); cache.flush(map); assertTrue(cache.cacheSize() == 0); Map cacheMap = - cache.getCacheTx(AionAddress.wrap(key.get(0).getAddress())); + cache.getCacheTx(Address.wrap(key.get(0).getAddress())); assertTrue(cacheMap.size() == 0); - cacheMap = cache.getCacheTx(AionAddress.wrap(key.get(1).getAddress())); + cacheMap = cache.getCacheTx(Address.wrap(key.get(1).getAddress())); assertTrue(cacheMap.size() == 0); } @@ -295,12 +296,12 @@ public void maxPendingSizeTest1() { PendingTxCache cache = new PendingTxCache(1); List txn = getMockTransaction(0, 680, 0); - for (ITransaction tx : txn) { + for (Transaction tx : txn) { cache.addCacheTx((AionTransaction) tx); } Map cacheMap = - cache.getCacheTx(AionAddress.wrap(key.get(0).getAddress())); + cache.getCacheTx(Address.wrap(key.get(0).getAddress())); assertTrue(cacheMap.size() == 659); } @@ -310,7 +311,7 @@ public void maxPendingSizeTest2() { PendingTxCache cache = new PendingTxCache(1); List txn = getMockTransaction(0, 659, 0); - for (ITransaction tx : txn) { + for (Transaction tx : txn) { cache.addCacheTx((AionTransaction) tx); } @@ -321,7 +322,7 @@ public void maxPendingSizeTest2() { assertTrue(cache.cacheTxSize() == 659); Map cacheMap = - cache.getCacheTx(AionAddress.wrap(key.get(0).getAddress())); + cache.getCacheTx(Address.wrap(key.get(0).getAddress())); assertTrue(cacheMap.size() == 659); } @@ -342,7 +343,7 @@ public void maxPendingSizeTest3() { assertTrue(cache.cacheTxSize() == 658); Map cacheMap = - cache.getCacheTx(AionAddress.wrap(key.get(0).getAddress())); + cache.getCacheTx(Address.wrap(key.get(0).getAddress())); assertTrue(cacheMap.size() == 658); } @@ -363,7 +364,7 @@ public void maxPendingSizeTest4() { assertTrue(cache.cacheTxSize() == 652); Map cacheMap = - cache.getCacheTx(AionAddress.wrap(key.get(0).getAddress())); + cache.getCacheTx(Address.wrap(key.get(0).getAddress())); assertTrue(cacheMap.size() == 652); } @@ -381,7 +382,7 @@ public void maxPendingSizeTest5() { assertTrue(cache.cacheTxSize() == 659); Map cacheMap = - cache.getCacheTx(AionAddress.wrap(key.get(0).getAddress())); + cache.getCacheTx(Address.wrap(key.get(0).getAddress())); assertTrue(cache.cacheTxSize() == 659); AionTransaction tx = getMockBigTransaction(100, 1, 0, 2000).get(0); @@ -404,7 +405,7 @@ public void maxPendingSizeTest6() { assertTrue(cache.cacheTxSize() == 659); Map cacheMap = - cache.getCacheTx(AionAddress.wrap(key.get(0).getAddress())); + cache.getCacheTx(Address.wrap(key.get(0).getAddress())); assertTrue(cacheMap.size() == 659); AionTransaction tx = getMockBigTransaction(100, 1, 0, 199_500).get(0); @@ -426,7 +427,7 @@ public void maxPendingSizeTest7() { assertTrue(cache.cacheTxSize() == 659); Map cacheMap = - cache.getCacheTx(AionAddress.wrap(key.get(0).getAddress())); + cache.getCacheTx(Address.wrap(key.get(0).getAddress())); assertTrue(cacheMap.size() == 659); AionTransaction tx = getMockBigTransaction(100, 1, 0, 199_500).get(0); @@ -470,8 +471,8 @@ public void benchmark1() { System.out.println("flush starting"); Map flushMap = new HashMap<>(); - flushMap.put(AionAddress.wrap(key.get(0).getAddress()), BigInteger.valueOf(remove)); - flushMap.put(AionAddress.wrap(key.get(1).getAddress()), BigInteger.valueOf(remove)); + flushMap.put(Address.wrap(key.get(0).getAddress()), BigInteger.valueOf(remove)); + flushMap.put(Address.wrap(key.get(1).getAddress()), BigInteger.valueOf(remove)); t1 = System.currentTimeMillis(); cache.flush(flushMap); @@ -479,10 +480,10 @@ public void benchmark1() { System.out.println("flush took " + t2 + " ms"); Map cacheMap = - cache.getCacheTx(AionAddress.wrap(key.get(0).getAddress())); + cache.getCacheTx(Address.wrap(key.get(0).getAddress())); assertTrue(cacheMap.size() == input - remove); - cacheMap = cache.getCacheTx(AionAddress.wrap(key.get(1).getAddress())); + cacheMap = cache.getCacheTx(Address.wrap(key.get(1).getAddress())); assertTrue(cacheMap.size() == input - remove); } } diff --git a/modAionImpl/test/org/aion/zero/impl/cli/CliTest.java b/modAionImpl/test/org/aion/zero/impl/cli/CliTest.java index cddcdadeb6..dec15c8d98 100644 --- a/modAionImpl/test/org/aion/zero/impl/cli/CliTest.java +++ b/modAionImpl/test/org/aion/zero/impl/cli/CliTest.java @@ -26,11 +26,11 @@ import java.util.Set; import junitparams.JUnitParamsRunner; import junitparams.Parameters; -import org.aion.base.util.Hex; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.mcf.account.Keystore; import org.aion.mcf.config.Cfg; +import org.aion.util.conversions.Hex; import org.aion.zero.impl.cli.Cli.ReturnType; import org.aion.zero.impl.cli.Cli.TaskPriority; import org.aion.zero.impl.config.CfgAion; diff --git a/modAionImpl/test/org/aion/zero/impl/consensus/BalanceTransferConsensusTest.java b/modAionImpl/test/org/aion/zero/impl/consensus/BalanceTransferConsensusTest.java new file mode 100644 index 0000000000..362b98d826 --- /dev/null +++ b/modAionImpl/test/org/aion/zero/impl/consensus/BalanceTransferConsensusTest.java @@ -0,0 +1,237 @@ +package org.aion.zero.impl.consensus; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.aion.mcf.core.ImportResult; +import org.aion.types.Address; +import org.aion.vm.VirtualMachineProvider; +import org.aion.zero.impl.StandaloneBlockchain; +import org.aion.zero.impl.StandaloneBlockchain.Builder; +import org.aion.zero.impl.StandaloneBlockchain.Bundle; +import org.aion.util.conversions.Hex; +import org.aion.zero.impl.types.AionBlock; +import org.aion.zero.impl.types.AionBlockSummary; +import org.aion.zero.types.AionTransaction; +import org.aion.zero.types.AionTxReceipt; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** Consensus tests on balance transfers to regular accounts (not contracts). */ +public class BalanceTransferConsensusTest { + private static final byte[] SENDER_KEY = + org.aion.util.conversions.Hex.decode( + "81e071e5bf2c155f641641d88b5956af52c768fbb90968979b20858d65d71f32aa935b67ac46480caaefcdd56dd31862e578694a99083e9fad88cb6df89fc7cb"); + private static final byte[] SENDER_ADDR = + org.aion.util.conversions.Hex.decode( + "a00a4175a89a6ffbfdc45782771fba3f5e9da36baa69444f8f95e325430463e7"); + private static final BigInteger SENDER_BALANCE = new BigInteger("1000000000000000000000000"); + private static final byte[] MINER = + Hex.decode("0000000000000000000000000000000000000000000000000000000000000000"); + private static final long ENERGY_PRICE = 10_123_456_789L; + + private StandaloneBlockchain blockchain; + + @Before + public void setup() { + Bundle bundle = + new Builder() + .withDefaultAccounts( + Collections.singletonList( + org.aion.crypto.ECKeyFac.inst().fromPrivate(SENDER_KEY))) + .withValidatorConfiguration("simple") + .withAvmEnabled() + .build(); + this.blockchain = bundle.bc; + VirtualMachineProvider.initializeAllVirtualMachines(); + } + + @After + public void tearDown() { + this.blockchain = null; + VirtualMachineProvider.shutdownAllVirtualMachines(); + } + + private static final String RECIPIENT1 = + "a04272bb5f935fb170baf2998cb25dd15cc5794e7c5bac7241bec00c4971c7f8"; + private static final String STATE_ROOT1 = + "d60ebda1ffb8ebdf1f8e92e66c6260320918efc2f5beba06e2a535487f2d8826"; + private static final String BLOCK_RECEIPTS_ROOT1 = + "b6308552ce9fc04bc27d9cab5e4e8a39795b3f711dbef8c53776700110268a50"; + private static final String RECEIPT_TRIE1 = + "f90125a0c0dce68e921f0559c03d8b072fd9b723961c7d17bbf7745ef45b4d5d721b264bb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"; + + @Test + public void testBalanceTransfer() { + BigInteger amount = BigInteger.TEN.pow(23).add(BigInteger.valueOf(13_897_651)); + BigInteger initialBalance = getBalance(Address.wrap(SENDER_ADDR)); + assertEquals(SENDER_BALANCE, initialBalance); + assertArrayEquals(MINER, this.blockchain.getMinerCoinbase().toBytes()); + + Address address = Address.wrap(Hex.decode(RECIPIENT1)); + assertEquals(BigInteger.ZERO, getBalance(address)); + + AionTransaction transaction = makeBalanceTransferTransaction(address, amount); + + // Process the transaction. + Pair results = processTransactions(transaction, 1); + + // Collect the consensus information from the block & receipt. + AionBlockSummary blockSummary = results.getRight(); + AionTxReceipt receipt = blockSummary.getSummaries().get(0).getReceipt(); + assertTrue(receipt.isSuccessful()); + + byte[] stateRoot = blockSummary.getBlock().getStateRoot(); + byte[] blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot(); + byte[] receiptTrieEncoded = receipt.getReceiptTrieEncoded(); + + // Verify the consensus information. + assertArrayEquals(Hex.decode(STATE_ROOT1), stateRoot); + assertArrayEquals(Hex.decode(BLOCK_RECEIPTS_ROOT1), blockReceiptsRoot); + assertArrayEquals(Hex.decode(RECEIPT_TRIE1), receiptTrieEncoded); + + // Verify the sender's balance is as expected. + BigInteger expectedBalance = new BigInteger("899999999785463689829861"); + assertEquals(expectedBalance, getBalance(Address.wrap(SENDER_ADDR))); + + // Verify that the recipient's balance is as expected. + assertEquals(amount, getBalance(address)); + + // Verify that the miner's balance is as expected. + BigInteger expectedMinerBalance = new BigInteger("749212067557748651"); + assertEquals(expectedMinerBalance, getBalance(Address.wrap(MINER))); + } + + private static final String RECIPIENT2 = + "a03272bb5f935fb170baf2998cb25dd15cc5794e7c5bac7241bec00c4971c7f7"; + private static final String RECIPIENT3 = + "a05272bb5f935fb170baf2998cb25dd15cc5794e7c5bac7241bec00c4971c7f9"; + private static final String RECIPIENT4 = + "a06272bb5f935fb170baf2998cb25dd15cc5794e7c5bac7241bec00c4971c7fa"; + private static final String RECIPIENT5 = + "a07272bb5f935fb170baf2998cb25dd15cc5794e7c5bac7241bec00c4971c7fb"; + private static final String STATE_ROOT2 = + "6cd80c2d8398ccde9c8ada11c14e93a8d81e3e8825d205b7f0d3357514cd0fb5"; + private static final String BLOCK_RECEIPTS_ROOT2 = + "aa970e6870850fa0f5affab7615da762d7b2204113395d05bb0e9679fd7028d3"; + private static final String RECEIPT_TRIE2 = + "f90125a0bd01553d145789ba229ac9b2dd26c0570854c69ecfe1a1aa4921d82169067e20b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"; + + @Test + public void testBalanceTransfers() { + BigInteger amount = BigInteger.TEN.pow(22).add(BigInteger.valueOf(123_987_156)); + BigInteger initialBalance = getBalance(Address.wrap(SENDER_ADDR)); + assertEquals(SENDER_BALANCE, initialBalance); + assertArrayEquals(MINER, this.blockchain.getMinerCoinbase().toBytes()); + + // Get the recipients. + List
    recipients = produceRecipients(); + for (Address recipient : recipients) { + assertEquals(BigInteger.ZERO, getBalance(recipient)); + } + + List transactions = makeBalanceTransferTransactions(recipients, amount); + + // Process the transactions. + Pair results = + processTransactions(transactions, transactions.size()); + + // Collect the consensus information from the block & receipt. + AionBlockSummary blockSummary = results.getRight(); + AionTxReceipt receipt = blockSummary.getSummaries().get(0).getReceipt(); + assertTrue(receipt.isSuccessful()); + + byte[] stateRoot = blockSummary.getBlock().getStateRoot(); + byte[] blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot(); + byte[] receiptTrieEncoded = receipt.getReceiptTrieEncoded(); + + // Verify the consensus information. + assertArrayEquals(Hex.decode(STATE_ROOT2), stateRoot); + assertArrayEquals(Hex.decode(BLOCK_RECEIPTS_ROOT2), blockReceiptsRoot); + assertArrayEquals(Hex.decode(RECEIPT_TRIE2), receiptTrieEncoded); + + // Verify the sender's balance is as expected. + BigInteger expectedBalance = new BigInteger("949999998927317898701780"); + assertEquals(expectedBalance, getBalance(Address.wrap(SENDER_ADDR))); + + // Verify that the recipients' balances are as expected. + for (Address recipient : recipients) { + assertEquals(amount, getBalance(recipient)); + } + + // Verify that the miner's balance is as expected. + BigInteger expectedMinerBalance = new BigInteger("750070212742838603"); + assertEquals(expectedMinerBalance, getBalance(Address.wrap(MINER))); + } + + private List
    produceRecipients() { + List
    addresses = new ArrayList<>(); + addresses.add(Address.wrap(Hex.decode(RECIPIENT1))); + addresses.add(Address.wrap(Hex.decode(RECIPIENT2))); + addresses.add(Address.wrap(Hex.decode(RECIPIENT3))); + addresses.add(Address.wrap(Hex.decode(RECIPIENT4))); + addresses.add(Address.wrap(Hex.decode(RECIPIENT5))); + return addresses; + } + + private Pair processTransactions( + List transactions, int numNonRejectedTransactions) { + AionBlock parentBlock = this.blockchain.getRepository().blockStore.getBestBlock(); + AionBlock block = this.blockchain.createNewBlock(parentBlock, transactions, false); + Pair results = + this.blockchain.tryToConnectAndFetchSummary(block); + assertEquals(ImportResult.IMPORTED_BEST, results.getLeft()); + assertEquals(numNonRejectedTransactions, results.getRight().getSummaries().size()); + return results; + } + + private Pair processTransactions( + AionTransaction transaction, int numNonRejectedTransactions) { + return processTransactions( + Collections.singletonList(transaction), numNonRejectedTransactions); + } + + private static List makeBalanceTransferTransactions( + List
    recipients, BigInteger amount) { + List transactions = new ArrayList<>(); + + BigInteger nonce = BigInteger.ZERO; + for (Address recipient : recipients) { + transactions.add(makeBalanceTransferTransaction(recipient, amount, nonce)); + nonce = nonce.add(BigInteger.ONE); + } + + return transactions; + } + + private static AionTransaction makeBalanceTransferTransaction( + Address recipient, BigInteger amount) { + return makeBalanceTransferTransaction(recipient, amount, BigInteger.ZERO); + } + + private static AionTransaction makeBalanceTransferTransaction( + Address recipient, BigInteger amount, BigInteger nonce) { + org.aion.crypto.ECKey key = org.aion.crypto.ECKeyFac.inst().fromPrivate(SENDER_KEY); + AionTransaction transaction = + new AionTransaction( + nonce.toByteArray(), + recipient, + amount.toByteArray(), + new byte[] {0x1, 0x2, 0x3}, + 2_000_000, + ENERGY_PRICE); + transaction.sign(key); + return transaction; + } + + private BigInteger getBalance(Address address) { + return this.blockchain.getRepository().getBalance(address); + } +} diff --git a/modAionImpl/test/org/aion/zero/impl/ConsensusTest.java b/modAionImpl/test/org/aion/zero/impl/consensus/ConsensusTest.java similarity index 98% rename from modAionImpl/test/org/aion/zero/impl/ConsensusTest.java rename to modAionImpl/test/org/aion/zero/impl/consensus/ConsensusTest.java index afa63a4770..5b8f29f8c9 100644 --- a/modAionImpl/test/org/aion/zero/impl/ConsensusTest.java +++ b/modAionImpl/test/org/aion/zero/impl/consensus/ConsensusTest.java @@ -1,4 +1,4 @@ -package org.aion.zero.impl; +package org.aion.zero.impl.consensus; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -7,13 +7,16 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.mcf.core.ImportResult; import org.aion.util.bytes.ByteUtil; import org.aion.util.conversions.Hex; -import org.aion.vm.api.interfaces.Address; + +import org.aion.zero.impl.StandaloneBlockchain; +import org.aion.zero.impl.StandaloneBlockchain.Builder; +import org.aion.zero.impl.StandaloneBlockchain.Bundle; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.impl.types.AionBlockSummary; import org.aion.zero.types.AionTransaction; @@ -37,11 +40,11 @@ */ public class ConsensusTest { private static final Address CONTRACT = - AionAddress.wrap("a04272bb5f935fb170baf2998cb25dd15cc5794e7c5bac7241bec00c4971c7f8"); + Address.wrap("a04272bb5f935fb170baf2998cb25dd15cc5794e7c5bac7241bec00c4971c7f8"); private static final Address OWNER = - AionAddress.wrap("a05577af5a82aa86bb2f4247e3f809bd0d396d45ec3c4602d5824962d21b1679"); + Address.wrap("a05577af5a82aa86bb2f4247e3f809bd0d396d45ec3c4602d5824962d21b1679"); private static final Address OTHER = - AionAddress.wrap("a05577af5a82aa86bb2f4247e3f809bd0d396d45ec3c4602d5824962d21b1678"); + Address.wrap("a05577af5a82aa86bb2f4247e3f809bd0d396d45ec3c4602d5824962d21b1678"); private static final byte[] PRIVATE_KEY = Hex.decode( "81e071e5bf2c155f641641d88b5956af52c768fbb90968979b20858d65d71f32aa935b67ac46480caaefcdd56dd31862e578694a99083e9fad88cb6df89fc7cb"); @@ -162,8 +165,8 @@ public class ConsensusTest { @Test public void testConsensus() { - StandaloneBlockchain.Bundle bundle = - new StandaloneBlockchain.Builder() + Bundle bundle = + new Builder() .withDefaultAccounts( Collections.singletonList(ECKeyFac.inst().fromPrivate(PRIVATE_KEY))) .withValidatorConfiguration("simple") diff --git a/modAionImpl/test/org/aion/zero/impl/consensus/FvmBalanceTransferConsensusTest.java b/modAionImpl/test/org/aion/zero/impl/consensus/FvmBalanceTransferConsensusTest.java new file mode 100644 index 0000000000..5cf9d4e7ca --- /dev/null +++ b/modAionImpl/test/org/aion/zero/impl/consensus/FvmBalanceTransferConsensusTest.java @@ -0,0 +1,955 @@ +package org.aion.zero.impl.consensus; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.math.BigInteger; +import java.util.Collections; +import java.util.List; +import java.util.Properties; +import org.aion.crypto.ECKey; +import org.aion.mcf.core.ImportResult; +import org.aion.precompiled.ContractFactory; +import org.aion.types.Address; +import org.aion.util.conversions.Hex; +import org.aion.zero.impl.StandaloneBlockchain; +import org.aion.zero.impl.StandaloneBlockchain.Builder; +import org.aion.zero.impl.StandaloneBlockchain.Bundle; +import org.aion.zero.impl.config.CfgAion; +import org.aion.zero.impl.types.AionBlock; +import org.aion.zero.impl.types.AionBlockSummary; +import org.aion.zero.types.AionTransaction; +import org.aion.zero.types.AionTxReceipt; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** Consensus tests meant to test out balance transfers to fvm contracts. */ +public class FvmBalanceTransferConsensusTest { + private static final byte[] SENDER_KEY = + Hex.decode( + "81e071e5bf2c155f641641d88b5956af52c768fbb90968979b20858d65d71f32aa935b67ac46480caaefcdd56dd31862e578694a99083e9fad88cb6df89fc7cb"); + private static final byte[] SENDER_ADDR = + Hex.decode("a00a4175a89a6ffbfdc45782771fba3f5e9da36baa69444f8f95e325430463e7"); + private static final BigInteger SENDER_BALANCE = new BigInteger("1000000000000000000000000"); + private static final byte[] MINER = + Hex.decode("0000000000000000000000000000000000000000000000000000000000000000"); + private static final long ENERGY_PRICE = 10_123_456_789L; + + private StandaloneBlockchain blockchain; + + @Before + public void setup() { + Bundle bundle = + new Builder() + .withDefaultAccounts( + Collections.singletonList( + org.aion.crypto.ECKeyFac.inst().fromPrivate(SENDER_KEY))) + .withValidatorConfiguration("simple") + .withAvmEnabled() + .build(); + this.blockchain = bundle.bc; + } + + @After + public void tearDown() { + this.blockchain = null; + } + + @Test + public void testTransferToPrecompiledContract() { + BigInteger amount = BigInteger.TEN.pow(12).add(BigInteger.valueOf(293_865)); + BigInteger initialBalance = getBalance(Address.wrap(SENDER_ADDR)); + assertThat(initialBalance).isEqualTo(SENDER_BALANCE); + assertThat(this.blockchain.getMinerCoinbase().toBytes()).isEqualTo(MINER); + + // ensure bridge is viewed as precompiled contract + Address bridge = + Address.wrap("0000000000000000000000000000000000000000000000000000000000000200"); + assertThat(ContractFactory.isPrecompiledContract(bridge)).isTrue(); + + // Make balance transfer transaction to precompiled contract. + ECKey key = org.aion.crypto.ECKeyFac.inst().fromPrivate(SENDER_KEY); + AionTransaction transaction = + new AionTransaction( + BigInteger.ZERO.toByteArray(), + bridge, + amount.toByteArray(), + new byte[] {}, + 2_000_000, + ENERGY_PRICE); + transaction.sign(key); + + // Process the transaction. + Pair results = processTransaction(transaction, 1); + + // Collect the consensus information from the block & receipt. + AionBlockSummary blockSummary = results.getRight(); + AionTxReceipt receipt = blockSummary.getSummaries().get(0).getReceipt(); + assertThat(receipt.isSuccessful()).isTrue(); + assertThat(receipt.getEnergyUsed()).isEqualTo(21000); + + byte[] stateRoot = blockSummary.getBlock().getStateRoot(); + byte[] blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot(); + byte[] receiptTrieEncoded = receipt.getReceiptTrieEncoded(); + + // Verify the consensus information. + String expectedRoot = "419F9A4C02612094A9B9A2EAC5CC6DF761214882C35267328297D09246206A9A"; + String expectedReceiptsRoot = + "9A73184E9A5514164D980452E2283892D0487B6833D3F9F782C8686BFDA1B809"; + String expectedReceiptsTrie = + "f90125a034b98e6a317bd93f39959d41cccafec864329cadfb0d8d7bfc5d30df5612e401b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"; + assertThat(stateRoot).isEqualTo(Hex.decode(expectedRoot)); + assertThat(blockReceiptsRoot).isEqualTo(Hex.decode(expectedReceiptsRoot)); + assertThat(receiptTrieEncoded).isEqualTo(Hex.decode(expectedReceiptsTrie)); + + // Verify that the sender has the expected balance. + BigInteger expectedBalance = new BigInteger("999999999786407407137135"); + assertThat(getBalance(Address.wrap(SENDER_ADDR))).isEqualTo(expectedBalance); + + // Verify that the contract has the expected balance. + BigInteger contractBalance = getBalance(bridge); + assertThat(contractBalance).isEqualTo(amount); + + // Verify that the miner has the expected balance. + BigInteger expectedMinerBalance = new BigInteger("749210123854045163"); + assertThat(getBalance(Address.wrap(MINER))).isEqualTo(expectedMinerBalance); + } + + @Test + public void testCallToPrecompiledContract() { + BigInteger initialBalance = getBalance(Address.wrap(SENDER_ADDR)); + assertThat(initialBalance).isEqualTo(SENDER_BALANCE); + assertThat(this.blockchain.getMinerCoinbase().toBytes()).isEqualTo(MINER); + + // ensure bridge is viewed as precompiled contract + Address bridge = + Address.wrap("0000000000000000000000000000000000000000000000000000000000000200"); + assertThat(ContractFactory.isPrecompiledContract(bridge)).isTrue(); + + // Make call transaction to precompiled contract. + ECKey key = org.aion.crypto.ECKeyFac.inst().fromPrivate(SENDER_KEY); + AionTransaction transaction = + new AionTransaction( + BigInteger.ZERO.toByteArray(), + bridge, + BigInteger.ZERO.toByteArray(), + Hex.decode( + "a6f9dae1a048613dd3cb89685cb3f9cfa410ecf606c7ec7320e721edacd194050828c6b0"), + 2_000_000, + ENERGY_PRICE); + transaction.sign(key); + + // Process the transaction. + Pair results = processTransaction(transaction, 1); + + // Collect the consensus information from the block & receipt. + AionBlockSummary blockSummary = results.getRight(); + AionTxReceipt receipt = blockSummary.getSummaries().get(0).getReceipt(); + assertThat(receipt.isSuccessful()).isTrue(); + assertThat(receipt.getEnergyUsed()).isEqualTo(23304); + + byte[] stateRoot = blockSummary.getBlock().getStateRoot(); + byte[] blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot(); + byte[] receiptTrieEncoded = receipt.getReceiptTrieEncoded(); + + // Verify the consensus information. + String expectedRoot = "7D91DD44FC7AABC0291BB6FD9CBCD70BEB3859FDD10E0F2356D2B5947EBC55D7"; + String expectedReceiptsRoot = + "E897C7EB2531B5CC45293AE3EC0CC156B0FACEAEF3046D671A08D6C91BA88827"; + String expectedReceiptsTrie = + "f90125a06ed1cbe0a46be351c90404aaeb7d12d9737d4c8a070e8c63dc1cfc0d7441fbdbb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"; + assertThat(stateRoot).isEqualTo(Hex.decode(expectedRoot)); + assertThat(blockReceiptsRoot).isEqualTo(Hex.decode(expectedReceiptsRoot)); + assertThat(receiptTrieEncoded).isEqualTo(Hex.decode(expectedReceiptsTrie)); + + // Verify that the sender has the expected balance. + BigInteger expectedBalance = new BigInteger("999999999764082962989144"); + assertThat(getBalance(Address.wrap(SENDER_ADDR))).isEqualTo(expectedBalance); + + // Verify that the contract has the expected balance. + BigInteger contractBalance = getBalance(bridge); + assertThat(contractBalance).isEqualTo(BigInteger.ZERO); + + // Verify that the miner has the expected balance. + BigInteger expectedMinerBalance = new BigInteger("749233448298487019"); + assertThat(getBalance(Address.wrap(MINER))).isEqualTo(expectedMinerBalance); + } + + @Test + public void testTransferToPrecompiledBlake2bContractWithoutData() { + BigInteger amount = BigInteger.TEN.pow(12).add(BigInteger.valueOf(293_865)); + BigInteger initialBalance = getBalance(Address.wrap(SENDER_ADDR)); + assertThat(initialBalance).isEqualTo(SENDER_BALANCE); + assertThat(this.blockchain.getMinerCoinbase().toBytes()).isEqualTo(MINER); + + // get contract address from precompiled factory + Address blake2b = ContractFactory.getBlake2bHashContractAddress(); + assertThat(ContractFactory.isPrecompiledContract(blake2b)).isTrue(); + + // Make balance transfer transaction to precompiled contract. + ECKey key = org.aion.crypto.ECKeyFac.inst().fromPrivate(SENDER_KEY); + AionTransaction transaction = + new AionTransaction( + BigInteger.ZERO.toByteArray(), + blake2b, + amount.toByteArray(), + new byte[] {}, + 2_000_000, + ENERGY_PRICE); + transaction.sign(key); + + // Process the transaction. + Pair results = processTransaction(transaction, 1); + + // Collect the consensus information from the block & receipt. + AionBlockSummary blockSummary = results.getRight(); + AionTxReceipt receipt = blockSummary.getSummaries().get(0).getReceipt(); + assertThat(receipt.isSuccessful()).isFalse(); + assertThat(receipt.getEnergyUsed()).isEqualTo(21010); + + byte[] stateRoot = blockSummary.getBlock().getStateRoot(); + byte[] blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot(); + byte[] receiptTrieEncoded = receipt.getReceiptTrieEncoded(); + + // Verify the consensus information. + String expectedRoot = "37C62813178F694DA9A82398F63CBD7CFFD913B6CE6B2080A8B9374E688EF37E"; + String expectedReceiptsRoot = + "BE3697A1A56274D8378EE9EF40C308BFBFC8BE48AD5250E1EDCF04A26E11F021"; + String expectedReceiptsTrie = + "f90125a0619b938d5971660fd2a83cf7c2718653bb5f9b8e78b3b5e7a361e66635c32fd1b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"; + assertThat(stateRoot).isEqualTo(Hex.decode(expectedRoot)); + assertThat(blockReceiptsRoot).isEqualTo(Hex.decode(expectedReceiptsRoot)); + assertThat(receiptTrieEncoded).isEqualTo(Hex.decode(expectedReceiptsTrie)); + + // Verify that the sender has the expected balance. + BigInteger expectedBalance = new BigInteger("999999979753086422000000"); + assertThat(getBalance(Address.wrap(SENDER_ADDR))).isEqualTo(expectedBalance); + + // Verify that the contract has the expected balance. + BigInteger contractBalance = getBalance(blake2b); + assertThat(contractBalance).isEqualTo(BigInteger.ZERO); + + // Verify that the miner has the expected balance. + BigInteger expectedMinerBalance = new BigInteger("749210225088613053"); + assertThat(getBalance(Address.wrap(MINER))).isEqualTo(expectedMinerBalance); + } + + @Test + public void testTransferToPrecompiledBlake2bContractWithData() { + // ensure the contract is live + Properties properties = new Properties(); + properties.put("fork0.3.2", "0"); + CfgAion cfg = CfgAion.inst(); + cfg.getFork().setProperties(properties); + + BigInteger amount = BigInteger.TEN.pow(12).add(BigInteger.valueOf(293_865)); + BigInteger initialBalance = getBalance(Address.wrap(SENDER_ADDR)); + assertThat(initialBalance).isEqualTo(SENDER_BALANCE); + assertThat(this.blockchain.getMinerCoinbase().toBytes()).isEqualTo(MINER); + + // get contract address from precompiled factory + Address blake2b = ContractFactory.getBlake2bHashContractAddress(); + assertThat(ContractFactory.isPrecompiledContract(blake2b)).isTrue(); + + // Make balance transfer transaction to precompiled contract. + ECKey key = org.aion.crypto.ECKeyFac.inst().fromPrivate(SENDER_KEY); + AionTransaction transaction = + new AionTransaction( + BigInteger.ZERO.toByteArray(), + blake2b, + amount.toByteArray(), + Hex.decode("abcdef0123456789"), + 2_000_000, + ENERGY_PRICE); + transaction.sign(key); + + // Process the transaction. + Pair results = processTransaction(transaction, 1); + + // Collect the consensus information from the block & receipt. + AionBlockSummary blockSummary = results.getRight(); + AionTxReceipt receipt = blockSummary.getSummaries().get(0).getReceipt(); + assertThat(receipt.isSuccessful()).isTrue(); + assertThat(receipt.getEnergyUsed()).isEqualTo(21526); + assertThat(receipt.getTransactionOutput()) + .isEqualTo( + Hex.decode( + "ac86b78afd9bdda3641a47a4aff2a7ee26acd40cc534d63655e9dfbf3f890a02")); + + byte[] stateRoot = blockSummary.getBlock().getStateRoot(); + byte[] blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot(); + byte[] receiptTrieEncoded = receipt.getReceiptTrieEncoded(); + + // Verify the consensus information. + String expectedRoot = "12CB8B149B8465CE3A3BD3AF3D19EB39C3DADD528880BB7CCB4FC4ED10758E68"; + String expectedReceiptsRoot = + "55CB056398D1AA49328E11E97BA034C532D312CD8C4959F3E609FD25E2FC0C62"; + String expectedReceiptsTrie = + "f90125a0188897e00f24f83eb6a27004dcb96cb4fa4370a1e7b072f2c21c9a437146fa69b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"; + assertThat(stateRoot).isEqualTo(Hex.decode(expectedRoot)); + assertThat(blockReceiptsRoot).isEqualTo(Hex.decode(expectedReceiptsRoot)); + assertThat(receiptTrieEncoded).isEqualTo(Hex.decode(expectedReceiptsTrie)); + + // Verify that the sender has the expected balance. + BigInteger expectedBalance = new BigInteger("999999999781082468866121"); + assertThat(getBalance(Address.wrap(SENDER_ADDR))).isEqualTo(expectedBalance); + + // Verify that the contract has the expected balance. + BigInteger contractBalance = getBalance(blake2b); + assertThat(contractBalance).isEqualTo(amount); + + // Verify that the miner has the expected balance. + BigInteger expectedMinerBalance = new BigInteger("749215448792316177"); + assertThat(getBalance(Address.wrap(MINER))).isEqualTo(expectedMinerBalance); + } + + @Test + public void testCallToPrecompiledBlake2bContract() { + // ensure the contract is live (after fork) + Properties properties = new Properties(); + properties.put("fork0.3.2", "0"); + CfgAion cfg = CfgAion.inst(); + cfg.getFork().setProperties(properties); + + BigInteger initialBalance = getBalance(Address.wrap(SENDER_ADDR)); + assertThat(initialBalance).isEqualTo(SENDER_BALANCE); + assertThat(this.blockchain.getMinerCoinbase().toBytes()).isEqualTo(MINER); + + // get contract address from precompiled factory + Address blake2b = ContractFactory.getBlake2bHashContractAddress(); + assertThat(ContractFactory.isPrecompiledContract(blake2b)).isTrue(); + + // Make call transaction to precompiled contract. + ECKey key = org.aion.crypto.ECKeyFac.inst().fromPrivate(SENDER_KEY); + AionTransaction transaction = + new AionTransaction( + BigInteger.ZERO.toByteArray(), + blake2b, + BigInteger.ZERO.toByteArray(), + Hex.decode("abcdef0123456789"), + 2_000_000, + ENERGY_PRICE); + transaction.sign(key); + + // Process the transaction. + Pair results = processTransaction(transaction, 1); + + // Collect the consensus information from the block & receipt. + AionBlockSummary blockSummary = results.getRight(); + AionTxReceipt receipt = blockSummary.getSummaries().get(0).getReceipt(); + assertThat(receipt.isSuccessful()).isTrue(); + assertThat(receipt.getEnergyUsed()).isEqualTo(21526); + assertThat(receipt.getTransactionOutput()) + .isEqualTo( + Hex.decode( + "ac86b78afd9bdda3641a47a4aff2a7ee26acd40cc534d63655e9dfbf3f890a02")); + + byte[] stateRoot = blockSummary.getBlock().getStateRoot(); + byte[] blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot(); + byte[] receiptTrieEncoded = receipt.getReceiptTrieEncoded(); + + // Verify the consensus information. + String expectedRoot = "ABBF04753B23F36F04CC4C0AEF7969C29236A4FCD982F3A4D824CB1EDE60AF4B"; + String expectedReceiptsRoot = + "72C976AF0CE4627E1CA3FA1EA5EB798A0CB7118E186626E04ECA7198887AD3A1"; + String expectedReceiptsTrie = + "f90125a03441b15983ce33839dfd1a7b62c1fa86ca4ff9df76d263bcc7c8f1d14225dc5cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"; + assertThat(stateRoot).isEqualTo(Hex.decode(expectedRoot)); + assertThat(blockReceiptsRoot).isEqualTo(Hex.decode(expectedReceiptsRoot)); + assertThat(receiptTrieEncoded).isEqualTo(Hex.decode(expectedReceiptsTrie)); + + // Verify that the sender has the expected balance. + BigInteger expectedBalance = new BigInteger("999999999782082469159986"); + assertThat(getBalance(Address.wrap(SENDER_ADDR))).isEqualTo(expectedBalance); + + // Verify that the contract has the expected balance. + BigInteger contractBalance = getBalance(blake2b); + assertThat(contractBalance).isEqualTo(BigInteger.ZERO); + + // Verify that the miner has the expected balance. + BigInteger expectedMinerBalance = new BigInteger("749215448792316177"); + assertThat(getBalance(Address.wrap(MINER))).isEqualTo(expectedMinerBalance); + } + + private static final String CONTRACT = + "a04272bb5f935fb170baf2998cb25dd15cc5794e7c5bac7241bec00c4971c7f8"; + private static final String STATE_ROOT1 = + "043f209d36ab740fe9e126705bc7933a27b3a4627c47efd24ee1d039b6fde25f"; + private static final String BLOCK_RECEIPTS_ROOT1 = + "cf3ff96895af00a66b8f2dd93d6401d8edd83b6fb6a6b0d8d1b0059802d2b673"; + private static final String RECEIPT_TRIE1 = + "f90125a02d7af5f12c661cdbda95a70593fc63ea4896190fb49c926e99d83f8da7ab424ab9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"; + + @Test + public void testTransferUponCreationToNonPayableConstructor() { + BigInteger amount = BigInteger.TEN.pow(12).add(BigInteger.valueOf(293_865)); + BigInteger initialBalance = getBalance(Address.wrap(SENDER_ADDR)); + assertEquals(SENDER_BALANCE, initialBalance); + assertArrayEquals(MINER, this.blockchain.getMinerCoinbase().toBytes()); + + // Make the create & transfer transaction. + AionTransaction transaction = + makeCreateAndTransferToFvmNonpayableConstructorContractTx(amount); + assertArrayEquals(Hex.decode(CONTRACT), transaction.getContractAddress().toBytes()); + + // Process the transaction. + Pair results = processTransaction(transaction, 1); + + // Collect the consensus information from the block & receipt. + AionBlockSummary blockSummary = results.getRight(); + AionTxReceipt receipt = blockSummary.getSummaries().get(0).getReceipt(); + assertFalse(receipt.isSuccessful()); + + byte[] stateRoot = blockSummary.getBlock().getStateRoot(); + byte[] blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot(); + byte[] receiptTrieEncoded = receipt.getReceiptTrieEncoded(); + + // Verify the consensus information. + assertArrayEquals(Hex.decode(STATE_ROOT1), stateRoot); + assertArrayEquals(Hex.decode(BLOCK_RECEIPTS_ROOT1), blockReceiptsRoot); + assertArrayEquals(Hex.decode(RECEIPT_TRIE1), receiptTrieEncoded); + + // Verify that the sender has the expected balance. + BigInteger expectedBalance = new BigInteger("999999997708454321241960"); + assertEquals(expectedBalance, getBalance(Address.wrap(SENDER_ADDR))); + + // Verify that the contract has the expected balance. + BigInteger contractBalance = getBalance(transaction.getContractAddress()); + assertEquals(BigInteger.ZERO, contractBalance); + + // Verify that the miner has the expected balance. + BigInteger expectedMinerBalance = new BigInteger("751289076940234203"); + assertEquals(expectedMinerBalance, getBalance(Address.wrap(MINER))); + } + + private BigInteger getEnergyCost(AionTxReceipt receipt) { + return BigInteger.valueOf(receipt.getEnergyUsed()) + .multiply(BigInteger.valueOf(ENERGY_PRICE)); + } + + private static final String STATE_ROOT2 = + "86e9e3551f2376ee521300972206d6d87731f406ef0a9e29f001e4766ba78e4b"; + private static final String BLOCK_RECEIPTS_ROOT2 = + "292c8ce512aa7c0fc0d2bf67518aceea8699d2d0b5558a494a89a46dc67a7669"; + private static final String RECEIPT_TRIE2 = + "f90125a054b2261c6ca2d93a93617360523731e3506ea97e01a91af95d27ae270f5ecf65b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"; + + @Test + public void testTransferUponCreationToPayableConstructor() { + BigInteger amount = BigInteger.TEN.pow(11).add(BigInteger.valueOf(1_234_578)); + BigInteger initialBalance = getBalance(Address.wrap(SENDER_ADDR)); + assertEquals(SENDER_BALANCE, initialBalance); + assertArrayEquals(MINER, this.blockchain.getMinerCoinbase().toBytes()); + + // Make the create & transfer transaction. + AionTransaction transaction = + makeCreateAndTransferToFvmPayableConstructorContractTx(amount); + assertArrayEquals(Hex.decode(CONTRACT), transaction.getContractAddress().toBytes()); + + // Process the transaction. + Pair results = processTransaction(transaction, 1); + + // Collect the consensus information from the block & receipt. + AionBlockSummary blockSummary = results.getRight(); + AionTxReceipt receipt = blockSummary.getSummaries().get(0).getReceipt(); + assertTrue(receipt.isSuccessful()); + + byte[] stateRoot = blockSummary.getBlock().getStateRoot(); + byte[] blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot(); + byte[] receiptTrieEncoded = receipt.getReceiptTrieEncoded(); + + // Verify the consensus information. + assertArrayEquals(Hex.decode(STATE_ROOT2), stateRoot); + assertArrayEquals(Hex.decode(BLOCK_RECEIPTS_ROOT2), blockReceiptsRoot); + assertArrayEquals(Hex.decode(RECEIPT_TRIE2), receiptTrieEncoded); + + BigInteger expectedBalance = new BigInteger("999999997714155060747479"); + assertEquals(expectedBalance, getBalance(Address.wrap(SENDER_ADDR))); + + // Verify that the contract has the expected balance. + BigInteger contractBalance = getBalance(transaction.getContractAddress()); + assertEquals(amount, contractBalance); + + // Verify that the miner has the expected balance. + BigInteger expectedMinerBalance = new BigInteger("751283276199494106"); + assertEquals(expectedMinerBalance, getBalance(Address.wrap(MINER))); + } + + private static final String STATE_ROOT3 = + "4ffe139207bb504713c104bfc9adb53fee3e7d45abec87201e516770532d7370"; + private static final String BLOCK_RECEIPTS_ROOT3 = + "dcfdef14452702e59ae10013411e04bff6aa34887fbe3a873ea827d8b1cda94d"; + private static final String RECEIPT_TRIE3 = + "f90125a0c99519d9a99ddc099d59165d502b881b7cb60caab0717d8e0237cf4b0676b464b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"; + private static final String STATE_ROOT4 = + "a5c0dceb6c92575dab5555f6c0acd5d207ea6143da2533c7ed10eba0eeb42c61"; + private static final String BLOCK_RECEIPTS_ROOT4 = + "6b6b16ecb1272a2a7e23f250eb0d49a93d00d928721d39f21e741f791c044267"; + private static final String RECEIPT_TRIE4 = + "f90125a091381a2543c775ee77441efa63260453c5f53243a63efbf4df21452fe2498dd6b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"; + + @Test + public void testTransferAfterCreatingContractToNonPayableFunction() { + BigInteger amount = BigInteger.TEN.pow(9).add(BigInteger.valueOf(3_124_587)); + BigInteger initialBalance = getBalance(Address.wrap(SENDER_ADDR)); + assertEquals(SENDER_BALANCE, initialBalance); + assertArrayEquals(MINER, this.blockchain.getMinerCoinbase().toBytes()); + + // Make the create transaction. + AionTransaction transaction = makeCreatePayableContractTx(); + assertArrayEquals(Hex.decode(CONTRACT), transaction.getContractAddress().toBytes()); + + // Process the transaction. + Pair results = processTransaction(transaction, 1); + + // Collect the consensus information from the block & receipt. + AionBlockSummary blockSummary = results.getRight(); + AionTxReceipt receipt = blockSummary.getSummaries().get(0).getReceipt(); + assertTrue(receipt.isSuccessful()); + + byte[] stateRoot = blockSummary.getBlock().getStateRoot(); + byte[] blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot(); + byte[] receiptTrieEncoded = receipt.getReceiptTrieEncoded(); + + // Verify the consensus information. + assertArrayEquals(Hex.decode(STATE_ROOT3), stateRoot); + assertArrayEquals(Hex.decode(BLOCK_RECEIPTS_ROOT3), blockReceiptsRoot); + assertArrayEquals(Hex.decode(RECEIPT_TRIE3), receiptTrieEncoded); + + // Make the balance transfer transaction. + Address contract = transaction.getContractAddress(); + transaction = makeCallNonpayableFunctionTx(contract, amount); + + // Process the transaction. + results = processTransaction(transaction, 1); + + // Collect the consensus information from the block & receipt. + blockSummary = results.getRight(); + receipt = blockSummary.getSummaries().get(0).getReceipt(); + assertFalse(receipt.isSuccessful()); + + stateRoot = blockSummary.getBlock().getStateRoot(); + blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot(); + receiptTrieEncoded = receipt.getReceiptTrieEncoded(); + + // Verify the consensus information. + assertArrayEquals(Hex.decode(STATE_ROOT4), stateRoot); + assertArrayEquals(Hex.decode(BLOCK_RECEIPTS_ROOT4), blockReceiptsRoot); + assertArrayEquals(Hex.decode(RECEIPT_TRIE4), receiptTrieEncoded); + + // Verify the sender's balance is as expected. + BigInteger expectedBalance = new BigInteger("999999997458455555837605"); + assertEquals(expectedBalance, getBalance(Address.wrap(SENDER_ADDR))); + + // Verify that the contract has the expected balance. + assertEquals(BigInteger.ZERO, getBalance(contract)); + + // Verify that the miner has the expected balance. + BigInteger expectedMinerBalance = new BigInteger("1500539496606935792"); + assertEquals(expectedMinerBalance, getBalance(Address.wrap(MINER))); + } + + private static final String STATE_ROOT5 = + "2fcb5e9463cad96a5cc7154e0e3236aa8d32e3c68212fd263813d87f72b14cfd"; + private static final String BLOCK_RECEIPTS_ROOT5 = + "d75eb82ed9377f0ebcc579f13bd3d8bd7f42c30208c8f0118d0bcfc90d641a79"; + private static final String RECEIPT_TRIE5 = + "f90125a0763548459d92b2c6106837fd97e49be68da58767cadbab8fe490cb66e6043bf2b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"; + + @Test + public void testTransferAfterCreatingContractToPayableFunction() { + BigInteger amount = BigInteger.TEN.pow(17).add(BigInteger.valueOf(38_193)); + BigInteger initialBalance = getBalance(Address.wrap(SENDER_ADDR)); + assertEquals(SENDER_BALANCE, initialBalance); + assertArrayEquals(MINER, this.blockchain.getMinerCoinbase().toBytes()); + + // Make the create transaction. + AionTransaction transaction = makeCreatePayableContractTx(); + assertArrayEquals(Hex.decode(CONTRACT), transaction.getContractAddress().toBytes()); + + // Process the transaction. + Pair results = processTransaction(transaction, 1); + + // Collect the consensus information from the block & receipt. + AionBlockSummary blockSummary = results.getRight(); + AionTxReceipt receipt = blockSummary.getSummaries().get(0).getReceipt(); + assertTrue(receipt.isSuccessful()); + + byte[] stateRoot = blockSummary.getBlock().getStateRoot(); + byte[] blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot(); + byte[] receiptTrieEncoded = receipt.getReceiptTrieEncoded(); + + // Verify the consensus information. + assertArrayEquals(Hex.decode(STATE_ROOT3), stateRoot); + assertArrayEquals(Hex.decode(BLOCK_RECEIPTS_ROOT3), blockReceiptsRoot); + assertArrayEquals(Hex.decode(RECEIPT_TRIE3), receiptTrieEncoded); + + // Make the balance transfer transaction. + Address contract = transaction.getContractAddress(); + transaction = makeCallPayableFunctionTx(contract, amount); + + // Process the transaction. + results = processTransaction(transaction, 1); + + // Collect the consensus information from the block & receipt. + blockSummary = results.getRight(); + receipt = blockSummary.getSummaries().get(0).getReceipt(); + assertTrue(receipt.isSuccessful()); + + stateRoot = blockSummary.getBlock().getStateRoot(); + blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot(); + receiptTrieEncoded = receipt.getReceiptTrieEncoded(); + + // Verify the consensus information. + assertArrayEquals(Hex.decode(STATE_ROOT5), stateRoot); + assertArrayEquals(Hex.decode(BLOCK_RECEIPTS_ROOT5), blockReceiptsRoot); + assertArrayEquals(Hex.decode(RECEIPT_TRIE5), receiptTrieEncoded); + + // Verify the sender's balance is as expected. + BigInteger expectedBalance = new BigInteger("999999897458394815058678"); + assertEquals(expectedBalance, getBalance(Address.wrap(SENDER_ADDR))); + + // Verify that the contract has the expected balance. + assertEquals(amount, getBalance(contract)); + + // Verify that the miner has the expected balance. + BigInteger expectedMinerBalance = new BigInteger("1500539557347676526"); + assertEquals(expectedMinerBalance, getBalance(Address.wrap(MINER))); + } + + private static final String STATE_ROOT6 = + "5ea37f5754ecc75f5d41bf300b6f379c9f72eb6e50c86d7f8a52b36325629ae4"; + private static final String BLOCK_RECEIPTS_ROOT6 = + "484e54668297bf2004c932eb3237f24a465d9c9a778cf2a9434d61b532dd9908"; + private static final String RECEIPT_TRIE6 = + "f90125a02912545d2a9f54bdd96dc2fc812470730c197583b9d75b56a854c05215451522b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"; + private static final String STATE_ROOT7 = + "440a881c8e4fba775e855a9874f56f559e6529f69e8cd6ae17860e3ac2e79af6"; + private static final String BLOCK_RECEIPTS_ROOT7 = + "c32c4f95e92957cbf6ef709b431654fbaa11dc9c290687f997b3d5e78deacd2c"; + private static final String RECEIPT_TRIE7 = + "f90125a0734a96fd117112031af907c63609a00bc136d117f132be130b0f32b0be9eda0eb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"; + + @Test + public void testTransferAfterCreatingToNonPayableFallbackFunction() { + BigInteger amount = BigInteger.TEN.pow(17).add(BigInteger.valueOf(38_193)); + BigInteger initialBalance = getBalance(Address.wrap(SENDER_ADDR)); + assertEquals(SENDER_BALANCE, initialBalance); + assertArrayEquals(MINER, this.blockchain.getMinerCoinbase().toBytes()); + + // Make the create transaction. + AionTransaction transaction = makeCreateNonpayableFallbackContractTx(); + assertArrayEquals(Hex.decode(CONTRACT), transaction.getContractAddress().toBytes()); + + // Process the transaction. + Pair results = processTransaction(transaction, 1); + + // Collect the consensus information from the block & receipt. + AionBlockSummary blockSummary = results.getRight(); + AionTxReceipt receipt = blockSummary.getSummaries().get(0).getReceipt(); + assertTrue(receipt.isSuccessful()); + + byte[] stateRoot = blockSummary.getBlock().getStateRoot(); + byte[] blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot(); + byte[] receiptTrieEncoded = receipt.getReceiptTrieEncoded(); + + // Verify the consensus information. + assertArrayEquals(Hex.decode(STATE_ROOT6), stateRoot); + assertArrayEquals(Hex.decode(BLOCK_RECEIPTS_ROOT6), blockReceiptsRoot); + assertArrayEquals(Hex.decode(RECEIPT_TRIE6), receiptTrieEncoded); + + // Make the balance transfer transaction. + Address contract = transaction.getContractAddress(); + transaction = makeCallFallbackFunctionTx(contract, amount); + + // Process the transaction. + results = processTransaction(transaction, 1); + + // Collect the consensus information from the block & receipt. + blockSummary = results.getRight(); + receipt = blockSummary.getSummaries().get(0).getReceipt(); + assertFalse(receipt.isSuccessful()); + + stateRoot = blockSummary.getBlock().getStateRoot(); + blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot(); + receiptTrieEncoded = receipt.getReceiptTrieEncoded(); + + // Verify the consensus information. + assertArrayEquals(Hex.decode(STATE_ROOT7), stateRoot); + assertArrayEquals(Hex.decode(BLOCK_RECEIPTS_ROOT7), blockReceiptsRoot); + assertArrayEquals(Hex.decode(RECEIPT_TRIE7), receiptTrieEncoded); + + // Verify the sender's balance is as expected. + BigInteger expectedBalance = new BigInteger("999999997488350123735522"); + assertEquals(expectedBalance, getBalance(Address.wrap(SENDER_ADDR))); + + // Verify that the contract has the expected balance. + assertEquals(BigInteger.ZERO, getBalance(contract)); + + // Verify that the miner has the expected balance. + BigInteger expectedMinerBalance = new BigInteger("1500509602039037875"); + assertEquals(expectedMinerBalance, getBalance(Address.wrap(MINER))); + } + + private static final String STATE_ROOT8 = + "7ab509766ece9a4d307fd7cd8c2c4ceae9f5ed7b75399668d7b90985d9b3b123"; + private static final String BLOCK_RECEIPTS_ROOT8 = + "7026679223b9afd81c159d4aa6f65d78d1ae1b47e9cfbb0ddda0301e9ad1fff3"; + private static final String RECEIPT_TRIE8 = + "f90125a0b017205b58b2790dddf4450b3b9289f140bf7e0c59f3136b5eb77170c5242ff4b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"; + private static final String STATE_ROOT9 = + "35124c16c8fddf510ecd691a891c2732cd2e19bf348722f408210ed98b1b6d84"; + private static final String BLOCK_RECEIPTS_ROOT9 = + "d4b95308896b1cefabb82e710f06acfa9be421995fe5ec0ebcd2128c00f50d9d"; + private static final String RECEIPT_TRIE9 = + "f90125a08eec03dcd128e093c0ee7e9d6187f3448722d7bb9c24c9686a9f0486ac810c00b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"; + + @Test + public void testTransferAfterCreatingToPayableFallbackFunction() { + BigInteger amount = BigInteger.TEN.pow(17).add(BigInteger.valueOf(38_193)); + BigInteger initialBalance = getBalance(Address.wrap(SENDER_ADDR)); + assertEquals(SENDER_BALANCE, initialBalance); + assertArrayEquals(MINER, this.blockchain.getMinerCoinbase().toBytes()); + + // Make the create transaction. + AionTransaction transaction = makeCreatePayableFallbackContractTx(); + assertArrayEquals(Hex.decode(CONTRACT), transaction.getContractAddress().toBytes()); + + // Process the transaction. + Pair results = processTransaction(transaction, 1); + + // Collect the consensus information from the block & receipt. + AionBlockSummary blockSummary = results.getRight(); + AionTxReceipt receipt = blockSummary.getSummaries().get(0).getReceipt(); + assertTrue(receipt.isSuccessful()); + + byte[] stateRoot = blockSummary.getBlock().getStateRoot(); + byte[] blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot(); + byte[] receiptTrieEncoded = receipt.getReceiptTrieEncoded(); + + // Verify the consensus information. + assertArrayEquals(Hex.decode(STATE_ROOT8), stateRoot); + assertArrayEquals(Hex.decode(BLOCK_RECEIPTS_ROOT8), blockReceiptsRoot); + assertArrayEquals(Hex.decode(RECEIPT_TRIE8), receiptTrieEncoded); + + // Make the balance transfer transaction. + Address contract = transaction.getContractAddress(); + transaction = makeCallFallbackFunctionTx(contract, amount); + + // Process the transaction. + results = processTransaction(transaction, 1); + + // Collect the consensus information from the block & receipt. + blockSummary = results.getRight(); + receipt = blockSummary.getSummaries().get(0).getReceipt(); + assertTrue(receipt.isSuccessful()); + + stateRoot = blockSummary.getBlock().getStateRoot(); + blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot(); + receiptTrieEncoded = receipt.getReceiptTrieEncoded(); + + // Verify the consensus information. + assertArrayEquals(Hex.decode(STATE_ROOT9), stateRoot); + assertArrayEquals(Hex.decode(BLOCK_RECEIPTS_ROOT9), blockReceiptsRoot); + assertArrayEquals(Hex.decode(RECEIPT_TRIE9), receiptTrieEncoded); + + // Verify the sender's balance is as expected. + BigInteger expectedBalance = new BigInteger("999999897494333086659628"); + assertEquals(expectedBalance, getBalance(Address.wrap(SENDER_ADDR))); + + // Verify that the contract has the expected balance. + assertEquals(amount, getBalance(contract)); + + // Verify that the miner has the expected balance. + BigInteger expectedMinerBalance = new BigInteger("1500503619076075576"); + assertEquals(expectedMinerBalance, getBalance(Address.wrap(MINER))); + } + + private static AionTransaction makeCreateAndTransferToFvmNonpayableConstructorContractTx( + BigInteger amount) { + ECKey key = org.aion.crypto.ECKeyFac.inst().fromPrivate(SENDER_KEY); + AionTransaction transaction = + new AionTransaction( + BigInteger.ZERO.toByteArray(), + null, + amount.toByteArray(), + getNonpayableConstructorContractBytes(), + 5_000_000, + ENERGY_PRICE); + transaction.sign(key); + return transaction; + } + + private static AionTransaction makeCreateAndTransferToFvmPayableConstructorContractTx( + BigInteger amount) { + ECKey key = org.aion.crypto.ECKeyFac.inst().fromPrivate(SENDER_KEY); + AionTransaction transaction = + new AionTransaction( + BigInteger.ZERO.toByteArray(), + null, + amount.toByteArray(), + getPayableConstructorContractBytes(), + 5_000_000, + ENERGY_PRICE); + transaction.sign(key); + return transaction; + } + + private static AionTransaction makeCreatePayableFallbackContractTx() { + ECKey key = org.aion.crypto.ECKeyFac.inst().fromPrivate(SENDER_KEY); + AionTransaction transaction = + new AionTransaction( + BigInteger.ZERO.toByteArray(), + null, + BigInteger.ZERO.toByteArray(), + getPayableFallbackContractBytes(), + 5_000_000, + ENERGY_PRICE); + transaction.sign(key); + return transaction; + } + + private static AionTransaction makeCreateNonpayableFallbackContractTx() { + ECKey key = org.aion.crypto.ECKeyFac.inst().fromPrivate(SENDER_KEY); + AionTransaction transaction = + new AionTransaction( + BigInteger.ZERO.toByteArray(), + null, + BigInteger.ZERO.toByteArray(), + getNonpayableFallbackContractBytes(), + 5_000_000, + ENERGY_PRICE); + transaction.sign(key); + return transaction; + } + + private static AionTransaction makeCreatePayableContractTx() { + ECKey key = org.aion.crypto.ECKeyFac.inst().fromPrivate(SENDER_KEY); + AionTransaction transaction = + new AionTransaction( + BigInteger.ZERO.toByteArray(), + null, + BigInteger.ZERO.toByteArray(), + getPayableContractBytes(), + 5_000_000, + ENERGY_PRICE); + transaction.sign(key); + return transaction; + } + + private static AionTransaction makeCallNonpayableFunctionTx( + Address contract, BigInteger amount) { + ECKey key = org.aion.crypto.ECKeyFac.inst().fromPrivate(SENDER_KEY); + AionTransaction transaction = + new AionTransaction( + BigInteger.ONE.toByteArray(), + contract, + amount.toByteArray(), + callNonpayableFunctionEncoding(), + 2_000_000, + ENERGY_PRICE); + transaction.sign(key); + return transaction; + } + + private static AionTransaction makeCallFallbackFunctionTx(Address contract, BigInteger amount) { + ECKey key = org.aion.crypto.ECKeyFac.inst().fromPrivate(SENDER_KEY); + AionTransaction transaction = + new AionTransaction( + BigInteger.ONE.toByteArray(), + contract, + amount.toByteArray(), + new byte[0], + 2_000_000, + ENERGY_PRICE); + transaction.sign(key); + return transaction; + } + + private static AionTransaction makeCallPayableFunctionTx(Address contract, BigInteger amount) { + ECKey key = org.aion.crypto.ECKeyFac.inst().fromPrivate(SENDER_KEY); + AionTransaction transaction = + new AionTransaction( + BigInteger.ONE.toByteArray(), + contract, + amount.toByteArray(), + callPayableFunctionEncoding(), + 2_000_000, + ENERGY_PRICE); + transaction.sign(key); + return transaction; + } + + private Pair processTransaction( + AionTransaction transaction, int numNonRejectedTransactions) { + AionBlock parentBlock = this.blockchain.getRepository().blockStore.getBestBlock(); + List transactions = Collections.singletonList(transaction); + AionBlock block = this.blockchain.createNewBlock(parentBlock, transactions, false); + Pair results = + this.blockchain.tryToConnectAndFetchSummary(block); + assertEquals(ImportResult.IMPORTED_BEST, results.getLeft()); + assertEquals(numNonRejectedTransactions, results.getRight().getSummaries().size()); + return results; + } + + private BigInteger getBalance(Address address) { + return this.blockchain.getRepository().getBalance(address); + } + + /** Returns the bytes of NonpayableConstructor.sol */ + private static byte[] getNonpayableConstructorContractBytes() { + return Hex.decode( + "60506040523415600f5760006000fd5b5b5b6015565b603a8060226000396000" + + "f30060506040526008565b60006000fd00a165627a7a72305820d1e98a5ae7ff9b50d168b62389e56" + + "665feb01e6742150667324a5430b67237ba0029"); + } + + /** Returns the bytes of PayableConstructor.sol */ + private static byte[] getPayableConstructorContractBytes() { + return Hex.decode( + "60506040525b5b600a565b603a8060176000396000f30060506040526008565" + + "b60006000fd00a165627a7a72305820fcd15b67312358cf40ec28495d2606f24a526ba03d5b2feb1" + + "c124a61be8543f00029"); + } + + /** Returns the bytes of PayableContract.sol */ + private static byte[] getPayableContractBytes() { + return Hex.decode( + "60506040525b5b600a565b6088806100186000396000f300605060405260003" + + "56c01000000000000000000000000900463ffffffff1680630f385d6114603b5780634a6a74071460" + + "4e576035565b60006000fd5b341560465760006000fd5b604c6056565b005b60546059565b005b5b5" + + "65b5b5600a165627a7a72305820c35d0465bf2aede0825558c533938ea55bd711f85d5ee4bbfef990" + + "d8554fa6510029"); + } + + /** Returns the bytes of NonpayableFallbackContract.sol */ + private static byte[] getNonpayableFallbackContractBytes() { + return Hex.decode( + "60506040523415600f5760006000fd5b6013565b60488060206000396000f30" + + "060506040523615600d57600d565b341560185760006000fd5b5b5b0000a165627a7a723058201f2" + + "c39dedd348a16f4b9bd99ff935f8bea8a42050b334f0e958b15e2deb2d95e0029"); + } + + /** Returns the bytes of PayableFallbackContract.sol */ + private static byte[] getPayableFallbackContractBytes() { + return Hex.decode( + "60506040523415600f5760006000fd5b6013565b603d8060206000396000f30" + + "060506040523615600d57600d565b5b5b0000a165627a7a723058205a54983a3fd2c6098a380903d" + + "f78688d9f34e4e5e2b86df61a7cf42e1d22f2b60029"); + } + + /** Encoding to call 'notPayableFunction' in PayableContract.sol */ + private static byte[] callNonpayableFunctionEncoding() { + return Hex.decode("0f385d61"); + } + + /** Encoding to call 'payableFunction' in PayableContract.sol */ + private static byte[] callPayableFunctionEncoding() { + return Hex.decode("4a6a7407"); + } +} diff --git a/modAionImpl/test/org/aion/zero/impl/core/BloomFilterTest.java b/modAionImpl/test/org/aion/zero/impl/core/BloomFilterTest.java index af5d1b1b13..69ddb6f1c4 100644 --- a/modAionImpl/test/org/aion/zero/impl/core/BloomFilterTest.java +++ b/modAionImpl/test/org/aion/zero/impl/core/BloomFilterTest.java @@ -3,10 +3,10 @@ import static com.google.common.truth.Truth.assertThat; import java.math.BigInteger; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.crypto.HashUtil; import org.aion.mcf.vm.types.Bloom; -import org.aion.vm.api.interfaces.Address; + import org.junit.Test; /** @@ -26,7 +26,7 @@ public void testSimpleAddSearchBloom() { @Test public void testContainsAddress() { Address addr = - new AionAddress("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); + new Address("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); Bloom bloom = BloomFilter.create(addr.toBytes()); assertThat(BloomFilter.containsAddress(bloom, addr)).isTrue(); } @@ -49,7 +49,7 @@ public void testContainsEvent2() { @Test public void testCompositeBloomFiltering() { Address addr = - new AionAddress("BEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEFFFF"); + new Address("BEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEBEEFFFF"); byte[] someEvent = HashUtil.h256(BigInteger.ONE.toByteArray()); byte[] anotherEvent = HashUtil.h256(BigInteger.TWO.toByteArray()); diff --git a/modAionImpl/test/org/aion/zero/impl/db/AionBlockStoreTest.java b/modAionImpl/test/org/aion/zero/impl/db/AionBlockStoreTest.java new file mode 100644 index 0000000000..42777ac6a6 --- /dev/null +++ b/modAionImpl/test/org/aion/zero/impl/db/AionBlockStoreTest.java @@ -0,0 +1,217 @@ +package org.aion.zero.impl.db; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.List; +import org.aion.db.impl.mockdb.MockDB; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.util.TestResources; +import org.aion.zero.impl.types.AionBlock; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link AionBlockStore}. + * + * @author Alexandra Roatis + */ +public class AionBlockStoreTest { + + // simply mocking the dbs didn't work possibly because of the use of locks + // for some reason index.size() gets called by store.getChainBlockByNumber(X) + ByteArrayKeyValueDatabase index = new MockDB("index"); + ByteArrayKeyValueDatabase blocks = new MockDB("blocks"); + + // returns a list of blocks in ascending order of height + List consecutiveBlocks = TestResources.consecutiveBlocks(4); + + @Before + public void openDatabases() { + index.open(); + blocks.open(); + } + + @After + public void closeDatabases() { + index.close(); + blocks.close(); + } + + @Test + public void testGetBlocksByRange_withGensisFirstBlock() { + AionBlockStore store = spy(new AionBlockStore(index, blocks, false)); + assertThat(store.getBlocksByRange(0L, 11L)).isNull(); + } + + @Test + public void testGetBlocksByRange_withNullFirstBlock() { + AionBlockStore store = spy(new AionBlockStore(index, blocks, false)); + when(store.getChainBlockByNumber(10L)).thenReturn(null); + when(store.getBlocksByRange(10L, 11L)).thenCallRealMethod(); + + assertThat(store.getBlocksByRange(10L, 11L)).isNull(); + } + + @Test + public void testGetBlocksByRange_withSingleBlock() { + AionBlock block = consecutiveBlocks.get(0); + + AionBlockStore store = spy(new AionBlockStore(index, blocks, false)); + when(store.getChainBlockByNumber(10L)).thenReturn(block); + when(store.getBlocksByRange(10L, 10L)).thenCallRealMethod(); + + List returned = store.getBlocksByRange(10L, 10L); + assertThat(returned.size()).isEqualTo(1); + assertThat(returned).contains(block); + } + + @Test + public void testGetBlocksByRange_withDescendingOrder() { + AionBlock first = consecutiveBlocks.get(2); + AionBlock middle = consecutiveBlocks.get(1); + AionBlock last = consecutiveBlocks.get(0); + + AionBlockStore store = spy(new AionBlockStore(index, blocks, false)); + when(store.getChainBlockByNumber(first.getNumber())).thenReturn(first); + when(store.getBlockByHash(first.getParentHash())).thenReturn(middle); + when(store.getBlockByHash(middle.getParentHash())).thenReturn(last); + when(store.getBlocksByRange(first.getNumber(), last.getNumber())).thenCallRealMethod(); + + List returned = store.getBlocksByRange(first.getNumber(), last.getNumber()); + assertThat(returned.size()).isEqualTo(3); + assertThat(returned.get(0)).isEqualTo(first); + assertThat(returned.get(1)).isEqualTo(middle); + assertThat(returned.get(2)).isEqualTo(last); + } + + @Test + public void testGetBlocksByRange_withDescendingOrderAndNullLast() { + AionBlock first = consecutiveBlocks.get(2); + AionBlock middle = consecutiveBlocks.get(1); + AionBlock last = consecutiveBlocks.get(0); + + AionBlockStore store = spy(new AionBlockStore(index, blocks, false)); + when(store.getChainBlockByNumber(first.getNumber())).thenReturn(first); + when(store.getBlockByHash(first.getParentHash())).thenReturn(middle); + when(store.getBlockByHash(middle.getParentHash())).thenReturn(null); + when(store.getBlocksByRange(first.getNumber(), last.getNumber())).thenCallRealMethod(); + + // the returned list is null due to missing block in range + assertThat(store.getBlocksByRange(first.getNumber(), last.getNumber())).isNull(); + } + + @Test + public void testGetBlocksByRange_withDescendingOrderAndGenesisLast() { + AionBlock first = consecutiveBlocks.get(2); // assigning it height 2 + AionBlock middle = consecutiveBlocks.get(1); // assumed height 1 + AionBlock last = consecutiveBlocks.get(0); // assumed height 0 + + AionBlockStore store = spy(new AionBlockStore(index, blocks, false)); + // returning the block at a different number than its height + when(store.getChainBlockByNumber(2L)).thenReturn(first); + when(store.getBlockByHash(first.getParentHash())).thenReturn(middle); + when(store.getBlocksByRange(2L, 0L)).thenCallRealMethod(); + + // the returned list has only 2 elements due to the null + List returned = store.getBlocksByRange(2L, 0L); + assertThat(returned.size()).isEqualTo(2); + assertThat(returned.get(0)).isEqualTo(first); + assertThat(returned.get(1)).isEqualTo(middle); + + // there should be no attempt to retrieve the genesis + verify(store, times(0)).getBlockByHash(last.getParentHash()); + verify(store, times(0)).getBlockByHash(middle.getParentHash()); + verify(store, times(1)).getBlockByHash(first.getParentHash()); + } + + @Test + public void testGetBlocksByRange_withAscendingOrder() { + AionBlock first = consecutiveBlocks.get(0); + AionBlock middle = consecutiveBlocks.get(1); + AionBlock last = consecutiveBlocks.get(2); + + AionBlockStore store = spy(new AionBlockStore(index, blocks, false)); + when(store.getChainBlockByNumber(first.getNumber())).thenReturn(first); + when(store.getChainBlockByNumber(last.getNumber())).thenReturn(last); + when(store.getBlockByHash(last.getParentHash())).thenReturn(middle); + when(store.getBlocksByRange(first.getNumber(), last.getNumber())).thenCallRealMethod(); + + List returned = store.getBlocksByRange(first.getNumber(), last.getNumber()); + assertThat(returned.size()).isEqualTo(3); + assertThat(returned.get(0)).isEqualTo(first); + assertThat(returned.get(1)).isEqualTo(middle); + assertThat(returned.get(2)).isEqualTo(last); + } + + @Test + public void testGetBlocksByRange_withAscendingOrderAndNullMiddle() { + AionBlock first = consecutiveBlocks.get(0); + AionBlock last = consecutiveBlocks.get(2); + + AionBlockStore store = spy(new AionBlockStore(index, blocks, false)); + when(store.getChainBlockByNumber(first.getNumber())).thenReturn(first); + when(store.getChainBlockByNumber(last.getNumber())).thenReturn(last); + when(store.getBlockByHash(last.getParentHash())).thenReturn(null); + when(store.getBlocksByRange(first.getNumber(), last.getNumber())).thenCallRealMethod(); + + // the returned list is null due to missing block in range + assertThat(store.getBlocksByRange(first.getNumber(), last.getNumber())).isNull(); + } + + @Test + public void testGetBlocksByRange_withAscendingOrderAndNullLast() { + AionBlock first = consecutiveBlocks.get(0); + AionBlock middle = consecutiveBlocks.get(1); + AionBlock best = consecutiveBlocks.get(2); + AionBlock last = consecutiveBlocks.get(3); + + AionBlockStore store = spy(new AionBlockStore(index, blocks, false)); + when(store.getChainBlockByNumber(first.getNumber())).thenReturn(first); + when(store.getChainBlockByNumber(last.getNumber())).thenReturn(null); + when(store.getBestBlock()).thenReturn(best); + when(store.getBlockByHash(best.getParentHash())).thenReturn(middle); + when(store.getBlocksByRange(first.getNumber(), last.getNumber())).thenCallRealMethod(); + + List returned = store.getBlocksByRange(first.getNumber(), last.getNumber()); + assertThat(returned.size()).isEqualTo(3); + assertThat(returned.get(0)).isEqualTo(first); + assertThat(returned.get(1)).isEqualTo(middle); + assertThat(returned.get(2)).isEqualTo(best); + } + + @Test + public void testGetBlocksByRange_withAscendingOrderAndNullBest() { + AionBlock first = consecutiveBlocks.get(0); + AionBlock last = consecutiveBlocks.get(3); + + AionBlockStore store = spy(new AionBlockStore(index, blocks, false)); + when(store.getChainBlockByNumber(first.getNumber())).thenReturn(first); + when(store.getChainBlockByNumber(last.getNumber())).thenReturn(null); + when(store.getBestBlock()).thenReturn(null); + when(store.getBlocksByRange(first.getNumber(), last.getNumber())).thenCallRealMethod(); + + // the returned list is null due to corrupt kernel + assertThat(store.getBlocksByRange(first.getNumber(), last.getNumber())).isNull(); + } + + @Test + public void testGetBlocksByRange_withAscendingOrderAndIncorrectHeight() { + AionBlock first = consecutiveBlocks.get(0); + AionBlock last = consecutiveBlocks.get(1); + AionBlock best = consecutiveBlocks.get(2); + + AionBlockStore store = spy(new AionBlockStore(index, blocks, false)); + when(store.getChainBlockByNumber(first.getNumber())).thenReturn(first); + when(store.getChainBlockByNumber(last.getNumber())).thenReturn(null); + when(store.getBestBlock()).thenReturn(best); + when(store.getBlocksByRange(first.getNumber(), last.getNumber())).thenCallRealMethod(); + + // the returned list is null due to corrupt kernel + assertThat(store.getBlocksByRange(first.getNumber(), last.getNumber())).isNull(); + } +} diff --git a/modAionImpl/test/org/aion/zero/impl/db/AionContractDetailsTest.java b/modAionImpl/test/org/aion/zero/impl/db/AionContractDetailsTest.java new file mode 100644 index 0000000000..a7cabb7773 --- /dev/null +++ b/modAionImpl/test/org/aion/zero/impl/db/AionContractDetailsTest.java @@ -0,0 +1,542 @@ +package org.aion.zero.impl.db; + +import static com.google.common.truth.Truth.assertThat; +import static org.aion.mcf.db.DatabaseUtils.connectAndOpen; +import static org.aion.util.bytes.ByteUtil.EMPTY_BYTE_ARRAY; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import org.aion.db.impl.DBVendor; +import org.aion.db.impl.DatabaseFactory; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.ContractDetails; +import org.aion.interfaces.db.PruneConfig; +import org.aion.interfaces.db.RepositoryConfig; +import org.aion.log.AionLoggerFactory; +import org.aion.log.LogEnum; +import org.aion.mcf.config.CfgPrune; +import org.aion.mcf.trie.JournalPruneDataSource; +import org.aion.mcf.trie.SecureTrie; +import org.aion.mcf.tx.TransactionTypes; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.rlp.RLP; +import org.aion.rlp.RLPList; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; +import org.aion.util.bytes.ByteUtil; +import org.apache.commons.lang3.RandomUtils; +import org.junit.Test; +import org.slf4j.Logger; + +public class AionContractDetailsTest { + private static final Logger LOG = AionLoggerFactory.getLogger(LogEnum.DB.name()); + + + private static final int IN_MEMORY_STORAGE_LIMIT = + 1000000; // CfgAion.inst().getDb().getDetailsInMemoryStorageLimit(); + + protected RepositoryConfig repoConfig = + new RepositoryConfig() { + @Override + public String getDbPath() { + return ""; + } + + @Override + public PruneConfig getPruneConfig() { + return new CfgPrune(false); + } + + @Override + public ContractDetails contractDetailsImpl() { + return ContractDetailsAion.createForTesting(0, 1000000).getDetails(); + } + + @Override + public Properties getDatabaseConfig(String db_name) { + Properties props = new Properties(); + props.setProperty(DatabaseFactory.Props.DB_TYPE, DBVendor.MOCKDB.toValue()); + props.setProperty(DatabaseFactory.Props.ENABLE_HEAP_CACHE, "false"); + return props; + } + }; + + private static ContractDetails deserialize( + byte[] rlp, ByteArrayKeyValueDatabase externalStorage) { + AionContractDetailsImpl result = new AionContractDetailsImpl(); + result.setExternalStorageDataSource(externalStorage); + result.decode(rlp); + + return result; + } + + @Test + public void test_1() throws Exception { + + byte[] code = ByteUtil.hexStringToBytes("60016002"); + + byte[] key_1 = ByteUtil.hexStringToBytes("111111"); + byte[] val_1 = ByteUtil.hexStringToBytes("aaaaaa"); + + byte[] key_2 = ByteUtil.hexStringToBytes("222222"); + byte[] val_2 = ByteUtil.hexStringToBytes("bbbbbb"); + + AionContractDetailsImpl contractDetails = + new AionContractDetailsImpl( + -1, // CfgAion.inst().getDb().getPrune(), + 1000000 // CfgAion.inst().getDb().getDetailsInMemoryStorageLimit() + ); + contractDetails.setCode(code); + contractDetails.put(new DataWordImpl(key_1).toWrapper(), new DataWordImpl(val_1).toWrapper()); + contractDetails.put(new DataWordImpl(key_2).toWrapper(), new DataWordImpl(val_2).toWrapper()); + contractDetails.setAddress(Address.ZERO_ADDRESS()); + + byte[] data = contractDetails.getEncoded(); + + AionContractDetailsImpl contractDetails_ = new AionContractDetailsImpl(data); + + assertEquals(ByteUtil.toHexString(code), ByteUtil.toHexString(contractDetails_.getCode())); + + assertEquals( + ByteUtil.toHexString(val_1), + ByteUtil.toHexString( + contractDetails_ + .get(new DataWordImpl(key_1).toWrapper()) + .getNoLeadZeroesData())); + + assertEquals( + ByteUtil.toHexString(val_2), + ByteUtil.toHexString( + contractDetails_ + .get(new DataWordImpl(key_2).toWrapper()) + .getNoLeadZeroesData())); + } + + @Test + public void test_2() throws Exception { + + byte[] code = + ByteUtil.hexStringToBytes( + "7c0100000000000000000000000000000000000000000000000000000000600035046333d546748114610065578063430fe5f01461007c5780634d432c1d1461008d578063501385b2146100b857806357eb3b30146100e9578063dbc7df61146100fb57005b6100766004356024356044356102f0565b60006000f35b61008760043561039e565b60006000f35b610098600435610178565b8073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b6100c96004356024356044356101a0565b8073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b6100f1610171565b8060005260206000f35b610106600435610133565b8360005282602052816040528073ffffffffffffffffffffffffffffffffffffffff1660605260806000f35b5b60006020819052908152604090208054600182015460028301546003909301549192909173ffffffffffffffffffffffffffffffffffffffff1684565b5b60015481565b5b60026020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081206002015481908302341080156101fe575073ffffffffffffffffffffffffffffffffffffffff8516600090815260208190526040812054145b8015610232575073ffffffffffffffffffffffffffffffffffffffff85166000908152602081905260409020600101548390105b61023b57610243565b3391506102e8565b6101966103ca60003973ffffffffffffffffffffffffffffffffffffffff3381166101965285166101b68190526000908152602081905260408120600201546101d6526101f68490526102169080f073ffffffffffffffffffffffffffffffffffffffff8616600090815260208190526040902060030180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905591508190505b509392505050565b73ffffffffffffffffffffffffffffffffffffffff33166000908152602081905260408120548190821461032357610364565b60018054808201909155600090815260026020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790555b50503373ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090209081556001810192909255600290910155565b3373ffffffffffffffffffffffffffffffffffffffff166000908152602081905260409020600201555600608061019660043960048051602451604451606451600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000908116909517815560018054909516909317909355600355915561013390819061006390396000f3007c0100000000000000000000000000000000000000000000000000000000600035046347810fe381146100445780637e4a1aa81461005557806383d2421b1461006957005b61004f6004356100ab565b60006000f35b6100636004356024356100fc565b60006000f35b61007460043561007a565b60006000f35b6001543373ffffffffffffffffffffffffffffffffffffffff9081169116146100a2576100a8565b60078190555b50565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905550565b6001543373ffffffffffffffffffffffffffffffffffffffff9081169116146101245761012f565b600582905560068190555b505056"); + Address address = Address.wrap(RandomUtils.nextBytes(Address.SIZE)); + + byte[] key_0 = ByteUtil.hexStringToBytes("18d63b70aa690ad37cb50908746c9a55"); + byte[] val_0 = ByteUtil.hexStringToBytes("00000000000000000000000000000064"); + + byte[] key_1 = ByteUtil.hexStringToBytes("18d63b70aa690ad37cb50908746c9a56"); + byte[] val_1 = ByteUtil.hexStringToBytes("0000000000000000000000000000000c"); + + byte[] key_2 = ByteUtil.hexStringToBytes("5a448d1967513482947d1d3f6104316f"); + + byte[] key_3 = ByteUtil.hexStringToBytes("5a448d1967513482947d1d3f61043171"); + byte[] val_3 = ByteUtil.hexStringToBytes("00000000000000000000000000000014"); + + byte[] key_4 = ByteUtil.hexStringToBytes("18d63b70aa690ad37cb50908746c9a54"); + + byte[] key_5 = ByteUtil.hexStringToBytes("5a448d1967513482947d1d3f61043170"); + byte[] val_5 = ByteUtil.hexStringToBytes("00000000000000000000000000000078"); + + byte[] key_6 = ByteUtil.hexStringToBytes("c83a08bbccc01a0644d599ccd2a7c2e0"); + byte[] val_6 = ByteUtil.hexStringToBytes("8fbec874791c4e3f9f48a59a44686efe"); + + byte[] key_7 = ByteUtil.hexStringToBytes("5aa541c6c03f602a426f04ae47508bb8"); + byte[] val_7 = ByteUtil.hexStringToBytes("7a657031000000000000000000000000"); + + byte[] key_8 = ByteUtil.hexStringToBytes("5aa541c6c03f602a426f04ae47508bb9"); + byte[] val_8 = ByteUtil.hexStringToBytes("000000000000000000000000000000c8"); + + byte[] key_9 = ByteUtil.hexStringToBytes("5aa541c6c03f602a426f04ae47508bba"); + byte[] val_9 = ByteUtil.hexStringToBytes("0000000000000000000000000000000a"); + + byte[] key_10 = ByteUtil.hexStringToBytes("00000000000000000000000000000001"); + byte[] val_10 = ByteUtil.hexStringToBytes("00000000000000000000000000000003"); + + byte[] key_11 = ByteUtil.hexStringToBytes("5aa541c6c03f602a426f04ae47508bbb"); + byte[] val_11 = ByteUtil.hexStringToBytes("194bcfc3670d8a1613e5b0c790036a35"); + + byte[] key_12 = ByteUtil.hexStringToBytes("aee92919b8c3389af86ef24535e8a28c"); + byte[] val_12 = ByteUtil.hexStringToBytes("cfe293a85bef5915e1a7acb37bf0c685"); + + byte[] key_13 = ByteUtil.hexStringToBytes("65c996598dc972688b7ace676c89077b"); + byte[] val_13 = ByteUtil.hexStringToBytes("d6ee27e285f2de7b68e8db25cf1b1063"); + + AionContractDetailsImpl contractDetails = new AionContractDetailsImpl(); + contractDetails.setCode(code); + contractDetails.setAddress(address); + contractDetails.put(new DataWordImpl(key_0).toWrapper(), new DataWordImpl(val_0).toWrapper()); + contractDetails.put(new DataWordImpl(key_1).toWrapper(), new DataWordImpl(val_1).toWrapper()); + contractDetails.delete(new DataWordImpl(key_2).toWrapper()); + contractDetails.put(new DataWordImpl(key_3).toWrapper(), new DataWordImpl(val_3).toWrapper()); + contractDetails.delete(new DataWordImpl(key_4).toWrapper()); + contractDetails.put(new DataWordImpl(key_5).toWrapper(), new DataWordImpl(val_5).toWrapper()); + contractDetails.put(new DataWordImpl(key_6).toWrapper(), new DataWordImpl(val_6).toWrapper()); + contractDetails.put(new DataWordImpl(key_7).toWrapper(), new DataWordImpl(val_7).toWrapper()); + contractDetails.put(new DataWordImpl(key_8).toWrapper(), new DataWordImpl(val_8).toWrapper()); + contractDetails.put(new DataWordImpl(key_9).toWrapper(), new DataWordImpl(val_9).toWrapper()); + contractDetails.put(new DataWordImpl(key_10).toWrapper(), new DataWordImpl(val_10).toWrapper()); + contractDetails.put(new DataWordImpl(key_11).toWrapper(), new DataWordImpl(val_11).toWrapper()); + contractDetails.put(new DataWordImpl(key_12).toWrapper(), new DataWordImpl(val_12).toWrapper()); + contractDetails.put(new DataWordImpl(key_13).toWrapper(), new DataWordImpl(val_13).toWrapper()); + + byte[] data = contractDetails.getEncoded(); + + AionContractDetailsImpl contractDetails_ = new AionContractDetailsImpl(data); + + assertEquals(ByteUtil.toHexString(code), ByteUtil.toHexString(contractDetails_.getCode())); + + assertTrue(address.equals(contractDetails_.getAddress())); + + assertEquals( + ByteUtil.toHexString(val_1), + ByteUtil.toHexString( + contractDetails_.get(new DataWordImpl(key_1).toWrapper()).getData())); + + assertNull(contractDetails_.get(new DataWordImpl(key_2).toWrapper())); + + assertEquals( + ByteUtil.toHexString(val_3), + ByteUtil.toHexString( + contractDetails_.get(new DataWordImpl(key_3).toWrapper()).getData())); + + assertNull(contractDetails_.get(new DataWordImpl(key_4).toWrapper())); + + assertEquals( + ByteUtil.toHexString(val_5), + ByteUtil.toHexString( + contractDetails_.get(new DataWordImpl(key_5).toWrapper()).getData())); + + assertEquals( + ByteUtil.toHexString(val_6), + ByteUtil.toHexString( + contractDetails_.get(new DataWordImpl(key_6).toWrapper()).getData())); + + assertEquals( + ByteUtil.toHexString(val_7), + ByteUtil.toHexString( + contractDetails_.get(new DataWordImpl(key_7).toWrapper()).getData())); + + assertEquals( + ByteUtil.toHexString(val_8), + ByteUtil.toHexString( + contractDetails_.get(new DataWordImpl(key_8).toWrapper()).getData())); + + assertEquals( + ByteUtil.toHexString(val_9), + ByteUtil.toHexString( + contractDetails_.get(new DataWordImpl(key_9).toWrapper()).getData())); + + assertEquals( + ByteUtil.toHexString(val_10), + ByteUtil.toHexString( + contractDetails_.get(new DataWordImpl(key_10).toWrapper()).getData())); + + assertEquals( + ByteUtil.toHexString(val_11), + ByteUtil.toHexString( + contractDetails_.get(new DataWordImpl(key_11).toWrapper()).getData())); + + assertEquals( + ByteUtil.toHexString(val_12), + ByteUtil.toHexString( + contractDetails_.get(new DataWordImpl(key_12).toWrapper()).getData())); + + assertEquals( + ByteUtil.toHexString(val_13), + ByteUtil.toHexString( + contractDetails_.get(new DataWordImpl(key_13).toWrapper()).getData())); + } + + @Test + public void testExternalStorageSerialization() { + Address address = Address.wrap(RandomUtils.nextBytes(Address.SIZE)); + byte[] code = RandomUtils.nextBytes(512); + Map elements = new HashMap<>(); + + AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig); + ByteArrayKeyValueDatabase externalStorage = repository.getDetailsDatabase(); + + AionContractDetailsImpl original = new AionContractDetailsImpl(0, 1000000); + + original.setExternalStorageDataSource(externalStorage); + original.setAddress(address); + original.setCode(code); + original.externalStorage = true; + + for (int i = 0; i < IN_MEMORY_STORAGE_LIMIT / 64 + 10; i++) { + DataWordImpl key = new DataWordImpl(RandomUtils.nextBytes(16)); + DataWordImpl value = new DataWordImpl(RandomUtils.nextBytes(16)); + + elements.put(key, value); + original.put(key.toWrapper(), wrapValueForPut(value)); + } + + original.syncStorage(); + + byte[] rlp = original.getEncoded(); + + AionContractDetailsImpl deserialized = new AionContractDetailsImpl(); + deserialized.setExternalStorageDataSource(externalStorage); + deserialized.decode(rlp); + + assertEquals(deserialized.externalStorage, true); + assertTrue(address.equals(deserialized.getAddress())); + assertEquals(ByteUtil.toHexString(code), ByteUtil.toHexString(deserialized.getCode())); + + for (DataWordImpl key : elements.keySet()) { + assertEquals( + elements.get(key).toWrapper(), + wrapValueFromGet(deserialized.get(key.toWrapper()))); + } + + DataWordImpl deletedKey = elements.keySet().iterator().next(); + + deserialized.delete(deletedKey.toWrapper()); + deserialized.delete(new DataWordImpl(RandomUtils.nextBytes(16)).toWrapper()); + } + + @Test + public void testContractStorageSwitch() { + Address address = Address.wrap(RandomUtils.nextBytes(Address.SIZE)); + byte[] code = RandomUtils.nextBytes(512); + Map elements = new HashMap<>(); + + int memstoragelimit = 512; + AionContractDetailsImpl original = new AionContractDetailsImpl(0, memstoragelimit); + + // getting storage specific properties + Properties sharedProps; + sharedProps = repoConfig.getDatabaseConfig("storage"); + sharedProps.setProperty(DatabaseFactory.Props.ENABLE_LOCKING, "false"); + sharedProps.setProperty(DatabaseFactory.Props.DB_PATH, repoConfig.getDbPath()); + sharedProps.setProperty(DatabaseFactory.Props.DB_NAME, "storage"); + ByteArrayKeyValueDatabase storagedb = connectAndOpen(sharedProps, LOG); + JournalPruneDataSource jpd = new JournalPruneDataSource(storagedb); + original.setDataSource(jpd); + original.setAddress(address); + original.setCode(code); + + // the first 2 insertion use memory storage + for (int i = 0; i < 2; i++) { + DataWordImpl key = new DataWordImpl(RandomUtils.nextBytes(16)); + DataWordImpl value = new DataWordImpl(RandomUtils.nextBytes(16)); + + elements.put(key, value); + original.put(key.toWrapper(), wrapValueForPut(value)); + } + + original.decode(original.getEncoded()); + original.syncStorage(); + assertTrue(!original.externalStorage); + + // transfer to external storage since 3rd insert + DataWordImpl key3rd = new DataWordImpl(RandomUtils.nextBytes(16)); + DataWordImpl value = new DataWordImpl(RandomUtils.nextBytes(16)); + elements.put(key3rd, value); + original.put(key3rd.toWrapper(), wrapValueForPut(value)); + + original.decode(original.getEncoded()); + original.syncStorage(); + assertTrue(original.externalStorage); + + byte[] rlp = original.getEncoded(); + + AionContractDetailsImpl deserialized = new AionContractDetailsImpl(0, memstoragelimit); + deserialized.setDataSource(jpd); + deserialized.decode(rlp); + + assertTrue(deserialized.externalStorage); + assertEquals(address, deserialized.getAddress()); + assertEquals(ByteUtil.toHexString(code), ByteUtil.toHexString(deserialized.getCode())); + + for (DataWordImpl key : elements.keySet()) { + assertEquals( + elements.get(key).toWrapper(), + wrapValueFromGet(deserialized.get(key.toWrapper()))); + } + + DataWordImpl deletedKey = elements.keySet().iterator().next(); + + deserialized.delete(deletedKey.toWrapper()); + deserialized.delete(new DataWordImpl(RandomUtils.nextBytes(16)).toWrapper()); + } + + @Test + public void testExternalStorageTransition() { + Address address = Address.wrap(RandomUtils.nextBytes(Address.SIZE)); + byte[] code = RandomUtils.nextBytes(512); + Map elements = new HashMap<>(); + + AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig); + ByteArrayKeyValueDatabase externalStorage = repository.getDetailsDatabase(); + + AionContractDetailsImpl original = new AionContractDetailsImpl(0, 1000000); + original.setExternalStorageDataSource(externalStorage); + original.setAddress(address); + original.setCode(code); + + for (int i = 0; i < IN_MEMORY_STORAGE_LIMIT / 64 + 10; i++) { + DataWordImpl key = new DataWordImpl(RandomUtils.nextBytes(16)); + DataWordImpl value = new DataWordImpl(RandomUtils.nextBytes(16)); + + elements.put(key, value); + original.put(key.toWrapper(), wrapValueForPut(value)); + } + + original.syncStorage(); + assertTrue(!externalStorage.isEmpty()); + + ContractDetails deserialized = deserialize(original.getEncoded(), externalStorage); + + // adds keys for in-memory storage limit overflow + for (int i = 0; i < 10; i++) { + DataWordImpl key = new DataWordImpl(RandomUtils.nextBytes(16)); + DataWordImpl value = new DataWordImpl(RandomUtils.nextBytes(16)); + + elements.put(key, value); + + deserialized.put(key.toWrapper(), wrapValueForPut(value)); + } + + deserialized.syncStorage(); + assertTrue(!externalStorage.isEmpty()); + + deserialized = deserialize(deserialized.getEncoded(), externalStorage); + + for (DataWordImpl key : elements.keySet()) { + assertEquals( + elements.get(key).toWrapper(), + wrapValueFromGet(deserialized.get(key.toWrapper()))); + } + } + + private static ByteArrayWrapper wrapValueForPut(DataWordImpl value) { + return (value.isZero()) + ? new ByteArrayWrapper(value.getData()) + : new ByteArrayWrapper(value.getNoLeadZeroesData()); + } + + private static ByteArrayWrapper wrapValueFromGet(ByteArrayWrapper value) { + return new ByteArrayWrapper(new DataWordImpl(value.getData()).getData()); + } + + @Test + public void testEncodingSwitchWithTrie() throws Exception { + Address address = Address.wrap(RandomUtils.nextBytes(Address.SIZE)); + byte[] code = RandomUtils.nextBytes(512); + + // create old encoding + byte[] rlpAddress = RLP.encodeElement(address.toBytes()); + byte[] rlpIsExternalStorage = RLP.encodeByte((byte) 0); + byte[] rlpStorageRoot = RLP.encodeElement(EMPTY_BYTE_ARRAY); + byte[] rlpStorage = RLP.encodeElement(new SecureTrie(null).serialize()); + byte[] rlpCode = RLP.encodeList(RLP.encodeElement(code)); + + byte[] oldEncoding = + RLP.encodeList( + rlpAddress, rlpIsExternalStorage, rlpStorageRoot, rlpStorage, rlpCode); + + // create object using encoding + AionContractDetailsImpl details = new AionContractDetailsImpl(oldEncoding); + + // check that the VM type is correct + assertThat(details.getVmType()).isEqualTo(TransactionTypes.FVM_CREATE_CODE); + + // check that the encoding has been updated + byte[] newEncoding = + RLP.encodeList( + rlpAddress, + rlpIsExternalStorage, + rlpStorageRoot, + rlpStorage, + rlpCode, + RLP.encodeByte(TransactionTypes.FVM_CREATE_CODE)); + assertThat(details.getEncoded()).isEqualTo(newEncoding); + } + + @Test + public void testEncodingSwitchWithRoot() throws Exception { + Address address = Address.wrap(RandomUtils.nextBytes(Address.SIZE)); + byte[] code = RandomUtils.nextBytes(512); + + // create old encoding + byte[] rlpAddress = RLP.encodeElement(address.toBytes()); + byte[] rlpIsExternalStorage = RLP.encodeByte((byte) 1); + byte[] rlpStorageRoot = RLP.encodeElement(RandomUtils.nextBytes(32)); + byte[] rlpStorage = RLP.encodeElement(EMPTY_BYTE_ARRAY); + byte[] rlpCode = RLP.encodeList(RLP.encodeElement(code)); + + byte[] oldEncoding = + RLP.encodeList( + rlpAddress, rlpIsExternalStorage, rlpStorageRoot, rlpStorage, rlpCode); + + // create object using encoding + AionContractDetailsImpl details = new AionContractDetailsImpl(oldEncoding); + + // check that the VM type is correct + assertThat(details.getVmType()).isEqualTo(TransactionTypes.FVM_CREATE_CODE); + + // check that the encoding has been updated + byte[] newEncoding = + RLP.encodeList( + rlpAddress, + rlpIsExternalStorage, + rlpStorageRoot, + rlpStorage, + rlpCode, + RLP.encodeByte(TransactionTypes.FVM_CREATE_CODE)); + assertThat(details.getEncoded()).isEqualTo(newEncoding); + } + + @Test + public void testEncodingWithAVM() throws Exception { + Address address = Address.wrap(RandomUtils.nextBytes(Address.SIZE)); + byte[] code = RandomUtils.nextBytes(512); + + // create old encoding + byte[] rlpAddress = RLP.encodeElement(address.toBytes()); + byte[] rlpIsExternalStorage = RLP.encodeByte((byte) 1); + byte[] rlpStorageRoot = RLP.encodeElement(RandomUtils.nextBytes(32)); + byte[] rlpStorage = RLP.encodeElement(EMPTY_BYTE_ARRAY); + byte[] rlpCode = RLP.encodeList(RLP.encodeElement(code)); + + byte[] oldEncoding = + RLP.encodeList( + rlpAddress, + rlpIsExternalStorage, + rlpStorageRoot, + rlpStorage, + rlpCode, + RLP.encodeByte(TransactionTypes.AVM_CREATE_CODE)); + + // create object using encoding + AionContractDetailsImpl details = new AionContractDetailsImpl(oldEncoding); + + // check that the VM type is correct + assertThat(details.getVmType()).isEqualTo(TransactionTypes.AVM_CREATE_CODE); + } + + @Test + public void testEncodingSize() throws Exception { + Address address = Address.wrap(RandomUtils.nextBytes(Address.SIZE)); + byte[] code = RandomUtils.nextBytes(512); + + AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig); + ByteArrayKeyValueDatabase externalStorage = repository.getDetailsDatabase(); + + AionContractDetailsImpl details = new AionContractDetailsImpl(0, 1000000); + details.setExternalStorageDataSource(externalStorage); + details.setAddress(address); + details.setCode(code); + + // ensure correct size after use of other constructor + RLPList data = (RLPList) RLP.decode2(details.getEncoded()).get(0); + assertThat(data.size()).isEqualTo(6); + + // check that the VM type is correct + assertThat(details.getVmType()).isEqualTo(TransactionTypes.FVM_CREATE_CODE); + } +} diff --git a/modMcf/test/org/aion/mcf/db/AionRepositoryCacheTest.java b/modAionImpl/test/org/aion/zero/impl/db/AionRepositoryCacheTest.java similarity index 80% rename from modMcf/test/org/aion/mcf/db/AionRepositoryCacheTest.java rename to modAionImpl/test/org/aion/zero/impl/db/AionRepositoryCacheTest.java index 9b7870c98b..3ffbee31cd 100644 --- a/modMcf/test/org/aion/mcf/db/AionRepositoryCacheTest.java +++ b/modAionImpl/test/org/aion/zero/impl/db/AionRepositoryCacheTest.java @@ -1,4 +1,4 @@ -package org.aion.mcf.db; +package org.aion.zero.impl.db; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @@ -7,21 +7,18 @@ import java.util.List; import java.util.Map; import java.util.Properties; -import org.aion.base.db.IContractDetails; -import org.aion.base.db.IPruneConfig; -import org.aion.base.db.IRepositoryConfig; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.vm.IDataWord; +import org.aion.interfaces.db.ContractDetails; +import org.aion.interfaces.db.PruneConfig; +import org.aion.interfaces.db.RepositoryConfig; +import org.aion.interfaces.vm.DataWord; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.db.impl.DBVendor; import org.aion.db.impl.DatabaseFactory; import org.aion.mcf.config.CfgPrune; -import org.aion.mcf.vm.types.DataWord; import org.aion.mcf.vm.types.DoubleDataWord; -import org.aion.vm.api.interfaces.Address; -import org.aion.zero.db.AionRepositoryCache; -import org.aion.zero.impl.db.AionRepositoryImpl; -import org.aion.zero.impl.db.ContractDetailsAion; + import org.apache.commons.lang3.RandomUtils; import org.junit.After; import org.junit.Before; @@ -32,20 +29,20 @@ public class AionRepositoryCacheTest { @Before public void setup() { - IRepositoryConfig repoConfig = - new IRepositoryConfig() { + RepositoryConfig repoConfig = + new RepositoryConfig() { @Override public String getDbPath() { return ""; } @Override - public IPruneConfig getPruneConfig() { + public PruneConfig getPruneConfig() { return new CfgPrune(false); } @Override - public IContractDetails contractDetailsImpl() { + public ContractDetails contractDetailsImpl() { return ContractDetailsAion.createForTesting(0, 1000000).getDetails(); } @@ -70,13 +67,13 @@ public void testGetStorageValueNoSuchAddress() { assertNull( cache.getStorageValue( getNewAddress(), - new DataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper())); + new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper())); } @Test public void testGetStorageValueIsSingleZero() { Address address = getNewAddress(); - IDataWord key = new DataWord(RandomUtils.nextBytes(DataWord.BYTES)); + DataWord key = new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)); cache.removeStorageRow(address, key.toWrapper()); assertNull(cache.getStorageValue(address, key.toWrapper())); @@ -88,7 +85,7 @@ public void testGetStorageValueIsSingleZero() { @Test public void testGetStorageValueIsDoubleZero() { Address address = getNewAddress(); - IDataWord key = new DataWord(RandomUtils.nextBytes(DataWord.BYTES)); + DataWord key = new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)); cache.removeStorageRow(address, key.toWrapper()); assertNull(cache.getStorageValue(address, key.toWrapper())); @@ -100,19 +97,19 @@ public void testGetStorageValueIsDoubleZero() { @Test public void testGetStorageValueWithSingleZeroKey() { Address address = getNewAddress(); - ByteArrayWrapper value = new DataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper(); - cache.addStorageRow(address, DataWord.ZERO.toWrapper(), value); - assertEquals(value, cache.getStorageValue(address, DataWord.ZERO.toWrapper())); + ByteArrayWrapper value = new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper(); + cache.addStorageRow(address, DataWordImpl.ZERO.toWrapper(), value); + assertEquals(value, cache.getStorageValue(address, DataWordImpl.ZERO.toWrapper())); value = new DoubleDataWord(RandomUtils.nextBytes(DoubleDataWord.BYTES)).toWrapper(); - cache.addStorageRow(address, DataWord.ZERO.toWrapper(), value); - assertEquals(value, cache.getStorageValue(address, DataWord.ZERO.toWrapper())); + cache.addStorageRow(address, DataWordImpl.ZERO.toWrapper(), value); + assertEquals(value, cache.getStorageValue(address, DataWordImpl.ZERO.toWrapper())); } @Test public void testGetStorageValueWithDoubleZeroKey() { Address address = getNewAddress(); - ByteArrayWrapper value = new DataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper(); + ByteArrayWrapper value = new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper(); cache.addStorageRow(address, DoubleDataWord.ZERO.toWrapper(), value); assertEquals(value, cache.getStorageValue(address, DoubleDataWord.ZERO.toWrapper())); @@ -126,12 +123,12 @@ public void testGetStorageValueWithZeroKeyAndValue() { Address address = getNewAddress(); // single-single - cache.removeStorageRow(address, DataWord.ZERO.toWrapper()); - assertNull(cache.getStorageValue(address, DataWord.ZERO.toWrapper())); + cache.removeStorageRow(address, DataWordImpl.ZERO.toWrapper()); + assertNull(cache.getStorageValue(address, DataWordImpl.ZERO.toWrapper())); // single-double - cache.removeStorageRow(address, DataWord.ZERO.toWrapper()); - assertNull(cache.getStorageValue(address, DataWord.ZERO.toWrapper())); + cache.removeStorageRow(address, DataWordImpl.ZERO.toWrapper()); + assertNull(cache.getStorageValue(address, DataWordImpl.ZERO.toWrapper())); // double-single cache.removeStorageRow(address, DoubleDataWord.ZERO.toWrapper()); @@ -145,7 +142,7 @@ public void testGetStorageValueWithZeroKeyAndValue() { @Test public void testOverwriteValueWithSingleZero() { Address address = getNewAddress(); - ByteArrayWrapper key = new DataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper(); + ByteArrayWrapper key = new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper(); ByteArrayWrapper value = new DoubleDataWord(RandomUtils.nextBytes(DoubleDataWord.BYTES)).toWrapper(); cache.addStorageRow(address, key, value); @@ -159,7 +156,7 @@ public void testOverwriteValueWithDoubleZero() { Address address = getNewAddress(); ByteArrayWrapper key = new DoubleDataWord(RandomUtils.nextBytes(DoubleDataWord.BYTES)).toWrapper(); - ByteArrayWrapper value = new DataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper(); + ByteArrayWrapper value = new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper(); cache.addStorageRow(address, key, value); assertEquals(value, cache.getStorageValue(address, key)); cache.removeStorageRow(address, key); @@ -189,7 +186,7 @@ public void testGetStorageValueEnMass() { /** Returns a new random address. */ private Address getNewAddress() { - return new AionAddress(RandomUtils.nextBytes(Address.SIZE)); + return new Address(RandomUtils.nextBytes(Address.SIZE)); } private List
    getAddressesInBulk(int num) { @@ -264,10 +261,10 @@ private List getValuesInBulk(int numValues) { return values; } - /** Returns a random DataWord if isSingleWord is true, otherwise a random DoubleDataWord. */ - private IDataWord getRandomWord(boolean isSingleWord) { + /** Returns a random DataWordImpl if isSingleWord is true, otherwise a random DoubleDataWord. */ + private DataWord getRandomWord(boolean isSingleWord) { return (isSingleWord) - ? new DataWord(RandomUtils.nextBytes(DataWord.BYTES)) + ? new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)) : new DoubleDataWord(RandomUtils.nextBytes(DoubleDataWord.BYTES)); } } diff --git a/modAionImpl/test/org/aion/zero/impl/db/AionRepositoryImplTest.java b/modAionImpl/test/org/aion/zero/impl/db/AionRepositoryImplTest.java index 80e45a7549..9655965384 100644 --- a/modAionImpl/test/org/aion/zero/impl/db/AionRepositoryImplTest.java +++ b/modAionImpl/test/org/aion/zero/impl/db/AionRepositoryImplTest.java @@ -5,15 +5,16 @@ import java.math.BigInteger; import java.util.Optional; import java.util.Properties; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.db.IContractDetails; -import org.aion.base.db.IPruneConfig; -import org.aion.base.db.IRepository; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.db.IRepositoryConfig; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; + +import org.aion.interfaces.db.ContractDetails; +import org.aion.interfaces.db.PruneConfig; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.interfaces.db.RepositoryConfig; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.Repository; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.HashUtil; import org.aion.db.impl.DBVendor; import org.aion.db.impl.DatabaseFactory; @@ -21,9 +22,8 @@ import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; import org.aion.mcf.trie.TrieNodeResult; -import org.aion.mcf.vm.types.DataWord; -import org.aion.vm.api.interfaces.Address; -import org.aion.zero.db.AionContractDetailsImpl; + +import org.aion.util.bytes.ByteUtil; import org.aion.zero.impl.sync.DatabaseType; import org.junit.FixMethodOrder; import org.junit.Test; @@ -32,20 +32,20 @@ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class AionRepositoryImplTest { - protected IRepositoryConfig repoConfig = - new IRepositoryConfig() { + protected RepositoryConfig repoConfig = + new RepositoryConfig() { @Override public String getDbPath() { return ""; } @Override - public IPruneConfig getPruneConfig() { + public PruneConfig getPruneConfig() { return new CfgPrune(false); } @Override - public IContractDetails contractDetailsImpl() { + public ContractDetails contractDetailsImpl() { return ContractDetailsAion.createForTesting(0, 1000000).getDetails(); } @@ -70,9 +70,9 @@ public void testAccountStateUpdate() { AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig); byte[] originalRoot = repository.getRoot(); - Address defaultAccount = AionAddress.wrap(ByteUtil.hexStringToBytes(value1)); + Address defaultAccount = Address.wrap(ByteUtil.hexStringToBytes(value1)); - IRepositoryCache track = repository.startTracking(); + RepositoryCache track = repository.startTracking(); track.addBalance(defaultAccount, BigInteger.valueOf(1)); track.flush(); @@ -86,9 +86,9 @@ public void testAccountStateUpdate() { @Test public void testAccountAddCodeStorage() { AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig); - IRepositoryCache track = repository.startTracking(); + RepositoryCache track = repository.startTracking(); - Address defaultAccount = AionAddress.wrap(ByteUtil.hexStringToBytes(value1)); + Address defaultAccount = Address.wrap(ByteUtil.hexStringToBytes(value1)); track.addBalance(defaultAccount, BigInteger.valueOf(1)); byte[] originalRoot = repository.getRoot(); @@ -107,9 +107,9 @@ public void testAccountAddCodeStorage() { @Test public void testAccountStateUpdateStorageRow() { AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig); - IRepositoryCache track = repository.startTracking(); + RepositoryCache track = repository.startTracking(); - Address defaultAccount = AionAddress.wrap(ByteUtil.hexStringToBytes(value1)); + Address defaultAccount = Address.wrap(ByteUtil.hexStringToBytes(value1)); track.addBalance(defaultAccount, BigInteger.valueOf(1)); // Consider the original root the one after an account has been added @@ -117,13 +117,13 @@ public void testAccountStateUpdateStorageRow() { byte[] key = HashUtil.blake128("hello".getBytes()); byte[] value = HashUtil.blake128("world".getBytes()); track.addStorageRow( - defaultAccount, new DataWord(key).toWrapper(), new DataWord(value).toWrapper()); + defaultAccount, new DataWordImpl(key).toWrapper(), new DataWordImpl(value).toWrapper()); track.flush(); byte[] retrievedValue = repository - .getStorageValue(defaultAccount, new DataWord(key).toWrapper()) + .getStorageValue(defaultAccount, new DataWordImpl(key).toWrapper()) .getNoLeadZeroesData(); assertThat(retrievedValue).isEqualTo(value); @@ -136,9 +136,9 @@ public void testAccountStateUpdateStorageRow() { @Test public void testAccountStateUpdateStorageRowFlush() { AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig); - IRepositoryCache track = repository.startTracking(); + RepositoryCache track = repository.startTracking(); - Address defaultAccount = AionAddress.wrap(ByteUtil.hexStringToBytes(value1)); + Address defaultAccount = Address.wrap(ByteUtil.hexStringToBytes(value1)); track.addBalance(defaultAccount, BigInteger.valueOf(1)); // Consider the original root the one after an account has been added @@ -146,7 +146,7 @@ public void testAccountStateUpdateStorageRowFlush() { byte[] key = HashUtil.blake128("hello".getBytes()); byte[] value = HashUtil.blake128("world".getBytes()); track.addStorageRow( - defaultAccount, new DataWord(key).toWrapper(), new DataWord(value).toWrapper()); + defaultAccount, new DataWordImpl(key).toWrapper(), new DataWordImpl(value).toWrapper()); // does not call parent's flush track.flush(); @@ -154,15 +154,15 @@ public void testAccountStateUpdateStorageRowFlush() { repository.flush(); /** Verify that the account has been flushed */ - IByteArrayKeyValueDatabase detailsDB = repository.getDetailsDatabase(); + ByteArrayKeyValueDatabase detailsDB = repository.getDetailsDatabase(); Optional serializedDetails = detailsDB.get(defaultAccount.toBytes()); assertThat(serializedDetails.isPresent()).isEqualTo(true); AionContractDetailsImpl details = new AionContractDetailsImpl(0, 1000000); details.decode(serializedDetails.get()); - assertThat(details.get(new DataWord(key).toWrapper())) - .isEqualTo(new DataWord(value).toWrapper()); + assertThat(details.get(new DataWordImpl(key).toWrapper())) + .isEqualTo(new DataWordImpl(value).toWrapper()); } /** Repo track test suite */ @@ -174,9 +174,9 @@ public void testAccountStateUpdateStorageRowFlush() { @Test public void testRepoTrackUpdateStorageRow() { final AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig); - final IRepositoryCache> repoTrack = + final RepositoryCache> repoTrack = repository.startTracking(); - final Address defaultAccount = AionAddress.wrap(ByteUtil.hexStringToBytes(value1)); + final Address defaultAccount = Address.wrap(ByteUtil.hexStringToBytes(value1)); final byte[] key = HashUtil.blake128("hello".getBytes()); final byte[] value = HashUtil.blake128("world".getBytes()); @@ -185,16 +185,16 @@ public void testRepoTrackUpdateStorageRow() { final byte[] originalRoot = repository.getRoot(); repoTrack.addStorageRow( - defaultAccount, new DataWord(key).toWrapper(), new DataWord(value).toWrapper()); + defaultAccount, new DataWordImpl(key).toWrapper(), new DataWordImpl(value).toWrapper()); ByteArrayWrapper retrievedStorageValue = - repoTrack.getStorageValue(defaultAccount, new DataWord(key).toWrapper()); - assertThat(retrievedStorageValue).isEqualTo(new DataWord(value).toWrapper()); + repoTrack.getStorageValue(defaultAccount, new DataWordImpl(key).toWrapper()); + assertThat(retrievedStorageValue).isEqualTo(new DataWordImpl(value).toWrapper()); // commit changes, then check that the root has updated repoTrack.flush(); - assertThat(repository.getStorageValue(defaultAccount, new DataWord(key).toWrapper())) + assertThat(repository.getStorageValue(defaultAccount, new DataWordImpl(key).toWrapper())) .isEqualTo(retrievedStorageValue); final byte[] newRoot = repository.getRoot(); @@ -203,14 +203,14 @@ public void testRepoTrackUpdateStorageRow() { @Test public void testSyncToPreviousRootNoFlush() { - final Address FIRST_ACC = AionAddress.wrap(value2); - final Address SECOND_ACC = AionAddress.wrap(value3); + final Address FIRST_ACC = Address.wrap(value2); + final Address SECOND_ACC = Address.wrap(value3); final AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig); byte[] originalRoot = repository.getRoot(); // now create a new account - IRepositoryCache track = repository.startTracking(); + RepositoryCache track = repository.startTracking(); track.addBalance(FIRST_ACC, BigInteger.ONE); track.flush(); @@ -249,11 +249,11 @@ public void testSyncToPreviousRootNoFlush() { @Test public void testSyncToPreviousRootWithFlush() { - final Address FIRST_ACC = AionAddress.wrap(value2); + final Address FIRST_ACC = Address.wrap(value2); AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig); byte[] originalRoot = repository.getRoot(); - IRepositoryCache track = repository.startTracking(); + RepositoryCache track = repository.startTracking(); track.addBalance(FIRST_ACC, BigInteger.ONE); track.flush(); byte[] newRoot = repository.getRoot(); @@ -287,11 +287,11 @@ public void testSyncToPreviousRootWithFlush() { public void test17NodePreviousRootTest() { // not that it matters since things are going to be hashed, but at least // the root node should point to a node that contains references to both - final Address DOG_ACC = AionAddress.wrap("00000000000000000000000000000dog".getBytes()); - final Address DOGE_ACC = AionAddress.wrap("0000000000000000000000000000doge".getBytes()); + final Address DOG_ACC = Address.wrap("00000000000000000000000000000dog".getBytes()); + final Address DOGE_ACC = Address.wrap("0000000000000000000000000000doge".getBytes()); AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig); - IRepositoryCache track = repository.startTracking(); + RepositoryCache track = repository.startTracking(); track.addBalance(DOG_ACC, BigInteger.ONE); track.addBalance(DOGE_ACC, BigInteger.ONE); track.flush(); @@ -319,10 +319,10 @@ public void testGetSnapshotToRoot() { AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig); // make some changes to the repository - final Address account1 = AionAddress.wrap(value1); - final Address account2 = AionAddress.wrap(value2); - final Address account3 = AionAddress.wrap(value3); - IRepositoryCache track = repository.startTracking(); + final Address account1 = Address.wrap(value1); + final Address account2 = Address.wrap(value2); + final Address account3 = Address.wrap(value3); + RepositoryCache track = repository.startTracking(); track.addBalance(account1, BigInteger.ONE); track.addBalance(account2, BigInteger.TWO); track.addBalance(account3, BigInteger.TEN); @@ -330,7 +330,7 @@ public void testGetSnapshotToRoot() { repository.flush(); // get snapshot to root - IRepository snapshot = repository.getSnapshotTo(repository.getRoot()); + Repository snapshot = repository.getSnapshotTo(repository.getRoot()); // check that the same values are retrieved assertThat(repository.getBalance(account1)).isEqualTo(snapshot.getBalance(account1)); @@ -377,7 +377,7 @@ public void testGetSnapshotToRoot() { @Test public void testImportTrieNode() { AionRepositoryImpl repository = AionRepositoryImpl.createForTesting(repoConfig); - IByteArrayKeyValueDatabase db = repository.getStateDatabase(); + ByteArrayKeyValueDatabase db = repository.getStateDatabase(); byte[] nodeKey = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, diff --git a/modAionImpl/test/org/aion/zero/impl/db/BlockInfoTest.java b/modAionImpl/test/org/aion/zero/impl/db/BlockInfoTest.java index 3a91a98b14..0781331dcc 100644 --- a/modAionImpl/test/org/aion/zero/impl/db/BlockInfoTest.java +++ b/modAionImpl/test/org/aion/zero/impl/db/BlockInfoTest.java @@ -6,9 +6,9 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.HashUtil; +import org.aion.util.bytes.ByteUtil; import org.junit.Test; /** Test suite for {@link org.aion.zero.impl.db.AionBlockStore.BlockInfo} serialization */ diff --git a/modAionImpl/test/org/aion/db/DoubleDataWordTest.java b/modAionImpl/test/org/aion/zero/impl/db/DoubleDataWordTest.java similarity index 73% rename from modAionImpl/test/org/aion/db/DoubleDataWordTest.java rename to modAionImpl/test/org/aion/zero/impl/db/DoubleDataWordTest.java index 444bbd952d..576b0d14cd 100644 --- a/modAionImpl/test/org/aion/db/DoubleDataWordTest.java +++ b/modAionImpl/test/org/aion/zero/impl/db/DoubleDataWordTest.java @@ -1,56 +1,53 @@ -package org.aion.db; +package org.aion.zero.impl.db; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertNull; import java.util.Properties; import java.util.Random; -import org.aion.base.db.IContractDetails; -import org.aion.base.db.IPruneConfig; -import org.aion.base.db.IRepository; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.db.IRepositoryConfig; -import org.aion.base.type.AionAddress; +import org.aion.interfaces.db.ContractDetails; +import org.aion.interfaces.db.PruneConfig; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.interfaces.db.RepositoryConfig; +import org.aion.interfaces.db.Repository; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; import org.aion.crypto.ECKeyFac; import org.aion.db.impl.DBVendor; import org.aion.db.impl.DatabaseFactory; import org.aion.mcf.config.CfgPrune; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; -import org.aion.mcf.vm.types.DataWord; import org.aion.mcf.vm.types.DoubleDataWord; -import org.aion.vm.api.interfaces.Address; -import org.aion.zero.db.AionRepositoryCache; -import org.aion.zero.impl.db.AionRepositoryImpl; -import org.aion.zero.impl.db.ContractDetailsAion; + import org.junit.After; import org.junit.Before; import org.junit.Test; /** Tests the DoubleDataWord class, mainly that it integrates well with the db. */ public class DoubleDataWordTest { - private IRepositoryConfig repoConfig; - private IRepository repo; - private IRepositoryCache> track; + private RepositoryConfig repoConfig; + private Repository repo; + private RepositoryCache> track; private Random rand; private Address addr; @Before public void setup() { this.repoConfig = - new IRepositoryConfig() { + new RepositoryConfig() { @Override public String getDbPath() { return ""; } @Override - public IPruneConfig getPruneConfig() { + public PruneConfig getPruneConfig() { return new CfgPrune(false); } @Override - public IContractDetails contractDetailsImpl() { + public ContractDetails contractDetailsImpl() { return ContractDetailsAion.createForTesting(0, 1000000).getDetails(); } @@ -66,7 +63,7 @@ public Properties getDatabaseConfig(String db_name) { this.repo = AionRepositoryImpl.createForTesting(repoConfig); this.track = new AionRepositoryCache(repo); this.rand = new Random(); - this.addr = AionAddress.wrap(ECKeyFac.inst().create().getAddress()); + this.addr = Address.wrap(ECKeyFac.inst().create().getAddress()); } @After @@ -87,14 +84,14 @@ public void tearDown() { public void testPrefixSuffixAmbiguity() { // doubleKeyFirst has its first 16 bytes identical to singleKey // doubleKeyLast has its last 16 bytes identical to singleKey - byte[] singleKey = new byte[DataWord.BYTES]; + byte[] singleKey = new byte[DataWordImpl.BYTES]; byte[] doubleKeyFirst = new byte[DoubleDataWord.BYTES]; byte[] doubleKeyLast = new byte[DoubleDataWord.BYTES]; rand.nextBytes(singleKey); - System.arraycopy(singleKey, 0, doubleKeyFirst, 0, DataWord.BYTES); - System.arraycopy(singleKey, 0, doubleKeyLast, DataWord.BYTES, DataWord.BYTES); + System.arraycopy(singleKey, 0, doubleKeyFirst, 0, DataWordImpl.BYTES); + System.arraycopy(singleKey, 0, doubleKeyLast, DataWordImpl.BYTES, DataWordImpl.BYTES); - byte[] singleVal = new byte[DataWord.BYTES]; + byte[] singleVal = new byte[DataWordImpl.BYTES]; byte[] doubleValFirst = new byte[DoubleDataWord.BYTES]; byte[] doubleValLast = new byte[DoubleDataWord.BYTES]; singleVal[0] = (byte) 0x1; @@ -102,7 +99,7 @@ public void testPrefixSuffixAmbiguity() { doubleValLast[0] = (byte) 0x3; track.addStorageRow( - addr, new DataWord(singleKey).toWrapper(), new DataWord(singleVal).toWrapper()); + addr, new DataWordImpl(singleKey).toWrapper(), new DataWordImpl(singleVal).toWrapper()); track.addStorageRow( addr, new DoubleDataWord(doubleKeyFirst).toWrapper(), @@ -114,7 +111,7 @@ public void testPrefixSuffixAmbiguity() { track.flush(); byte[] singleRes = - track.getStorageValue(addr, new DataWord(singleKey).toWrapper()).getData(); + track.getStorageValue(addr, new DataWordImpl(singleKey).toWrapper()).getData(); byte[] doubleResFirst = track.getStorageValue(addr, new DoubleDataWord(doubleKeyFirst).toWrapper()) .getData(); @@ -133,21 +130,21 @@ public void testPrefixSuffixAmbiguity() { */ @Test public void testPrefixSuffixAmbiguity2() { - byte[] singKey = new byte[DataWord.BYTES]; + byte[] singKey = new byte[DataWordImpl.BYTES]; rand.nextBytes(singKey); - byte[] singVal = new byte[DataWord.BYTES]; + byte[] singVal = new byte[DataWordImpl.BYTES]; singVal[0] = (byte) 0xAC; track.addStorageRow( - addr, new DataWord(singKey).toWrapper(), new DataWord(singVal).toWrapper()); + addr, new DataWordImpl(singKey).toWrapper(), new DataWordImpl(singVal).toWrapper()); track.flush(); byte[] doubleKeyPrefix = new byte[DoubleDataWord.BYTES]; byte[] doubleKeySuffix = new byte[DoubleDataWord.BYTES]; - System.arraycopy(singKey, 0, doubleKeyPrefix, 0, DataWord.BYTES); - System.arraycopy(singKey, 0, doubleKeySuffix, DataWord.BYTES, DataWord.BYTES); + System.arraycopy(singKey, 0, doubleKeyPrefix, 0, DataWordImpl.BYTES); + System.arraycopy(singKey, 0, doubleKeySuffix, DataWordImpl.BYTES, DataWordImpl.BYTES); - byte[] singRes = track.getStorageValue(addr, new DataWord(singKey).toWrapper()).getData(); + byte[] singRes = track.getStorageValue(addr, new DataWordImpl(singKey).toWrapper()).getData(); assertArrayEquals(singVal, singRes); assertNull(track.getStorageValue(addr, new DoubleDataWord(doubleKeyPrefix).toWrapper())); assertNull(track.getStorageValue(addr, new DoubleDataWord(doubleKeySuffix).toWrapper())); @@ -159,9 +156,9 @@ public void testPrefixSuffixAmbiguity2() { */ @Test public void testMixOfSingleAndDoubleDataWordsInRepo() { - byte[] key16 = new byte[DataWord.BYTES]; + byte[] key16 = new byte[DataWordImpl.BYTES]; byte[] key32 = new byte[DoubleDataWord.BYTES]; - byte[] val16 = new byte[DataWord.BYTES]; + byte[] val16 = new byte[DataWordImpl.BYTES]; byte[] val32 = new byte[DoubleDataWord.BYTES]; rand.nextBytes(key16); rand.nextBytes(key32); @@ -169,14 +166,14 @@ public void testMixOfSingleAndDoubleDataWordsInRepo() { rand.nextBytes(val32); track.addStorageRow( - addr, new DataWord(key16).toWrapper(), new DoubleDataWord(val32).toWrapper()); + addr, new DataWordImpl(key16).toWrapper(), new DoubleDataWord(val32).toWrapper()); track.addStorageRow( - addr, new DoubleDataWord(key32).toWrapper(), new DataWord(val16).toWrapper()); + addr, new DoubleDataWord(key32).toWrapper(), new DataWordImpl(val16).toWrapper()); assertArrayEquals( val16, track.getStorageValue(addr, new DoubleDataWord(key32).toWrapper()).getData()); assertArrayEquals( - val32, track.getStorageValue(addr, new DataWord(key16).toWrapper()).getData()); + val32, track.getStorageValue(addr, new DataWordImpl(key16).toWrapper()).getData()); } } diff --git a/modAionImpl/test/org/aion/zero/impl/db/FlushCopiesTest.java b/modAionImpl/test/org/aion/zero/impl/db/FlushCopiesTest.java index cac69c9444..e901e86071 100644 --- a/modAionImpl/test/org/aion/zero/impl/db/FlushCopiesTest.java +++ b/modAionImpl/test/org/aion/zero/impl/db/FlushCopiesTest.java @@ -5,15 +5,14 @@ import static org.junit.Assert.assertNotSame; import java.math.BigInteger; -import org.aion.base.db.IContractDetails; -import org.aion.base.db.IRepository; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.db.ContractDetails; +import org.aion.interfaces.db.Repository; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.mcf.core.AccountState; -import org.aion.mcf.vm.types.DataWord; +import org.aion.mcf.vm.types.DataWordImpl; import org.aion.mcf.vm.types.DoubleDataWord; -import org.aion.vm.api.interfaces.Address; -import org.aion.zero.db.AionRepositoryCache; + import org.aion.zero.impl.StandaloneBlockchain; import org.apache.commons.lang3.RandomUtils; import org.junit.After; @@ -21,11 +20,11 @@ import org.junit.Test; /** - * Tests the {@link org.aion.zero.db.AionRepositoryCache#flushCopiesTo(IRepository, boolean)} + * Tests the {@link AionRepositoryCache#flushCopiesTo(Repository, boolean)} * method. */ public class FlushCopiesTest { - private IRepository repository; + private Repository repository; @Before public void setup() { @@ -45,7 +44,7 @@ public void tearDown() { public void testAccountStateObjectReference() { AionRepositoryCache repositoryChild = (AionRepositoryCache) this.repository.startTracking(); - Address account = randomAionAddress(); + Address account = randomAddress(); BigInteger nonce = BigInteger.TEN; BigInteger balance = BigInteger.valueOf(11223344); byte[] code = new byte[100]; @@ -79,7 +78,7 @@ public void testAccountStateObjectReference() { public void testContractDetailsObjectReference() { AionRepositoryCache repositoryChild = (AionRepositoryCache) this.repository.startTracking(); - Address account = randomAionAddress(); + Address account = randomAddress(); BigInteger nonce = BigInteger.TEN; BigInteger balance = BigInteger.valueOf(11223344); byte[] code = new byte[100]; @@ -88,7 +87,7 @@ public void testContractDetailsObjectReference() { // Create a new account state in the child, flush to the parent without clearing child // state. - ByteArrayWrapper key = new DataWord(5).toWrapper(); + ByteArrayWrapper key = new DataWordImpl(5).toWrapper(); ByteArrayWrapper value = new DoubleDataWord(13429765314L).toWrapper(); repositoryChild.createAccount(account); @@ -99,8 +98,8 @@ public void testContractDetailsObjectReference() { repositoryChild.flushCopiesTo(this.repository, false); // Compare object references. - IContractDetails detailsInChild = repositoryChild.getContractDetails(account); - IContractDetails detailsInParent = this.repository.getContractDetails(account); + ContractDetails detailsInChild = repositoryChild.getContractDetails(account); + ContractDetails detailsInParent = this.repository.getContractDetails(account); // These references must be different. assertNotSame(detailsInChild, detailsInParent); @@ -115,7 +114,7 @@ public void testContractDetailsObjectReference() { public void testSiblingStateModificationsAreIndependentOfOneAnother() { AionRepositoryCache firstChild = (AionRepositoryCache) this.repository.startTracking(); - Address account = randomAionAddress(); + Address account = randomAddress(); BigInteger firstNonce = BigInteger.TEN; BigInteger firstBalance = BigInteger.valueOf(11223344); byte[] code = new byte[100]; @@ -126,7 +125,7 @@ public void testSiblingStateModificationsAreIndependentOfOneAnother() { // Create a new account state in the child, flush to the parent without clearing child // state. - ByteArrayWrapper firstKey = new DataWord(5).toWrapper(); + ByteArrayWrapper firstKey = new DataWordImpl(5).toWrapper(); ByteArrayWrapper firstValue = new DoubleDataWord(13429765314L).toWrapper(); firstChild.createAccount(account); @@ -143,7 +142,7 @@ public void testSiblingStateModificationsAreIndependentOfOneAnother() { BigInteger secondNonce = firstNonce.multiply(BigInteger.TWO); ByteArrayWrapper secondKey = new DoubleDataWord(289356).toWrapper(); - ByteArrayWrapper secondValue = new DataWord(23674).toWrapper(); + ByteArrayWrapper secondValue = new DataWordImpl(23674).toWrapper(); secondChild.setNonce(account, secondNonce); secondChild.addBalance(account, firstBalance); @@ -156,9 +155,9 @@ public void testSiblingStateModificationsAreIndependentOfOneAnother() { assertArrayEquals(firstStorageHash, firstChild.getContractDetails(account).getStorageHash()); } - private Address randomAionAddress() { + private Address randomAddress() { byte[] bytes = RandomUtils.nextBytes(Address.SIZE); bytes[0] = (byte) 0xa0; - return new AionAddress(bytes); + return new Address(bytes); } } diff --git a/modMcf/test/org/aion/mcf/db/IContractDetailsTest.java b/modAionImpl/test/org/aion/zero/impl/db/IContractDetailsTest.java similarity index 83% rename from modMcf/test/org/aion/mcf/db/IContractDetailsTest.java rename to modAionImpl/test/org/aion/zero/impl/db/IContractDetailsTest.java index 3cbc653f59..f05d3050d5 100644 --- a/modMcf/test/org/aion/mcf/db/IContractDetailsTest.java +++ b/modAionImpl/test/org/aion/zero/impl/db/IContractDetailsTest.java @@ -1,4 +1,4 @@ -package org.aion.mcf.db; +package org.aion.zero.impl.db; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; @@ -9,13 +9,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.aion.base.db.IContractDetails; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.vm.IDataWord; -import org.aion.mcf.vm.types.DataWord; +import org.aion.interfaces.db.ContractDetails; +import org.aion.interfaces.vm.DataWord; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.ByteArrayWrapper; import org.aion.mcf.vm.types.DoubleDataWord; import org.aion.util.conversions.Hex; -import org.aion.zero.db.AionContractDetailsImpl; import org.apache.commons.lang3.RandomUtils; import org.junit.After; import org.junit.Before; @@ -23,7 +22,7 @@ public class IContractDetailsTest { // The two ways of instantiating the cache. - private IContractDetails cache1, cache2; + private ContractDetails cache1, cache2; @Before public void setup() { @@ -51,7 +50,7 @@ public void testGetNoSuchDoubleKey() { @Test public void testPutSingleZeroValue() { - ByteArrayWrapper key = new DataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper(); + ByteArrayWrapper key = new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper(); checkGetNonExistentPairing(cache1, key); checkGetNonExistentPairing(cache2, key); @@ -62,7 +61,7 @@ public void testPutSingleZeroValue() { @Test public void testPutDoubleZeroValue() { - ByteArrayWrapper key = new DataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper(); + ByteArrayWrapper key = new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper(); checkGetNonExistentPairing(cache1, key); checkGetNonExistentPairing(cache2, key); @@ -73,7 +72,7 @@ public void testPutDoubleZeroValue() { @Test public void testPutSingleZeroKey() { - ByteArrayWrapper value = new DataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper(); + ByteArrayWrapper value = new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper(); doPutSingleZeroKeyTest(cache1, value); doPutSingleZeroKeyTest(cache2, value); @@ -84,7 +83,7 @@ public void testPutSingleZeroKey() { @Test public void testPutDoubleZeroKey() { - ByteArrayWrapper value = new DataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper(); + ByteArrayWrapper value = new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper(); doPutDoubleZeroKeyTest(cache1, value); doPutDoubleZeroKeyTest(cache2, value); @@ -96,18 +95,18 @@ public void testPutDoubleZeroKey() { @Test public void testPutZeroKeyAndValue() { // Try single-single - cache1.delete(DataWord.ZERO.toWrapper()); - ByteArrayWrapper result = cache1.get(DataWord.ZERO.toWrapper()); + cache1.delete(DataWordImpl.ZERO.toWrapper()); + ByteArrayWrapper result = cache1.get(DataWordImpl.ZERO.toWrapper()); assertNull(result); - cache2.delete(DataWord.ZERO.toWrapper()); - assertNull(cache2.get(DataWord.ZERO.toWrapper())); + cache2.delete(DataWordImpl.ZERO.toWrapper()); + assertNull(cache2.get(DataWordImpl.ZERO.toWrapper())); // Try single-double - cache1.delete(DataWord.ZERO.toWrapper()); - result = cache1.get(DataWord.ZERO.toWrapper()); + cache1.delete(DataWordImpl.ZERO.toWrapper()); + result = cache1.get(DataWordImpl.ZERO.toWrapper()); assertNull(result); - cache2.delete(DataWord.ZERO.toWrapper()); - assertNull(cache2.get(DataWord.ZERO.toWrapper())); + cache2.delete(DataWordImpl.ZERO.toWrapper()); + assertNull(cache2.get(DataWordImpl.ZERO.toWrapper())); // Try double-single cache1.delete(DoubleDataWord.ZERO.toWrapper()); @@ -127,25 +126,25 @@ public void testPutZeroKeyAndValue() { @Test public void testPutKeyValueThenOverwriteValueWithZero() { // single-single - ByteArrayWrapper key = new DataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper(); - ByteArrayWrapper value = new DataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper(); + ByteArrayWrapper key = new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper(); + ByteArrayWrapper value = new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper(); doPutKeyValueThenOverwriteValueWithZero(cache1, key, value); doPutKeyValueThenOverwriteValueWithZero(cache2, key, value); // single-double - value = new DoubleDataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper(); + value = new DoubleDataWord(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper(); doPutKeyValueThenOverwriteValueWithZero(cache1, key, value); doPutKeyValueThenOverwriteValueWithZero(cache2, key, value); // double-single - key = new DoubleDataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper(); - value = new DataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper(); + key = new DoubleDataWord(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper(); + value = new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper(); doPutKeyValueThenOverwriteValueWithZero(cache1, key, value); doPutKeyValueThenOverwriteValueWithZero(cache2, key, value); // double-double - key = new DoubleDataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper(); - value = new DoubleDataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper(); + key = new DoubleDataWord(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper(); + value = new DoubleDataWord(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper(); doPutKeyValueThenOverwriteValueWithZero(cache1, key, value); doPutKeyValueThenOverwriteValueWithZero(cache2, key, value); } @@ -316,33 +315,33 @@ public void testCacheUpdatedAndGetWithOriginalAionContract() { // <------------------------------------------HELPERS-------------------------------------------> /** - * Tests calling get() on a DataWord key that is not in cache -- first on a zero-byte key and + * Tests calling get() on a DataWordImpl key that is not in cache -- first on a zero-byte key and * then on a random key. */ - private void doGetNoSuchSingleKeyTest(IContractDetails cache) { - checkGetNonExistentPairing(cache, DataWord.ZERO.toWrapper()); + private void doGetNoSuchSingleKeyTest(ContractDetails cache) { + checkGetNonExistentPairing(cache, DataWordImpl.ZERO.toWrapper()); checkGetNonExistentPairing( - cache, new DataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper()); + cache, new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper()); } /** * Tests calling get() on a DoubleDataWord key that is not in cache -- first on a zero-byte key * and then on a random key. */ - private void doGetNoSuchDoubleKeyTest(IContractDetails cache) { + private void doGetNoSuchDoubleKeyTest(ContractDetails cache) { checkGetNonExistentPairing(cache, DoubleDataWord.ZERO.toWrapper()); checkGetNonExistentPairing( cache, new DoubleDataWord(RandomUtils.nextBytes(DoubleDataWord.BYTES)).toWrapper()); } - /** Tests putting value into cache with a zero-byte DataWord key. */ - private void doPutSingleZeroKeyTest(IContractDetails cache, ByteArrayWrapper value) { - cache.put(DataWord.ZERO.toWrapper(), value); - assertEquals(value, cache.get(DataWord.ZERO.toWrapper())); + /** Tests putting value into cache with a zero-byte DataWordImpl key. */ + private void doPutSingleZeroKeyTest(ContractDetails cache, ByteArrayWrapper value) { + cache.put(DataWordImpl.ZERO.toWrapper(), value); + assertEquals(value, cache.get(DataWordImpl.ZERO.toWrapper())); } /** Tests putting value into cache with a zero-byte DoubleDataWord key. */ - private void doPutDoubleZeroKeyTest(IContractDetails cache, ByteArrayWrapper value) { + private void doPutDoubleZeroKeyTest(ContractDetails cache, ByteArrayWrapper value) { cache.put(DoubleDataWord.ZERO.toWrapper(), value); assertEquals(value, cache.get(DoubleDataWord.ZERO.toWrapper())); } @@ -352,9 +351,9 @@ private void doPutDoubleZeroKeyTest(IContractDetails cache, ByteArrayWrapper val * key and then calling get() on that key. */ private void doPutKeyValueThenOverwriteValueWithZero( - IContractDetails cache, ByteArrayWrapper key, ByteArrayWrapper value) { + ContractDetails cache, ByteArrayWrapper key, ByteArrayWrapper value) { - // Test DataWord. + // Test DataWordImpl. cache.put(key, value); assertEquals(value, cache.get(key)); cache.delete(key); @@ -372,7 +371,7 @@ private void doPutKeyValueThenOverwriteValueWithZero( * n'th pair was deleted. */ private void checkAllPairs( - IContractDetails cache, + ContractDetails cache, List keys, List values, int n) { @@ -395,7 +394,7 @@ private void checkAllPairs( * keys and values, where it is assumed every n'th pair was deleted. */ private void checkStorage( - IContractDetails cache, + ContractDetails cache, List keys, List values, int n) { @@ -422,7 +421,7 @@ private void checkStorage( * Iterates over every key in keys -- which are assumed to exist in cache -- and then deletes * any key-value pair in cache for every n'th key in keys. */ - private void deleteEveryNthEntry(IContractDetails cache, List keys, int n) { + private void deleteEveryNthEntry(ContractDetails cache, List keys, int n) { int count = 1; for (ByteArrayWrapper key : keys) { if (count % n == 0) { @@ -434,7 +433,7 @@ private void deleteEveryNthEntry(IContractDetails cache, List /** Puts all of the key-value pairs in keys and values into cache. */ private void massPutIntoCache( - IContractDetails cache, List keys, List values) { + ContractDetails cache, List keys, List values) { int size = keys.size(); assertEquals(size, values.size()); @@ -470,10 +469,10 @@ private List getValuesInBulk(int numValues) { return values; } - /** Returns a random DataWord if isSingleWord is true, otherwise a random DoubleDataWord. */ - private IDataWord getRandomWord(boolean isSingleWord) { + /** Returns a random DataWordImpl if isSingleWord is true, otherwise a random DoubleDataWord. */ + private DataWord getRandomWord(boolean isSingleWord) { return (isSingleWord) - ? new DataWord(RandomUtils.nextBytes(DataWord.BYTES)) + ? new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)) : new DoubleDataWord(RandomUtils.nextBytes(DoubleDataWord.BYTES)); } @@ -481,9 +480,9 @@ private IDataWord getRandomWord(boolean isSingleWord) { * Sets a key-value pair with a zero value via cache.setStorage() and ensures that null is * returned when called on that same key. */ - private void doSetZeroValueViaStorageTest(IContractDetails cache) { + private void doSetZeroValueViaStorageTest(ContractDetails cache) { Map storage = new HashMap<>(); - ByteArrayWrapper key = new DataWord(RandomUtils.nextBytes(DataWord.BYTES)).toWrapper(); + ByteArrayWrapper key = new DataWordImpl(RandomUtils.nextBytes(DataWordImpl.BYTES)).toWrapper(); storage.put(key, null); cache.setStorage(storage); checkGetNonExistentPairing(cache, key); @@ -491,7 +490,7 @@ private void doSetZeroValueViaStorageTest(IContractDetails cache) { /** Checks cache returns the expected values given its storage is storage. */ private void checkKeyValueMapping( - IContractDetails cache, Map storage) { + ContractDetails cache, Map storage) { for (ByteArrayWrapper key : storage.keySet()) { ByteArrayWrapper value = storage.get(key); @@ -528,7 +527,7 @@ private Map getKeyValueMappingInBulk( * Assumption: key has no valid value mapping in cache. This method calls cache.get(key) and * checks its result. */ - private void checkGetNonExistentPairing(IContractDetails cache, ByteArrayWrapper key) { + private void checkGetNonExistentPairing(ContractDetails cache, ByteArrayWrapper key) { try { assertNull(cache.get(key)); } catch (AssertionError e) { diff --git a/modAionImpl/test/org/aion/zero/impl/db/PendingBlockStoreTest.java b/modAionImpl/test/org/aion/zero/impl/db/PendingBlockStoreTest.java index 860c088bbd..4873c1d636 100644 --- a/modAionImpl/test/org/aion/zero/impl/db/PendingBlockStoreTest.java +++ b/modAionImpl/test/org/aion/zero/impl/db/PendingBlockStoreTest.java @@ -11,7 +11,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; import org.aion.db.impl.DBVendor; import org.aion.db.impl.DatabaseFactory.Props; import org.aion.log.AionLoggerFactory; diff --git a/modAionImpl/test/org/aion/zero/impl/sync/SyncStatsTest.java b/modAionImpl/test/org/aion/zero/impl/sync/SyncStatsTest.java index 353ae24625..635206b32b 100644 --- a/modAionImpl/test/org/aion/zero/impl/sync/SyncStatsTest.java +++ b/modAionImpl/test/org/aion/zero/impl/sync/SyncStatsTest.java @@ -1,33 +1,20 @@ package org.aion.zero.impl.sync; import static com.google.common.truth.Truth.assertThat; -import static org.aion.zero.impl.BlockchainTestUtils.generateAccounts; -import static org.aion.zero.impl.BlockchainTestUtils.generateNewBlock; -import static org.aion.zero.impl.BlockchainTestUtils.generateRandomChain; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.UUID; -import org.aion.crypto.ECKey; -import org.aion.mcf.core.ImportResult; -import org.aion.zero.impl.StandaloneBlockchain; -import org.aion.zero.impl.types.AionBlock; +import org.aion.zero.impl.sync.statistics.BlockType; +import org.aion.zero.impl.sync.statistics.RequestType; import org.apache.commons.lang3.tuple.Pair; import org.junit.BeforeClass; import org.junit.Test; public class SyncStatsTest { - private static final List accounts = generateAccounts(10); - private final StandaloneBlockchain.Bundle bundle = - new StandaloneBlockchain.Builder() - .withValidatorConfiguration("simple") - .withDefaultAccounts(accounts) - .build(); - private static final List peers = new ArrayList<>(); @BeforeClass @@ -40,50 +27,30 @@ public static void setup() { @Test public void testAvgBlocksPerSecStat() { - StandaloneBlockchain chain = bundle.bc; - generateRandomChain(chain, 1, 1, accounts, 10); - - SyncStats stats = new SyncStats(chain.getBestBlock().getNumber(), true); + SyncStats stats = new SyncStats(0L, true); // ensures correct behaviour on empty stats assertThat(stats.getAvgBlocksPerSec()).isEqualTo(0d); - for (int totalBlocks = 1; totalBlocks <= 3; totalBlocks++) { - int count = 0; - while (count < totalBlocks) { - AionBlock current = generateNewBlock(chain, chain.getBestBlock(), accounts, 10); - assertThat(chain.tryToConnect(current)).isEqualTo(ImportResult.IMPORTED_BEST); - stats.update(current.getNumber()); - count++; - } + for (int blocks = 1; blocks <= 3; blocks++) { + stats.update(blocks); try { Thread.sleep(1000); } catch (InterruptedException e) { } } - assertThat(stats.getAvgBlocksPerSec()).isGreaterThan(0d); - assertThat(stats.getAvgBlocksPerSec()).isAtMost(3d); + assertThat(stats.getAvgBlocksPerSec()).isAtMost(2d); } @Test public void testAvgBlocksPerSecStatDisabled() { - StandaloneBlockchain chain = bundle.bc; - generateRandomChain(chain, 1, 1, accounts, 10); - // disables the stats - SyncStats stats = new SyncStats(chain.getBestBlock().getNumber(), false); + SyncStats stats = new SyncStats(0L, false); - for (int totalBlocks = 1; totalBlocks <= 3; totalBlocks++) { - int count = 0; - while (count < totalBlocks) { - AionBlock current = generateNewBlock(chain, chain.getBestBlock(), accounts, 10); - assertThat(chain.tryToConnect(current)).isEqualTo(ImportResult.IMPORTED_BEST); - stats.update(current.getNumber()); - count++; - } + for (int blocks = 1; blocks <= 3; blocks++) { + stats.update(blocks); } - // ensures nothing changed assertThat(stats.getAvgBlocksPerSec()).isEqualTo(0d); } @@ -91,15 +58,14 @@ public void testAvgBlocksPerSecStatDisabled() { @Test public void testTotalRequestsToPeersStat() { List peers = new ArrayList<>(this.peers); - while (peers.size() < 4) { + while (peers.size() < 7) { peers.add(UUID.randomUUID().toString().substring(0, 6)); } - // this tests requires at least 3 peers in the list - assertThat(peers.size()).isAtLeast(4); + // this tests requires at least 6 peers in the list + assertThat(peers.size()).isAtLeast(6); - StandaloneBlockchain chain = bundle.bc; - SyncStats stats = new SyncStats(chain.getBestBlock().getNumber(), true); + SyncStats stats = new SyncStats(0L, true); // ensures correct behaviour on empty stats Map emptyReqToPeers = stats.getPercentageOfRequestsToPeers(); @@ -107,26 +73,35 @@ public void testTotalRequestsToPeersStat() { float processedRequests = 0; - String firstPeer = peers.get(0); - String secondPeer = peers.get(1); - String thirdPeer = peers.get(2); - for (String peer : peers) { // status requests stats.updateTotalRequestsToPeer(peer, RequestType.STATUS); processedRequests++; - - if (peer == firstPeer || peer == secondPeer) { - // header requests + // header requests + if (peers.subList(0, 5).contains(peer)) { stats.updateTotalRequestsToPeer(peer, RequestType.HEADERS); processedRequests++; } - // bodies requests - if (peer == firstPeer) { + if (peers.subList(0, 4).contains(peer)) { stats.updateTotalRequestsToPeer(peer, RequestType.BODIES); processedRequests++; } + // blocks requests + if (peers.subList(0, 3).contains(peer)) { + stats.updateTotalRequestsToPeer(peer, RequestType.BLOCKS); + processedRequests++; + } + // receipts requests + if (peers.subList(0, 2).contains(peer)) { + stats.updateTotalRequestsToPeer(peer, RequestType.RECEIPTS); + processedRequests++; + } + // trie_data requests + if (peer == peers.get(0)) { + stats.updateTotalRequestsToPeer(peer, RequestType.TRIE_DATA); + processedRequests++; + } } Map reqToPeers = stats.getPercentageOfRequestsToPeers(); @@ -134,20 +109,37 @@ public void testTotalRequestsToPeersStat() { // makes sure no additional peers were created assertThat(reqToPeers.size()).isEqualTo(peers.size()); + String firstPeer = peers.get(0); + String secondPeer = peers.get(1); + String thirdPeer = peers.get(2); + String fourthPeer = peers.get(3); + String fifthPeer = peers.get(4); + String sixthPeer = peers.get(5); + // by design (the updates above are not symmetrical) + reqToPeers.get(peers.get(0)); assertThat(reqToPeers.get(firstPeer)).isGreaterThan(reqToPeers.get(secondPeer)); - assertThat(reqToPeers.get(firstPeer)).isEqualTo(3 / processedRequests); + assertThat(reqToPeers.get(firstPeer)).isEqualTo(6 / processedRequests); assertThat(reqToPeers.get(secondPeer)).isGreaterThan(reqToPeers.get(thirdPeer)); - assertThat(reqToPeers.get(secondPeer)).isEqualTo(2 / processedRequests); + assertThat(reqToPeers.get(secondPeer)).isEqualTo(5 / processedRequests); + + assertThat(reqToPeers.get(thirdPeer)).isGreaterThan(reqToPeers.get(fourthPeer)); + assertThat(reqToPeers.get(thirdPeer)).isEqualTo(4 / processedRequests); + + assertThat(reqToPeers.get(fourthPeer)).isGreaterThan(reqToPeers.get(fifthPeer)); + assertThat(reqToPeers.get(fourthPeer)).isEqualTo(3 / processedRequests); + + assertThat(reqToPeers.get(fifthPeer)).isGreaterThan(reqToPeers.get(sixthPeer)); + assertThat(reqToPeers.get(fifthPeer)).isEqualTo(2 / processedRequests); - assertThat(reqToPeers.get(thirdPeer)).isEqualTo(1 / processedRequests); + assertThat(reqToPeers.get(sixthPeer)).isEqualTo(1 / processedRequests); - for (String otherPeers : peers.subList(3, peers.size())) { - assertThat(reqToPeers.get(otherPeers)).isEqualTo(reqToPeers.get(thirdPeer)); + for (String otherPeers : peers.subList(6, peers.size())) { + assertThat(reqToPeers.get(otherPeers)).isEqualTo(reqToPeers.get(sixthPeer)); } - int blocks = 3; + int blocks = 6; float lastPercentage = (float) 1; float diffThreshold = (float) 0.01; @@ -164,50 +156,52 @@ public void testTotalRequestsToPeersStat() { @Test public void testTotalRequestsToPeersStatDisabled() { List peers = new ArrayList<>(this.peers); - while (peers.size() < 4) { + while (peers.size() < 7) { peers.add(UUID.randomUUID().toString().substring(0, 6)); } // this tests requires at least 3 peers in the list - assertThat(peers.size()).isAtLeast(4); + assertThat(peers.size()).isAtLeast(6); - StandaloneBlockchain chain = bundle.bc; // disables the stats - SyncStats stats = new SyncStats(chain.getBestBlock().getNumber(), false); - - String firstPeer = peers.get(0); - String secondPeer = peers.get(1); + SyncStats stats = new SyncStats(0L, false); for (String peer : peers) { // status requests stats.updateTotalRequestsToPeer(peer, RequestType.STATUS); - - if (peer == firstPeer || peer == secondPeer) { - // header requests + // header requests + if (peers.subList(0, 5).contains(peer)) { stats.updateTotalRequestsToPeer(peer, RequestType.HEADERS); } - // bodies requests - if (peer == firstPeer) { + if (peers.subList(0, 4).contains(peer)) { stats.updateTotalRequestsToPeer(peer, RequestType.BODIES); } + // blocks requests + if (peers.subList(0, 3).contains(peer)) { + stats.updateTotalRequestsToPeer(peer, RequestType.BLOCKS); + } + // receipts requests + if (peers.subList(0, 2).contains(peer)) { + stats.updateTotalRequestsToPeer(peer, RequestType.RECEIPTS); + } + // trie_data requests + if (peer == peers.get(0)) { + stats.updateTotalRequestsToPeer(peer, RequestType.TRIE_DATA); + } } // ensures still empty - assertThat(stats.getPercentageOfRequestsToPeers().isEmpty()).isTrue(); + assertThat(stats.getPercentageOfRequestsToPeers()).isNull(); } @Test - public void testTotalBlocksByPeer() { - - StandaloneBlockchain chain = bundle.bc; - generateRandomChain(chain, 1, 1, accounts, 10); - - SyncStats stats = new SyncStats(chain.getBestBlock().getNumber(), true); + public void testReceivedBlocksByPeer() { + SyncStats stats = new SyncStats(0L, true); // ensures correct behaviour on empty stats - Map emptyTotalBlockReqByPeer = stats.getTotalBlocksByPeer(); - assertThat(emptyTotalBlockReqByPeer.isEmpty()).isTrue(); + Map emptyReceivedBlockReqByPeer = stats.getReceivedBlocksByPeer(); + assertThat(emptyReceivedBlockReqByPeer.isEmpty()).isTrue(); int peerNo = 0; int processedBlocks = 0; @@ -215,72 +209,59 @@ public void testTotalBlocksByPeer() { int blocks = totalBlocks; processedBlocks += totalBlocks; while (blocks > 0) { - AionBlock current = generateNewBlock(chain, chain.getBestBlock(), accounts, 10); - assertThat(chain.tryToConnect(current)).isEqualTo(ImportResult.IMPORTED_BEST); - stats.updatePeerTotalBlocks(peers.get(peerNo), 1); + stats.updatePeerBlocks(peers.get(peerNo), 1, BlockType.RECEIVED); blocks--; } peerNo++; } - Map totalBlockReqByPeer = stats.getTotalBlocksByPeer(); - assertThat(totalBlockReqByPeer.size()).isEqualTo(peers.size()); + Map totalBlockResByPeer = stats.getReceivedBlocksByPeer(); + assertThat(totalBlockResByPeer.size()).isEqualTo(peers.size()); int total = 3; int lastTotalBlocks = processedBlocks; for (String nodeId : peers) { // ensures desc order - assertThat(lastTotalBlocks >= totalBlockReqByPeer.get(nodeId)).isTrue(); - lastTotalBlocks = totalBlockReqByPeer.get(nodeId); - assertThat(totalBlockReqByPeer.get(nodeId)).isEqualTo(total); + assertThat(lastTotalBlocks >= totalBlockResByPeer.get(nodeId)).isTrue(); + lastTotalBlocks = totalBlockResByPeer.get(nodeId); + assertThat(totalBlockResByPeer.get(nodeId)).isEqualTo(total); + assertThat(stats.getBlocksByPeer(nodeId, BlockType.RECEIVED)).isEqualTo(total); total--; } } @Test - public void testTotalBlocksByPeerDisabled() { - - StandaloneBlockchain chain = bundle.bc; - generateRandomChain(chain, 1, 1, accounts, 10); - + public void testReceivedBlocksByPeerDisabled() { // disables the stats - SyncStats stats = new SyncStats(chain.getBestBlock().getNumber(), false); + SyncStats stats = new SyncStats(0L, false); int peerNo = 0; for (int totalBlocks = peers.size(); totalBlocks > 0; totalBlocks--) { int blocks = totalBlocks; while (blocks > 0) { - AionBlock current = generateNewBlock(chain, chain.getBestBlock(), accounts, 10); - assertThat(chain.tryToConnect(current)).isEqualTo(ImportResult.IMPORTED_BEST); - stats.updatePeerTotalBlocks(peers.get(peerNo), 1); + stats.updatePeerBlocks(peers.get(peerNo), 1, BlockType.RECEIVED); blocks--; } peerNo++; } // ensures still empty - assertThat(stats.getTotalBlocksByPeer().isEmpty()).isTrue(); + assertThat(stats.getReceivedBlocksByPeer()).isNull(); } @Test public void testImportedBlocksByPeerStats() { - StandaloneBlockchain chain = bundle.bc; - generateRandomChain(chain, 1, 1, accounts, 10); - - SyncStats stats = new SyncStats(chain.getBestBlock().getNumber(), true); + SyncStats stats = new SyncStats(0L, true); // ensures correct behaviour on empty stats - assertEquals(stats.getImportedBlocksByPeer(peers.get(0)), 0); + assertEquals(stats.getBlocksByPeer(peers.get(0), BlockType.IMPORTED), 0); int peerNo = 0; for (int totalBlocks = peers.size(); totalBlocks > 0; totalBlocks--) { int blocks = totalBlocks; while (blocks > 0) { - AionBlock current = generateNewBlock(chain, chain.getBestBlock(), accounts, 10); - ImportResult result = chain.tryToConnect(current); - assertTrue(result.isStored()); - stats.updatePeerImportedBlocks(peers.get(peerNo), 1); + stats.updatePeerBlocks(peers.get(peerNo), 1, BlockType.IMPORTED); blocks--; } peerNo++; @@ -288,28 +269,21 @@ public void testImportedBlocksByPeerStats() { int imported = 3; for (String nodeId : peers) { - assertEquals((long) imported, stats.getImportedBlocksByPeer(nodeId)); + assertEquals((long) imported, stats.getBlocksByPeer(nodeId, BlockType.IMPORTED)); imported--; } } @Test public void testImportedBlocksByPeerDisabled() { - - StandaloneBlockchain chain = bundle.bc; - generateRandomChain(chain, 1, 1, accounts, 10); - // disables the stats - SyncStats stats = new SyncStats(chain.getBestBlock().getNumber(), false); + SyncStats stats = new SyncStats(0L, false); int peerNo = 0; for (int totalBlocks = peers.size(); totalBlocks > 0; totalBlocks--) { int blocks = totalBlocks; while (blocks > 0) { - AionBlock current = generateNewBlock(chain, chain.getBestBlock(), accounts, 10); - ImportResult result = chain.tryToConnect(current); - assertTrue(result.isStored()); - stats.updatePeerImportedBlocks(peers.get(peerNo), 1); + stats.updatePeerBlocks(peers.get(peerNo), 1, BlockType.IMPORTED); blocks--; } peerNo++; @@ -317,28 +291,23 @@ public void testImportedBlocksByPeerDisabled() { // ensures still empty for (String nodeId : peers) { - assertEquals(0, stats.getImportedBlocksByPeer(nodeId)); + assertEquals(0, stats.getBlocksByPeer(nodeId, BlockType.IMPORTED)); } } @Test public void testStoredBlocksByPeerStats() { - StandaloneBlockchain chain = bundle.bc; - generateRandomChain(chain, 1, 1, accounts, 10); - SyncStats stats = new SyncStats(chain.getBestBlock().getNumber(), true); + SyncStats stats = new SyncStats(0L, true); // ensures correct behaviour on empty stats - assertEquals(stats.getStoredBlocksByPeer(peers.get(0)), 0); + assertEquals(stats.getBlocksByPeer(peers.get(0), BlockType.STORED), 0); int peerNo = 0; for (int totalBlocks = peers.size(); totalBlocks > 0; totalBlocks--) { int blocks = totalBlocks; while (blocks > 0) { - AionBlock current = generateNewBlock(chain, chain.getBestBlock(), accounts, 10); - boolean result = chain.storePendingStatusBlock(current); - assertTrue(result); - stats.updatePeerStoredBlocks(peers.get(peerNo), 1); + stats.updatePeerBlocks(peers.get(peerNo), 1, BlockType.STORED); blocks--; } peerNo++; @@ -346,7 +315,7 @@ public void testStoredBlocksByPeerStats() { int stored = 3; for (String nodeId : peers) { - assertEquals((long) stored, stats.getStoredBlocksByPeer(nodeId)); + assertEquals((long) stored, stats.getBlocksByPeer(nodeId, BlockType.STORED)); stored--; } } @@ -354,20 +323,14 @@ public void testStoredBlocksByPeerStats() { @Test public void testStoredBlocksByPeerDisabled() { - StandaloneBlockchain chain = bundle.bc; - generateRandomChain(chain, 1, 1, accounts, 10); - // disables the stats - SyncStats stats = new SyncStats(chain.getBestBlock().getNumber(), false); + SyncStats stats = new SyncStats(0L, false); int peerNo = 0; for (int totalBlocks = peers.size(); totalBlocks > 0; totalBlocks--) { int blocks = totalBlocks; while (blocks > 0) { - AionBlock current = generateNewBlock(chain, chain.getBestBlock(), accounts, 10); - boolean result = chain.storePendingStatusBlock(current); - assertTrue(result); - stats.updatePeerStoredBlocks(peers.get(peerNo), 1); + stats.updatePeerBlocks(peers.get(peerNo), 1, BlockType.STORED); blocks--; } peerNo++; @@ -375,7 +338,7 @@ public void testStoredBlocksByPeerDisabled() { // ensures still empty for (String nodeId : peers) { - assertEquals(0, stats.getStoredBlocksByPeer(nodeId)); + assertEquals(0, stats.getBlocksByPeer(nodeId, BlockType.STORED)); } } @@ -436,18 +399,26 @@ public void testResponseStatsByPeersEmpty() { assertThat(stats.dumpResponseStats()).isEmpty(); // request time is logged but no response is received - stats.updateStatusRequest("dummy", System.nanoTime()); - stats.updateHeadersRequest("dummy", System.nanoTime()); - stats.updateBodiesRequest("dummy", System.nanoTime()); + stats.updateRequestTime("dummy", System.nanoTime(), RequestType.STATUS); + stats.updateRequestTime("dummy", System.nanoTime(), RequestType.HEADERS); + stats.updateRequestTime("dummy", System.nanoTime(), RequestType.BODIES); + stats.updateRequestTime("dummy", System.nanoTime(), RequestType.BLOCKS); + stats.updateRequestTime("dummy", System.nanoTime(), RequestType.RECEIPTS); + stats.updateRequestTime("dummy", System.nanoTime(), RequestType.TRIE_DATA); + assertThat(stats.getResponseStats()).isNull(); assertThat(stats.dumpResponseStats()).isEmpty(); stats = new SyncStats(0L, true); // response time is logged but no request exists - stats.updateStatusResponse("dummy", System.nanoTime()); - stats.updateHeadersResponse("dummy", System.nanoTime()); - stats.updateBodiesResponse("dummy", System.nanoTime()); + stats.updateResponseTime("dummy", System.nanoTime(), RequestType.STATUS); + stats.updateResponseTime("dummy", System.nanoTime(), RequestType.HEADERS); + stats.updateResponseTime("dummy", System.nanoTime(), RequestType.BODIES); + stats.updateResponseTime("dummy", System.nanoTime(), RequestType.BLOCKS); + stats.updateResponseTime("dummy", System.nanoTime(), RequestType.RECEIPTS); + stats.updateResponseTime("dummy", System.nanoTime(), RequestType.TRIE_DATA); + assertThat(stats.getResponseStats()).isNull(); assertThat(stats.dumpResponseStats()).isEmpty(); } @@ -458,7 +429,7 @@ public void testResponseStatsByPeers() { long time; int entries = 3; // should be updated if more message types are added - int requestTypes = 3; + int requestTypes = 6; for (String nodeId : peers) { int count = 1; @@ -467,16 +438,28 @@ public void testResponseStatsByPeers() { time = System.nanoTime(); // status -> type of request 1 - stats.updateStatusRequest(nodeId, time); - stats.updateStatusResponse(nodeId, time + 1_000_000); + stats.updateRequestTime(nodeId, time, RequestType.STATUS); + stats.updateResponseTime(nodeId, time + 1_000_000, RequestType.STATUS); // headers -> type of request 2 - stats.updateHeadersRequest(nodeId, time); - stats.updateHeadersResponse(nodeId, time + 1_000_000); + stats.updateRequestTime(nodeId, time, RequestType.HEADERS); + stats.updateResponseTime(nodeId, time + 1_000_000, RequestType.HEADERS); // bodies -> type of request 3 - stats.updateBodiesRequest(nodeId, time); - stats.updateBodiesResponse(nodeId, time + 1_000_000); + stats.updateRequestTime(nodeId, time, RequestType.BODIES); + stats.updateResponseTime(nodeId, time + 1_000_000, RequestType.BODIES); + + // bodies -> type of request 4 + stats.updateRequestTime(nodeId, time, RequestType.BLOCKS); + stats.updateResponseTime(nodeId, time + 1_000_000, RequestType.BLOCKS); + + // bodies -> type of request 5 + stats.updateRequestTime(nodeId, time, RequestType.RECEIPTS); + stats.updateResponseTime(nodeId, time + 1_000_000, RequestType.RECEIPTS); + + // bodies -> type of request 6 + stats.updateRequestTime(nodeId, time, RequestType.TRIE_DATA); + stats.updateResponseTime(nodeId, time + 1_000_000, RequestType.TRIE_DATA); count++; } @@ -484,8 +467,8 @@ public void testResponseStatsByPeers() { Map>> responseStats = stats.getResponseStats(); for (Map.Entry>> e : responseStats.entrySet()) { - // for entries for each: «all» «status» «headers» «bodies» - assertThat(e.getValue().size()).isEqualTo(4); + // 7 entries for each: «all» «status» «headers» «bodies» «blocks» «receipts» «trie_data» + assertThat(e.getValue().size()).isEqualTo(7); if (e.getKey().equals("overall")) { for (Map.Entry> sub : e.getValue().entrySet()) { @@ -535,8 +518,8 @@ public void testResponseStatsByPeersStatusOnly() { time = System.nanoTime(); // status - stats.updateStatusRequest(nodeId, time); - stats.updateStatusResponse(nodeId, time + 1_000_000); + stats.updateRequestTime(nodeId, time, RequestType.STATUS); + stats.updateResponseTime(nodeId, time + 1_000_000, RequestType.STATUS); count++; } @@ -544,8 +527,8 @@ public void testResponseStatsByPeersStatusOnly() { Map>> responseStats = stats.getResponseStats(); for (Map.Entry>> e : responseStats.entrySet()) { - // for entries for each: «all» «status» «headers» «bodies» - assertThat(e.getValue().size()).isEqualTo(4); + // 7 entries for each: «all» «status» «headers» «bodies» «blocks» «receipts» «trie_data» + assertThat(e.getValue().size()).isEqualTo(7); if (e.getKey().equals("overall")) { for (Map.Entry> sub : e.getValue().entrySet()) { @@ -594,8 +577,8 @@ public void testResponseStatsByPeersHeadersOnly() { time = System.nanoTime(); // headers - stats.updateHeadersRequest(nodeId, time); - stats.updateHeadersResponse(nodeId, time + 1_000_000); + stats.updateRequestTime(nodeId, time, RequestType.HEADERS); + stats.updateResponseTime(nodeId, time + 1_000_000, RequestType.HEADERS); count++; } @@ -603,8 +586,8 @@ public void testResponseStatsByPeersHeadersOnly() { Map>> responseStats = stats.getResponseStats(); for (Map.Entry>> e : responseStats.entrySet()) { - // for entries for each: «all» «status» «headers» «bodies» - assertThat(e.getValue().size()).isEqualTo(4); + // 7 entries for each: «all» «status» «headers» «bodies» «blocks» «receipts» «trie_data» + assertThat(e.getValue().size()).isEqualTo(7); if (e.getKey().equals("overall")) { for (Map.Entry> sub : e.getValue().entrySet()) { @@ -653,8 +636,8 @@ public void testResponseStatsByPeersBodiesOnly() { time = System.nanoTime(); // bodies - stats.updateBodiesRequest(nodeId, time); - stats.updateBodiesResponse(nodeId, time + 1_000_000); + stats.updateRequestTime(nodeId, time, RequestType.BODIES); + stats.updateResponseTime(nodeId, time + 1_000_000, RequestType.BODIES); count++; } @@ -662,8 +645,8 @@ public void testResponseStatsByPeersBodiesOnly() { Map>> responseStats = stats.getResponseStats(); for (Map.Entry>> e : responseStats.entrySet()) { - // for entries for each: «all» «status» «headers» «bodies» - assertThat(e.getValue().size()).isEqualTo(4); + // 7 entries for each: «all» «status» «headers» «bodies» «blocks» «receipts» «trie_data» + assertThat(e.getValue().size()).isEqualTo(7); if (e.getKey().equals("overall")) { for (Map.Entry> sub : e.getValue().entrySet()) { @@ -699,6 +682,183 @@ public void testResponseStatsByPeersBodiesOnly() { // System.out.println(stats.dumpResponseStats()); } + @Test + public void testResponseStatsByPeersBlocksOnly() { + SyncStats stats = new SyncStats(0L, true); + long time; + int entries = 3; + + for (String nodeId : peers) { + int count = 1; + + while (count <= entries) { + time = System.nanoTime(); + + // blocks + stats.updateRequestTime(nodeId, time, RequestType.BLOCKS); + stats.updateResponseTime(nodeId, time + 1_000_000, RequestType.BLOCKS); + + count++; + } + } + + Map>> responseStats = stats.getResponseStats(); + for (Map.Entry>> e : responseStats.entrySet()) { + // 7 entries for each: «all» «status» «headers» «bodies» «blocks» «receipts» «trie_data» + assertThat(e.getValue().size()).isEqualTo(7); + + if (e.getKey().equals("overall")) { + for (Map.Entry> sub : e.getValue().entrySet()) { + if (sub.getKey().equals("all") || sub.getKey().equals("blocks")) { + // check average + assertThat(sub.getValue().getLeft()).isEqualTo(1_000_000d); + // check entries + assertThat(sub.getValue().getRight()).isEqualTo(peers.size() * entries); + } else { + // check average + assertThat(sub.getValue().getLeft()).isEqualTo(0d); + // check entries + assertThat(sub.getValue().getRight()).isEqualTo(0); + } + } + } else { + for (Map.Entry> sub : e.getValue().entrySet()) { + if (sub.getKey().equals("all") || sub.getKey().equals("blocks")) { + // check average + assertThat(sub.getValue().getLeft()).isEqualTo(1_000_000d); + // check entries + assertThat(sub.getValue().getRight()).isEqualTo(entries); + } else { + // check average + assertThat(sub.getValue().getLeft()).isEqualTo(0d); + // check entries + assertThat(sub.getValue().getRight()).isEqualTo(0); + } + } + } + } + + // System.out.println(stats.dumpResponseStats()); + } + + @Test + public void testResponseStatsByPeersReceiptsOnly() { + SyncStats stats = new SyncStats(0L, true); + long time; + int entries = 3; + + for (String nodeId : peers) { + int count = 1; + + while (count <= entries) { + time = System.nanoTime(); + + // blocks + stats.updateRequestTime(nodeId, time, RequestType.RECEIPTS); + stats.updateResponseTime(nodeId, time + 1_000_000, RequestType.RECEIPTS); + + count++; + } + } + + Map>> responseStats = stats.getResponseStats(); + for (Map.Entry>> e : responseStats.entrySet()) { + // 7 entries for each: «all» «status» «headers» «bodies» «blocks» «receipts» «trie_data» + assertThat(e.getValue().size()).isEqualTo(7); + + if (e.getKey().equals("overall")) { + for (Map.Entry> sub : e.getValue().entrySet()) { + if (sub.getKey().equals("all") || sub.getKey().equals("receipts")) { + // check average + assertThat(sub.getValue().getLeft()).isEqualTo(1_000_000d); + // check entries + assertThat(sub.getValue().getRight()).isEqualTo(peers.size() * entries); + } else { + // check average + assertThat(sub.getValue().getLeft()).isEqualTo(0d); + // check entries + assertThat(sub.getValue().getRight()).isEqualTo(0); + } + } + } else { + for (Map.Entry> sub : e.getValue().entrySet()) { + if (sub.getKey().equals("all") || sub.getKey().equals("receipts")) { + // check average + assertThat(sub.getValue().getLeft()).isEqualTo(1_000_000d); + // check entries + assertThat(sub.getValue().getRight()).isEqualTo(entries); + } else { + // check average + assertThat(sub.getValue().getLeft()).isEqualTo(0d); + // check entries + assertThat(sub.getValue().getRight()).isEqualTo(0); + } + } + } + } + + // System.out.println(stats.dumpResponseStats()); + } + + @Test + public void testResponseStatsByPeersTrieDataOnly() { + SyncStats stats = new SyncStats(0L, true); + long time; + int entries = 3; + + for (String nodeId : peers) { + int count = 1; + + while (count <= entries) { + time = System.nanoTime(); + + // blocks + stats.updateRequestTime(nodeId, time, RequestType.TRIE_DATA); + stats.updateResponseTime(nodeId, time + 1_000_000, RequestType.TRIE_DATA); + + count++; + } + } + + Map>> responseStats = stats.getResponseStats(); + for (Map.Entry>> e : responseStats.entrySet()) { + // 7 entries for each: «all» «status» «headers» «bodies» «blocks» «receipts» «trie_data» + assertThat(e.getValue().size()).isEqualTo(7); + + if (e.getKey().equals("overall")) { + for (Map.Entry> sub : e.getValue().entrySet()) { + if (sub.getKey().equals("all") || sub.getKey().equals("trie_data")) { + // check average + assertThat(sub.getValue().getLeft()).isEqualTo(1_000_000d); + // check entries + assertThat(sub.getValue().getRight()).isEqualTo(peers.size() * entries); + } else { + // check average + assertThat(sub.getValue().getLeft()).isEqualTo(0d); + // check entries + assertThat(sub.getValue().getRight()).isEqualTo(0); + } + } + } else { + for (Map.Entry> sub : e.getValue().entrySet()) { + if (sub.getKey().equals("all") || sub.getKey().equals("trie_data")) { + // check average + assertThat(sub.getValue().getLeft()).isEqualTo(1_000_000d); + // check entries + assertThat(sub.getValue().getRight()).isEqualTo(entries); + } else { + // check average + assertThat(sub.getValue().getLeft()).isEqualTo(0d); + // check entries + assertThat(sub.getValue().getRight()).isEqualTo(0); + } + } + } + } + + // System.out.println(stats.dumpResponseStats()); + } + @Test public void testAverageResponseTimeByPeersStatsDisabled() { // disables the stats @@ -710,16 +870,16 @@ public void testAverageResponseTimeByPeersStatsDisabled() { while (count > 0) { // status updates - stats.updateStatusRequest(nodeId, System.nanoTime()); - stats.updateStatusResponse(nodeId, System.nanoTime()); + stats.updateRequestTime(nodeId, System.nanoTime(), RequestType.STATUS); + stats.updateResponseTime(nodeId, System.nanoTime(), RequestType.STATUS); // headers updates - stats.updateHeadersRequest(nodeId, System.nanoTime()); - stats.updateHeadersResponse(nodeId, System.nanoTime()); + stats.updateRequestTime(nodeId, System.nanoTime(), RequestType.HEADERS); + stats.updateResponseTime(nodeId, System.nanoTime(), RequestType.HEADERS); // bodies updates - stats.updateBodiesRequest(nodeId, System.nanoTime()); - stats.updateBodiesResponse(nodeId, System.nanoTime()); + stats.updateRequestTime(nodeId, System.nanoTime(), RequestType.BODIES); + stats.updateResponseTime(nodeId, System.nanoTime(), RequestType.BODIES); count--; } diff --git a/modAionImpl/test/org/aion/zero/impl/sync/TaskImportBlocksTest.java b/modAionImpl/test/org/aion/zero/impl/sync/TaskImportBlocksTest.java index 686d848fb8..7f76986159 100644 --- a/modAionImpl/test/org/aion/zero/impl/sync/TaskImportBlocksTest.java +++ b/modAionImpl/test/org/aion/zero/impl/sync/TaskImportBlocksTest.java @@ -10,7 +10,6 @@ import static org.aion.p2p.P2pConstant.COEFFICIENT_NORMAL_PEERS; import static org.aion.p2p.P2pConstant.LARGE_REQUEST_SIZE; import static org.aion.p2p.P2pConstant.MAX_NORMAL_PEERS; -import static org.aion.p2p.P2pConstant.MIN_NORMAL_PEERS; import static org.aion.zero.impl.BlockchainTestUtils.generateAccounts; import static org.aion.zero.impl.BlockchainTestUtils.generateNewBlock; import static org.aion.zero.impl.BlockchainTestUtils.generateNextBlock; @@ -39,14 +38,14 @@ import java.util.stream.Collectors; import junitparams.JUnitParamsRunner; import junitparams.Parameters; -import org.aion.base.db.IContractDetails; -import org.aion.base.db.IPruneConfig; -import org.aion.base.db.IRepositoryConfig; -import org.aion.base.util.ByteArrayWrapper; import org.aion.crypto.ECKey; import org.aion.db.impl.DBVendor; import org.aion.db.impl.DatabaseFactory; +import org.aion.interfaces.db.ContractDetails; +import org.aion.interfaces.db.PruneConfig; +import org.aion.interfaces.db.RepositoryConfig; import org.aion.mcf.core.ImportResult; +import org.aion.types.ByteArrayWrapper; import org.aion.zero.impl.AionBlockchainImpl; import org.aion.zero.impl.StandaloneBlockchain; import org.aion.zero.impl.db.ContractDetailsAion; @@ -92,9 +91,7 @@ private Object parametersForTestCountStates() { parameters.add(new Object[] {0L, 200L, mode, set2}); List set3 = new ArrayList<>(set2) - .stream() - .filter(s -> s.getMode() != mode) - .collect(Collectors.toList()); + .stream().filter(s -> s.getMode() != mode).collect(Collectors.toList()); parameters.add(new Object[] {0L, -1L, mode, set3}); } @@ -231,16 +228,16 @@ public void testFilterBatch_wPruningRestrictions() { builder.withValidatorConfiguration("simple") .withDefaultAccounts(accounts) .withRepoConfig( - new IRepositoryConfig() { + new RepositoryConfig() { @Override public String getDbPath() { return ""; } @Override - public IPruneConfig getPruneConfig() { + public PruneConfig getPruneConfig() { // top pruning without archiving - return new IPruneConfig() { + return new PruneConfig() { @Override public boolean isEnabled() { return true; @@ -264,7 +261,7 @@ public int getArchiveRate() { } @Override - public IContractDetails contractDetailsImpl() { + public ContractDetails contractDetailsImpl() { return ContractDetailsAion.createForTesting(0, 1000000) .getDetails(); } @@ -395,25 +392,6 @@ private Object allModesExceptLightning() { return new Object[] {NORMAL, THUNDER, BACKWARD, FORWARD}; } - @Test - @Parameters(method = "allModesExceptLightning") - public void testAttemptLightningJump_wMinNormalPeers(Mode mode) { - // checking that the test assumptions are met - assertThat(MIN_NORMAL_PEERS).isGreaterThan(0); - - // normalStates == MIN_NORMAL_PEERS - List states = new ArrayList<>(); - addStates(states, MIN_NORMAL_PEERS, NORMAL, 100L); - - PeerState input = new PeerState(mode, 100L); - PeerState expected = new PeerState(input); - - // expecting no change in the input value - SortedSet baseSet = new TreeSet<>(); - assertThat(attemptLightningJump(-1L, input, states, baseSet, null)).isEqualTo(expected); - assertThat(baseSet.size()).isEqualTo(0); - } - @Test @Parameters(method = "allModesExceptLightning") public void testAttemptLightningJump_wManyFastStates_wMaxNormalStates(Mode mode) { diff --git a/modAionImpl/test/org/aion/zero/impl/sync/handler/RequestBlocksHandlerTest.java b/modAionImpl/test/org/aion/zero/impl/sync/handler/RequestBlocksHandlerTest.java new file mode 100644 index 0000000000..5576810129 --- /dev/null +++ b/modAionImpl/test/org/aion/zero/impl/sync/handler/RequestBlocksHandlerTest.java @@ -0,0 +1,493 @@ +package org.aion.zero.impl.sync.handler; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import org.aion.p2p.IP2pMgr; +import org.aion.p2p.Ver; +import org.aion.p2p.impl1.P2pMgr; +import org.aion.rlp.RLP; +import org.aion.util.TestResources; +import org.aion.util.conversions.Hex; +import org.aion.zero.impl.AionBlockchainImpl; +import org.aion.zero.impl.core.IAionBlockchain; +import org.aion.zero.impl.sync.Act; +import org.aion.zero.impl.sync.msg.RequestBlocks; +import org.aion.zero.impl.sync.msg.ResponseBlocks; +import org.aion.zero.impl.types.AionBlock; +import org.junit.Test; +import org.slf4j.Logger; + +/** + * Unit tests for {@link RequestBlocksHandler}. + * + * @author Alexandra Roatis + */ +public class RequestBlocksHandlerTest { + private static final int peerId = Integer.MAX_VALUE; + private static final String displayId = "abcdef"; + + private final byte isTrue = 1; + private final byte isFalse = 0; + + @Test + public void testHeader() { + Logger log = mock(Logger.class); + IAionBlockchain chain = mock(AionBlockchainImpl.class); + IP2pMgr p2p = mock(P2pMgr.class); + + RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p); + // check handler header + assertThat(handler.getHeader().getVer()).isEqualTo(Ver.V1); + assertThat(handler.getHeader().getAction()).isEqualTo(Act.REQUEST_BLOCKS); + } + + @Test + public void testReceive_nullMessage() { + Logger log = mock(Logger.class); + IAionBlockchain chain = mock(AionBlockchainImpl.class); + IP2pMgr p2p = mock(P2pMgr.class); + + RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p); + + // receive null message + handler.receive(peerId, displayId, null); + + verify(log, times(1)).debug("", displayId); + verifyZeroInteractions(chain); + verifyZeroInteractions(p2p); + } + + @Test + public void testReceive_emptyMessage() { + Logger log = mock(Logger.class); + IAionBlockchain chain = mock(AionBlockchainImpl.class); + IP2pMgr p2p = mock(P2pMgr.class); + + RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p); + + // receive empty message + handler.receive(peerId, displayId, new byte[0]); + + verify(log, times(1)).debug("", displayId); + verifyZeroInteractions(chain); + verifyZeroInteractions(p2p); + } + + @Test + public void testReceive_incorrectMessage() { + Logger log = mock(Logger.class); + when(log.isTraceEnabled()).thenReturn(false); + + IAionBlockchain chain = mock(AionBlockchainImpl.class); + IP2pMgr p2p = mock(P2pMgr.class); + + RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p); + + // receive incorrect message + byte[] incorrectEncoding = + RLP.encodeList( + RLP.encodeByte(isTrue), + RLP.encode(10L), + RLP.encodeInt(10), + RLP.encode(Byte.MAX_VALUE + 1)); + handler.receive(peerId, displayId, incorrectEncoding); + + verify(log, times(1)) + .error( + "", + incorrectEncoding.length, + displayId); + verifyZeroInteractions(chain); + verifyZeroInteractions(p2p); + } + + @Test + public void testReceive_incorrectMessage_withTrace() { + Logger log = mock(Logger.class); + when(log.isTraceEnabled()).thenReturn(true); + + IAionBlockchain chain = mock(AionBlockchainImpl.class); + IP2pMgr p2p = mock(P2pMgr.class); + + RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p); + + // receive incorrect message + byte[] incorrectEncoding = + RLP.encodeList( + RLP.encodeByte(isFalse), + RLP.encode(consecutiveBlocks.get(0).getHash()), + RLP.encodeInt(10), + RLP.encode(Byte.MAX_VALUE + 1)); + handler.receive(peerId, displayId, incorrectEncoding); + + verify(log, times(1)) + .error( + "", + incorrectEncoding.length, + displayId); + verify(log, times(1)) + .trace( + "", + Arrays.toString(incorrectEncoding), + displayId); + verifyZeroInteractions(chain); + verifyZeroInteractions(p2p); + } + + @Test + public void testReceive_correctMessage_nullValue_withHeight() { + Logger log = mock(Logger.class); + when(log.isDebugEnabled()).thenReturn(true); + + IAionBlockchain chain = mock(AionBlockchainImpl.class); + when(chain.getBlocksByRange(10L, 1L)).thenReturn(null); + + IP2pMgr p2p = mock(P2pMgr.class); + + RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p); + + // receive correct message + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isTrue), + RLP.encode(10L), + RLP.encodeInt(10), + RLP.encodeByte(isTrue)); + handler.receive(peerId, displayId, encoding); + + verify(log, times(1)) + .debug("", 10L, 10, "DESC"); + verify(chain, times(1)).getBlocksByRange(10L, 1L); + verifyZeroInteractions(p2p); + } + + @Test + public void testReceive_correctMessage_nullBlock_withHash() { + Logger log = mock(Logger.class); + when(log.isDebugEnabled()).thenReturn(true); + + byte[] hash = consecutiveBlocks.get(0).getHash(); + IAionBlockchain chain = mock(AionBlockchainImpl.class); + when(chain.getBlockByHash(hash)).thenReturn(null); + + IP2pMgr p2p = mock(P2pMgr.class); + + RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p); + + // receive correct message + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isFalse), + RLP.encode(hash), + RLP.encodeInt(10), + RLP.encodeByte(isTrue)); + handler.receive(peerId, displayId, encoding); + + verify(log, times(1)) + .debug( + "", + Hex.toHexString(hash), + 10, + "DESC"); + verify(chain, times(1)).getBlockByHash(hash); + verify(chain, times(0)).getBlocksByRange(10L, 1L); + verifyZeroInteractions(p2p); + } + + @Test + public void testReceive_correctMessage_nullValue_withHash() { + AionBlock first = consecutiveBlocks.get(0); + byte[] hash = first.getHash(); + AionBlock last = consecutiveBlocks.get(3); + + Logger log = mock(Logger.class); + when(log.isDebugEnabled()).thenReturn(true); + + IAionBlockchain chain = mock(AionBlockchainImpl.class); + when(chain.getBlockByHash(hash)).thenReturn(first); + when(chain.getBlocksByRange(first.getNumber(), last.getNumber())).thenReturn(null); + + IP2pMgr p2p = mock(P2pMgr.class); + + RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p); + + // receive correct message + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isFalse), + RLP.encode(hash), + RLP.encodeInt(4), + RLP.encodeByte(isFalse)); + handler.receive(peerId, displayId, encoding); + + verify(log, times(1)) + .debug( + "", + Hex.toHexString(hash), + 4, + "ASC"); + verify(chain, times(1)).getBlockByHash(hash); + verify(chain, times(1)).getBlocksByRange(first.getNumber(), last.getNumber()); + + ResponseBlocks expectedResponse = new ResponseBlocks(List.of(first)); + verify(p2p, times(1)).send(peerId, displayId, expectedResponse); + } + + @Test + public void testReceive_correctMessage_withException_withHeight() { + Logger log = mock(Logger.class); + when(log.isDebugEnabled()).thenReturn(true); + + IAionBlockchain chain = mock(AionBlockchainImpl.class); + Exception e = new NullPointerException(); + when(chain.getBlocksByRange(10L, 1L)).thenThrow(e); + + IP2pMgr p2p = mock(P2pMgr.class); + + RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p); + + // receive correct message + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isTrue), + RLP.encode(10L), + RLP.encodeInt(10), + RLP.encodeByte(isTrue)); + handler.receive(peerId, displayId, encoding); + + verify(log, times(1)) + .debug("", 10L, 10, "DESC"); + verify(log).error("", e); + verify(chain, times(1)).getBlocksByRange(10L, 1L); + verifyZeroInteractions(p2p); + } + + @Test + public void testReceive_correctMessage_withException_withHash() { + AionBlock first = consecutiveBlocks.get(0); + byte[] hash = first.getHash(); + AionBlock last = consecutiveBlocks.get(3); + + Logger log = mock(Logger.class); + when(log.isDebugEnabled()).thenReturn(true); + + IAionBlockchain chain = mock(AionBlockchainImpl.class); + when(chain.getBlockByHash(hash)).thenReturn(first); + Exception e = new NullPointerException(); + when(chain.getBlocksByRange(first.getNumber(), last.getNumber())).thenThrow(e); + + IP2pMgr p2p = mock(P2pMgr.class); + + RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p); + + // receive correct message + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isFalse), + RLP.encode(hash), + RLP.encodeInt(4), + RLP.encodeByte(isFalse)); + handler.receive(peerId, displayId, encoding); + + verify(log, times(1)) + .debug( + "", + Hex.toHexString(hash), + 4, + "ASC"); + verify(log).error("", e); + + verify(chain, times(1)).getBlockByHash(hash); + verify(chain, times(1)).getBlocksByRange(first.getNumber(), last.getNumber()); + + ResponseBlocks expectedResponse = new ResponseBlocks(List.of(first)); + verify(p2p, times(1)).send(peerId, displayId, expectedResponse); + } + + // returns a list of blocks in ascending order of height + List consecutiveBlocks = TestResources.consecutiveBlocks(4); + + @Test + public void testReceive_correctMessage_ascending_withHeight() { + AionBlock first = consecutiveBlocks.get(0); + AionBlock last = consecutiveBlocks.get(3); + + Logger log = mock(Logger.class); + when(log.isDebugEnabled()).thenReturn(true); + + IAionBlockchain chain = mock(AionBlockchainImpl.class); + when(chain.getBlocksByRange(first.getNumber(), last.getNumber())) + .thenReturn(consecutiveBlocks); + + IP2pMgr p2p = mock(P2pMgr.class); + + RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p); + + // receive correct message + RequestBlocks request = new RequestBlocks(first.getNumber(), 4, false); + handler.receive(peerId, displayId, request.encode()); + + verify(log, times(1)) + .debug( + "", + first.getNumber(), + 4, + "ASC"); + verify(chain, times(1)).getBlocksByRange(first.getNumber(), last.getNumber()); + + ResponseBlocks expectedResponse = new ResponseBlocks(consecutiveBlocks); + verify(p2p, times(1)).send(peerId, displayId, expectedResponse); + } + + @Test + public void testReceive_correctMessage_ascending_withHash() { + AionBlock first = consecutiveBlocks.get(0); + byte[] hash = first.getHash(); + AionBlock last = consecutiveBlocks.get(3); + + Logger log = mock(Logger.class); + when(log.isDebugEnabled()).thenReturn(true); + + IAionBlockchain chain = mock(AionBlockchainImpl.class); + when(chain.getBlockByHash(hash)).thenReturn(first); + when(chain.getBlocksByRange(first.getNumber(), last.getNumber())) + .thenReturn(consecutiveBlocks); + + IP2pMgr p2p = mock(P2pMgr.class); + + RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p); + + // receive correct message + RequestBlocks request = new RequestBlocks(hash, 4, false); + handler.receive(peerId, displayId, request.encode()); + + verify(log, times(1)) + .debug( + "", + Hex.toHexString(hash), + 4, + "ASC"); + verify(chain, times(1)).getBlockByHash(hash); + verify(chain, times(1)).getBlocksByRange(first.getNumber(), last.getNumber()); + + ResponseBlocks expectedResponse = new ResponseBlocks(consecutiveBlocks); + verify(p2p, times(1)).send(peerId, displayId, expectedResponse); + } + + @Test + public void testReceive_correctMessage_descending_withHeight() { + AionBlock first = consecutiveBlocks.get(3); + AionBlock last = consecutiveBlocks.get(0); + // reverse the list order + LinkedList reverse = new LinkedList<>(); + for (AionBlock b : consecutiveBlocks) { + reverse.addFirst(b); + } + + Logger log = mock(Logger.class); + when(log.isDebugEnabled()).thenReturn(true); + + IAionBlockchain chain = mock(AionBlockchainImpl.class); + when(chain.getBlocksByRange(first.getNumber(), last.getNumber())).thenReturn(reverse); + + IP2pMgr p2p = mock(P2pMgr.class); + + RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p); + + // receive correct message + RequestBlocks request = new RequestBlocks(first.getNumber(), 4, true); + handler.receive(peerId, displayId, request.encode()); + + verify(log, times(1)) + .debug( + "", + first.getNumber(), + 4, + "DESC"); + verify(chain, times(1)).getBlocksByRange(first.getNumber(), last.getNumber()); + + ResponseBlocks expectedResponse = new ResponseBlocks(reverse); + verify(p2p, times(1)).send(peerId, displayId, expectedResponse); + } + + @Test + public void testReceive_correctMessage_descending_withHash() { + AionBlock first = consecutiveBlocks.get(3); + byte[] hash = first.getHash(); + AionBlock last = consecutiveBlocks.get(0); + // reverse the list order + LinkedList reverse = new LinkedList<>(); + for (AionBlock b : consecutiveBlocks) { + reverse.addFirst(b); + } + + Logger log = mock(Logger.class); + when(log.isDebugEnabled()).thenReturn(true); + + IAionBlockchain chain = mock(AionBlockchainImpl.class); + when(chain.getBlockByHash(hash)).thenReturn(first); + when(chain.getBlocksByRange(first.getNumber(), last.getNumber())).thenReturn(reverse); + + IP2pMgr p2p = mock(P2pMgr.class); + + RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p); + + // receive correct message + RequestBlocks request = new RequestBlocks(hash, 4, true); + handler.receive(peerId, displayId, request.encode()); + + verify(log, times(1)) + .debug( + "", + Hex.toHexString(hash), + 4, + "DESC"); + verify(chain, times(1)).getBlockByHash(hash); + verify(chain, times(1)).getBlocksByRange(first.getNumber(), last.getNumber()); + + ResponseBlocks expectedResponse = new ResponseBlocks(reverse); + verify(p2p, times(1)).send(peerId, displayId, expectedResponse); + } + + @Test + public void testReceive_correctMessage_withHashOnSideChain() { + AionBlock first = consecutiveBlocks.get(0); + byte[] hash = first.getHash(); + AionBlock last = consecutiveBlocks.get(3); + + Logger log = mock(Logger.class); + when(log.isDebugEnabled()).thenReturn(true); + + IAionBlockchain chain = mock(AionBlockchainImpl.class); + when(chain.getBlockByHash(hash)).thenReturn(first); + when(chain.getBlocksByRange(first.getNumber(), last.getNumber())).thenReturn(List.of(last)); + + IP2pMgr p2p = mock(P2pMgr.class); + + RequestBlocksHandler handler = new RequestBlocksHandler(log, chain, p2p); + + // receive correct message + RequestBlocks request = new RequestBlocks(hash, 4, false); + handler.receive(peerId, displayId, request.encode()); + + verify(log, times(1)) + .debug( + "", + Hex.toHexString(hash), + 4, + "ASC"); + verify(chain, times(1)).getBlockByHash(hash); + verify(chain, times(1)).getBlocksByRange(first.getNumber(), last.getNumber()); + + ResponseBlocks expectedResponse = new ResponseBlocks(List.of(first)); + verify(p2p, times(1)).send(peerId, displayId, expectedResponse); + } +} diff --git a/modAionImpl/test/org/aion/zero/impl/sync/handler/RequestTrieDataHandlerTest.java b/modAionImpl/test/org/aion/zero/impl/sync/handler/RequestTrieDataHandlerTest.java index e0739f5ab6..9eb77ffa53 100644 --- a/modAionImpl/test/org/aion/zero/impl/sync/handler/RequestTrieDataHandlerTest.java +++ b/modAionImpl/test/org/aion/zero/impl/sync/handler/RequestTrieDataHandlerTest.java @@ -1,5 +1,6 @@ package org.aion.zero.impl.sync.handler; +import static com.google.common.truth.Truth.assertThat; import static org.aion.p2p.V1Constants.TRIE_DATA_REQUEST_MAXIMUM_BATCH_SIZE; import static org.aion.zero.impl.sync.DatabaseType.STATE; import static org.aion.zero.impl.sync.msg.RequestTrieDataTest.nodeKey; @@ -15,10 +16,12 @@ import java.util.Arrays; import org.aion.p2p.IP2pMgr; +import org.aion.p2p.Ver; import org.aion.p2p.impl1.P2pMgr; import org.aion.rlp.RLP; import org.aion.zero.impl.AionBlockchainImpl; import org.aion.zero.impl.core.IAionBlockchain; +import org.aion.zero.impl.sync.Act; import org.aion.zero.impl.sync.msg.ResponseTrieData; import org.junit.Test; import org.slf4j.Logger; @@ -32,6 +35,18 @@ public class RequestTrieDataHandlerTest { private static final int peerId = Integer.MAX_VALUE; private static final String displayId = "abcdef"; + @Test + public void testHeader() { + Logger log = mock(Logger.class); + IAionBlockchain chain = mock(AionBlockchainImpl.class); + IP2pMgr p2p = mock(P2pMgr.class); + + RequestTrieDataHandler handler = new RequestTrieDataHandler(log, chain, p2p); + // check handler header + assertThat(handler.getHeader().getVer()).isEqualTo(Ver.V1); + assertThat(handler.getHeader().getAction()).isEqualTo(Act.REQUEST_TRIE_DATA); + } + @Test public void testReceive_nullMessage() { Logger log = mock(Logger.class); @@ -86,7 +101,7 @@ public void testReceive_incorrectMessage() { .error( "", outOfOderEncoding.length, - peerId); + displayId); verifyZeroInteractions(chain); verifyZeroInteractions(p2p); } @@ -109,11 +124,16 @@ public void testReceive_incorrectMessage_withTrace() { RLP.encodeInt(0)); handler.receive(peerId, displayId, outOfOderEncoding); + verify(log, times(1)) + .error( + "", + outOfOderEncoding.length, + displayId); verify(log, times(1)) .trace( "", Arrays.toString(outOfOderEncoding), - peerId); + displayId); verifyZeroInteractions(chain); verifyZeroInteractions(p2p); } diff --git a/modAionImpl/test/org/aion/zero/impl/sync/handler/ResponseBlocksHandlerTest.java b/modAionImpl/test/org/aion/zero/impl/sync/handler/ResponseBlocksHandlerTest.java new file mode 100644 index 0000000000..8952e6dd5a --- /dev/null +++ b/modAionImpl/test/org/aion/zero/impl/sync/handler/ResponseBlocksHandlerTest.java @@ -0,0 +1,147 @@ +package org.aion.zero.impl.sync.handler; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import org.aion.p2p.IP2pMgr; +import org.aion.p2p.Ver; +import org.aion.p2p.impl1.P2pMgr; +import org.aion.rlp.RLP; +import org.aion.util.TestResources; +import org.aion.zero.impl.sync.Act; +import org.aion.zero.impl.sync.FastSyncManager; +import org.aion.zero.impl.sync.msg.ResponseBlocks; +import org.junit.Test; +import org.slf4j.Logger; + +/** + * Unit tests for {@link ResponseBlocksHandler}. + * + * @author Alexandra Roatis + */ +public class ResponseBlocksHandlerTest { + private static final int peerId = Integer.MAX_VALUE; + private static final String displayId = "abcdef"; + + @Test + public void testHeader() { + Logger log = mock(Logger.class); + FastSyncManager fastSyncManager = mock(FastSyncManager.class); + IP2pMgr p2p = mock(P2pMgr.class); + + ResponseBlocksHandler handler = new ResponseBlocksHandler(log, fastSyncManager, p2p); + // check handler header + assertThat(handler.getHeader().getVer()).isEqualTo(Ver.V1); + assertThat(handler.getHeader().getAction()).isEqualTo(Act.RESPONSE_BLOCKS); + } + + @Test + public void testReceive_nullMessage() { + Logger log = mock(Logger.class); + FastSyncManager fastSyncManager = mock(FastSyncManager.class); + IP2pMgr p2p = mock(P2pMgr.class); + + ResponseBlocksHandler handler = new ResponseBlocksHandler(log, fastSyncManager, p2p); + + // receive null message + handler.receive(peerId, displayId, null); + + verify(p2p, times(1)).errCheck(peerId, displayId); + verify(log, times(1)).debug("", displayId); + verifyZeroInteractions(fastSyncManager); + } + + @Test + public void testReceive_emptyMessage() { + Logger log = mock(Logger.class); + FastSyncManager fastSyncManager = mock(FastSyncManager.class); + IP2pMgr p2p = mock(P2pMgr.class); + + ResponseBlocksHandler handler = new ResponseBlocksHandler(log, fastSyncManager, p2p); + + // receive empty message + handler.receive(peerId, displayId, new byte[0]); + + verify(p2p, times(1)).errCheck(peerId, displayId); + verify(log, times(1)).debug("", displayId); + verifyZeroInteractions(fastSyncManager); + } + + @Test + public void testReceive_incorrectMessage() { + Logger log = mock(Logger.class); + when(log.isTraceEnabled()).thenReturn(false); + when(log.isDebugEnabled()).thenReturn(true); + + FastSyncManager fastSyncManager = mock(FastSyncManager.class); + IP2pMgr p2p = mock(P2pMgr.class); + + ResponseBlocksHandler handler = new ResponseBlocksHandler(log, fastSyncManager, p2p); + + // receive incorrect message + byte[] incorrectEncoding = RLP.encodeInt(1); + handler.receive(peerId, displayId, incorrectEncoding); + + verify(p2p, times(1)).errCheck(peerId, displayId); + verify(log, times(1)) + .error( + "", + incorrectEncoding.length, + displayId); + verifyZeroInteractions(fastSyncManager); + } + + @Test + public void testReceive_incorrectMessage_withTrace() { + Logger log = mock(Logger.class); + when(log.isTraceEnabled()).thenReturn(true); + + FastSyncManager fastSyncManager = mock(FastSyncManager.class); + IP2pMgr p2p = mock(P2pMgr.class); + + ResponseBlocksHandler handler = new ResponseBlocksHandler(log, fastSyncManager, p2p); + + // receive incorrect message + byte[] incorrectEncoding = RLP.encodeInt(1); + handler.receive(peerId, displayId, incorrectEncoding); + + verify(p2p, times(1)).errCheck(peerId, displayId); + verify(log, times(1)) + .error( + "", + incorrectEncoding.length, + displayId); + verify(log, times(1)) + .trace( + "", + Arrays.toString(incorrectEncoding), + displayId); + verifyZeroInteractions(fastSyncManager); + } + + @Test + public void testReceive_correctMessage() { + Logger log = mock(Logger.class); + when(log.isDebugEnabled()).thenReturn(true); + + FastSyncManager fastSyncManager = mock(FastSyncManager.class); + IP2pMgr p2p = mock(P2pMgr.class); + + ResponseBlocksHandler handler = new ResponseBlocksHandler(log, fastSyncManager, p2p); + + // receive correct message + byte[] encoding = RLP.encodeList(TestResources.consecutiveBlocks(1).get(0).getEncoded()); + handler.receive(peerId, displayId, encoding); + + ResponseBlocks response = ResponseBlocks.decode(encoding); + + verify(log, times(1)).debug("", response, displayId); + verify(fastSyncManager, times(1)).validateAndAddBlocks(peerId, displayId, response); + verifyZeroInteractions(p2p); + } +} diff --git a/modAionImpl/test/org/aion/zero/impl/sync/handler/ResponseTrieDataHandlerTest.java b/modAionImpl/test/org/aion/zero/impl/sync/handler/ResponseTrieDataHandlerTest.java index 44ba4133f2..8d16e62561 100644 --- a/modAionImpl/test/org/aion/zero/impl/sync/handler/ResponseTrieDataHandlerTest.java +++ b/modAionImpl/test/org/aion/zero/impl/sync/handler/ResponseTrieDataHandlerTest.java @@ -14,7 +14,9 @@ import java.util.Arrays; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; +import org.aion.p2p.Ver; import org.aion.rlp.RLP; +import org.aion.zero.impl.sync.Act; import org.aion.zero.impl.sync.TrieNodeWrapper; import org.aion.zero.impl.sync.msg.ResponseTrieData; import org.junit.Test; @@ -29,6 +31,17 @@ public class ResponseTrieDataHandlerTest { private static final int peerId = Integer.MAX_VALUE; private static final String displayId = "abcdef"; + @Test + public void testHeader() { + Logger log = mock(Logger.class); + BlockingQueue receivedQueue = mock(LinkedBlockingQueue.class); + + ResponseTrieDataHandler handler = new ResponseTrieDataHandler(log, receivedQueue); + // check handler header + assertThat(handler.getHeader().getVer()).isEqualTo(Ver.V1); + assertThat(handler.getHeader().getAction()).isEqualTo(Act.RESPONSE_TRIE_DATA); + } + @Test public void testReceive_nullMessage() { Logger log = mock(Logger.class); @@ -84,7 +97,7 @@ public void testReceive_incorrectMessage() { .error( "", outOfOderEncoding.length, - peerId); + displayId); verifyZeroInteractions(receivedQueue); } @@ -115,7 +128,12 @@ public void testReceive_incorrectMessage_withTrace() { .trace( "", Arrays.toString(outOfOderEncoding), - peerId); + displayId); + verify(log, times(1)) + .error( + "", + outOfOderEncoding.length, + displayId); verifyZeroInteractions(receivedQueue); } diff --git a/modAionImpl/test/org/aion/zero/impl/sync/msg/RequestBlocksTest.java b/modAionImpl/test/org/aion/zero/impl/sync/msg/RequestBlocksTest.java new file mode 100644 index 0000000000..322d56eb03 --- /dev/null +++ b/modAionImpl/test/org/aion/zero/impl/sync/msg/RequestBlocksTest.java @@ -0,0 +1,582 @@ +package org.aion.zero.impl.sync.msg; + +import static com.google.common.truth.Truth.assertThat; +import static org.aion.p2p.V1Constants.HASH_SIZE; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; +import org.aion.p2p.Ver; +import org.aion.rlp.RLP; +import org.aion.zero.impl.sync.Act; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Unit tests for {@link RequestBlocks} messages. + * + * @author Alexandra Roatis + */ +@RunWith(JUnitParamsRunner.class) +public class RequestBlocksTest { + + private static final byte[] hash = + new byte[] { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32 + }; + private static final byte[] altHash = + new byte[] { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31 + }; + private static final byte[] zeroHash = new byte[HASH_SIZE]; + private static final byte[] smallHash = + new byte[] { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31 + }; + private static final byte[] largeHash = + new byte[] { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33 + }; + private final byte[] emptyByteArray = new byte[] {}; + + private final byte isTrue = 1; + private final byte isFalse = 0; + + @Test + public void testHeader_newObject_withHeight() { + RequestBlocks message = new RequestBlocks(10L, 10, true); + // check message header + assertThat(message.getHeader().getVer()).isEqualTo(Ver.V1); + assertThat(message.getHeader().getAction()).isEqualTo(Act.REQUEST_BLOCKS); + } + + @Test + public void testHeader_newObject_withHash() { + RequestBlocks message = new RequestBlocks(hash, 10, true); + // check message header + assertThat(message.getHeader().getVer()).isEqualTo(Ver.V1); + assertThat(message.getHeader().getAction()).isEqualTo(Act.REQUEST_BLOCKS); + } + + @Test + public void testHeader_decode_withHeight() { + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isTrue), + RLP.encode(10L), + RLP.encodeInt(10), + RLP.encodeByte(isFalse)); + RequestBlocks message = RequestBlocks.decode(encoding); + // check message header + assertThat(message).isNotNull(); + assertThat(message.getHeader().getVer()).isEqualTo(Ver.V1); + assertThat(message.getHeader().getAction()).isEqualTo(Act.REQUEST_BLOCKS); + } + + @Test + public void testHeader_decode_withHash() { + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isFalse), + RLP.encodeElement(hash), + RLP.encodeInt(10), + RLP.encodeByte(isFalse)); + RequestBlocks message = RequestBlocks.decode(encoding); + // check message header + assertThat(message).isNotNull(); + assertThat(message.getHeader().getVer()).isEqualTo(Ver.V1); + assertThat(message.getHeader().getAction()).isEqualTo(Act.REQUEST_BLOCKS); + } + + @Test(expected = NullPointerException.class) + public void testConstructor_nullHash() { + new RequestBlocks(null, 10, true); + } + + @Test(expected = IllegalArgumentException.class) + public void testConstructor_smallHash() { + new RequestBlocks(smallHash, 10, true); + } + + @Test(expected = IllegalArgumentException.class) + public void testConstructor_largeHash() { + new RequestBlocks(largeHash, 10, true); + } + + @Test + public void testDecode_nullMessage() { + assertThat(RequestBlocks.decode(null)).isNull(); + } + + @Test + public void testDecode_emptyMessage() { + assertThat(RequestBlocks.decode(new byte[0])).isNull(); + } + + @Test + public void testDecode_missingNumberFlag() { + byte[] encoding = + RLP.encodeList(RLP.encode(10L), RLP.encodeInt(10), RLP.encodeByte(isTrue)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + + encoding = + RLP.encodeList(RLP.encodeElement(hash), RLP.encodeInt(10), RLP.encodeByte(isTrue)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + } + + @Test + public void testDecode_missingStart() { + byte[] encoding = + RLP.encodeList(RLP.encodeByte(isTrue), RLP.encodeInt(10), RLP.encodeByte(isTrue)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + + encoding = + RLP.encodeList(RLP.encodeByte(isFalse), RLP.encodeInt(10), RLP.encodeByte(isTrue)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + } + + @Test + public void testDecode_missingCount() { + byte[] encoding = + RLP.encodeList(RLP.encodeByte(isTrue), RLP.encode(10L), RLP.encodeByte(isFalse)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + + encoding = + RLP.encodeList( + RLP.encodeByte(isFalse), RLP.encodeElement(hash), RLP.encodeByte(isFalse)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + } + + @Test + public void testDecode_missingOrder() { + byte[] encoding = + RLP.encodeList(RLP.encodeByte(isTrue), RLP.encode(10L), RLP.encodeInt(10)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + + encoding = + RLP.encodeList(RLP.encodeByte(isFalse), RLP.encodeElement(hash), RLP.encodeInt(10)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + } + + @Test + public void testDecode_additionalValue() { + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isTrue), + RLP.encode(10L), + RLP.encodeInt(10), + RLP.encodeByte(isTrue), + RLP.encodeInt(10)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + } + + @Test + public void testDecode_incorrectNumberFlag() { + // flag = 2 + byte[] encoding = + RLP.encodeList( + RLP.encodeByte((byte) 2), + RLP.encode(10L), + RLP.encodeInt(10), + RLP.encodeByte(isFalse)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + + // flag = -1 + encoding = + RLP.encodeList( + RLP.encodeByte((byte) -1), + RLP.encodeElement(hash), + RLP.encodeInt(10), + RLP.encodeByte(isTrue)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + } + + @Test + public void testDecode_incorrectStartHeight() { + // conversion to negative value + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isTrue), + RLP.encode(BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE)), + RLP.encodeInt(10), + RLP.encodeByte(isFalse)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + + // 0 is outside the allowed range + encoding = RLP.encodeList(RLP.encode(0L), RLP.encodeInt(10), RLP.encodeByte(isTrue)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + } + + @Test + public void testDecode_smallStartHash() { + // conversion to negative value + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isFalse), + RLP.encodeElement(smallHash), + RLP.encodeInt(10), + RLP.encodeByte(isFalse)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + + // 0 is outside the allowed range + encoding = RLP.encodeList(RLP.encode(0L), RLP.encodeInt(10), RLP.encodeByte(isTrue)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + } + + @Test + public void testDecode_largeStartHash() { + // conversion to negative value + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isFalse), + RLP.encodeElement(largeHash), + RLP.encodeInt(10), + RLP.encodeByte(isFalse)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + + // 0 is outside the allowed range + encoding = RLP.encodeList(RLP.encode(0L), RLP.encodeInt(10), RLP.encodeByte(isTrue)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + } + + @Test + public void testDecode_incorrectFlag() { + // most of these interpretations can't really be prevented + // cause the hash/height can be interpreted as a height/hash + // these tests are for cases where we can validate the incorrect conversions + + // flag says hash but height (with encoding < 32 bytes) is given + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isFalse), + RLP.encode(10L), + RLP.encode(10), + RLP.encodeByte(isTrue)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + + // flag says height but hash (with decoding outside long values) is given + byte[] largeLongHash = + new byte[] { + 0, -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 + }; + encoding = + RLP.encodeList( + RLP.encodeByte(isTrue), + RLP.encodeElement(largeLongHash), + RLP.encodeInt(10), + RLP.encodeByte(isTrue)); + + assertThat(RequestBlocks.decode(encoding)).isNull(); + } + + @Test + public void testDecode_incorrectCount() { + // using height + // conversion to negative value + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isTrue), + RLP.encode(10L), + RLP.encode(1L + Integer.MAX_VALUE), + RLP.encodeByte(isTrue)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + + // 0 is outside the allowed range + encoding = + RLP.encodeList( + RLP.encodeByte(isTrue), + RLP.encode(10L), + RLP.encodeInt(0), + RLP.encodeByte(isTrue)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + + // using hash + // conversion to negative value + encoding = + RLP.encodeList( + RLP.encodeByte(isFalse), + RLP.encodeElement(largeHash), + RLP.encode(1L + Integer.MAX_VALUE), + RLP.encodeByte(isTrue)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + + // 0 is outside the allowed range + encoding = + RLP.encodeList( + RLP.encodeByte(isFalse), + RLP.encodeElement(largeHash), + RLP.encodeInt(0), + RLP.encodeByte(isTrue)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + } + + @Test + public void testDecode_incorrectOrder() { + // using height + // max byte value + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isTrue), + RLP.encode(10L), + RLP.encodeInt(10), + RLP.encodeByte(Byte.MAX_VALUE)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + + // outside the allowed range + encoding = + RLP.encodeList( + RLP.encodeByte(isTrue), + RLP.encode(10L), + RLP.encodeInt(10), + RLP.encodeByte((byte) 2)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + + // conversion to negative value + encoding = + RLP.encodeList( + RLP.encodeByte(isTrue), + RLP.encode(10L), + RLP.encodeInt(10), + RLP.encode(Byte.MAX_VALUE + 1)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + + // using hash + // max byte value + encoding = + RLP.encodeList( + RLP.encodeByte(isFalse), + RLP.encodeElement(largeHash), + RLP.encodeInt(10), + RLP.encodeByte(Byte.MAX_VALUE)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + + // outside the allowed range + encoding = + RLP.encodeList( + RLP.encodeByte(isFalse), + RLP.encodeElement(largeHash), + RLP.encodeInt(10), + RLP.encodeByte((byte) 2)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + + // conversion to negative value + encoding = + RLP.encodeList( + RLP.encodeByte(isFalse), + RLP.encodeElement(largeHash), + RLP.encodeInt(10), + RLP.encode(Byte.MAX_VALUE + 1)); + assertThat(RequestBlocks.decode(encoding)).isNull(); + } + + @Test + public void testDecode_notAList() { + // conversion to negative value + byte[] encoding = RLP.encode(10L); + assertThat(RequestBlocks.decode(encoding)).isNull(); + } + + /** + * Parameters for testing: + * + *
      + *
    • {@link #testDecode_correct(byte,Object, int, byte)} + *
    • {@link #testEncode_correct(byte,Object, int, byte)} + *
    • {@link #testEncodeDecode(byte,Object, int, byte)} + *
    + */ + @SuppressWarnings("unused") + private Object correctParameters() { + List parameters = new ArrayList<>(); + + long[] startOptions = new long[] {1L, Integer.MAX_VALUE, Long.MAX_VALUE}; + int[] countOptions = new int[] {1, Byte.MAX_VALUE, Integer.MAX_VALUE}; + byte[] orderOptions = new byte[] {isTrue, isFalse}; + + for (long start : startOptions) { + for (int count : countOptions) { + for (byte order : orderOptions) { + parameters.add(new Object[] {isTrue, start, count, order}); + } + } + } + + byte[][] hashOptions = new byte[][] {hash, altHash}; + for (byte[] start : hashOptions) { + for (int count : countOptions) { + for (byte order : orderOptions) { + parameters.add(new Object[] {isFalse, start, count, order}); + } + } + } + + return parameters.toArray(); + } + + @Test + @Parameters(method = "correctParameters") + public void testDecode_correct(byte flag, Object start, int count, byte order) { + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(flag), + flag == isTrue ? RLP.encode(start) : RLP.encodeElement((byte[]) start), + RLP.encodeInt(count), + RLP.encodeByte(order)); + + RequestBlocks message = RequestBlocks.decode(encoding); + + assertThat(message).isNotNull(); + assertThat(message.isNumber()).isEqualTo(flag == isTrue); + if (flag == isTrue) { + assertThat(message.getStartHeight()).isEqualTo(start); + assertThat(message.getStartHash()).isNull(); + } else { + assertThat(message.getStartHash()).isEqualTo(start); + assertThat(message.getStartHeight()).isNull(); + } + assertThat(message.getCount()).isEqualTo(count); + assertThat(message.isDescending()).isEqualTo(order == isTrue); + } + + @Test + @Parameters(method = "correctParameters") + public void testEncode_correct(byte flag, Object start, int count, byte order) { + byte[] expected = + RLP.encodeList( + RLP.encodeByte(flag), + flag == isTrue ? RLP.encode(start) : RLP.encodeElement((byte[]) start), + RLP.encodeInt(count), + RLP.encodeByte(order)); + + RequestBlocks message; + if (flag == isTrue) { + message = new RequestBlocks((long) start, count, order == isTrue); + assertThat(message.getStartHash()).isNull(); + } else { + message = new RequestBlocks((byte[]) start, count, order == isTrue); + assertThat(message.getStartHeight()).isNull(); + } + assertThat(message.isNumber()).isEqualTo(flag == isTrue); + assertThat(message.encode()).isEqualTo(expected); + } + + @Test + @Parameters(method = "correctParameters") + public void testEncodeDecode(byte flag, Object start, int count, byte order) { + // encode + RequestBlocks message; + if (flag == isTrue) { + message = new RequestBlocks((long) start, count, order == isTrue); + assertThat(message.getStartHeight()).isEqualTo(start); + assertThat(message.getStartHash()).isNull(); + } else { + message = new RequestBlocks((byte[]) start, count, order == isTrue); + assertThat(message.getStartHash()).isEqualTo(start); + assertThat(message.getStartHeight()).isNull(); + } + + assertThat(message.isNumber()).isEqualTo(flag == isTrue); + assertThat(message.getCount()).isEqualTo(count); + assertThat(message.isDescending()).isEqualTo(order == isTrue); + + byte[] encoding = message.encode(); + + // decode + RequestBlocks decoded = RequestBlocks.decode(encoding); + + assertThat(decoded).isNotNull(); + assertThat(decoded.isNumber()).isEqualTo(flag == isTrue); + if (flag == isTrue) { + assertThat(decoded.getStartHeight()).isEqualTo(start); + assertThat(decoded.getStartHash()).isNull(); + } else { + assertThat(decoded.getStartHash()).isEqualTo(start); + assertThat(decoded.getStartHeight()).isNull(); + } + assertThat(decoded.getCount()).isEqualTo(count); + assertThat(decoded.isDescending()).isEqualTo(order == isTrue); + } + + @Test + public void testEncode_differentStartHeight() { + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isTrue), + RLP.encode(1L), + RLP.encodeInt(1), + RLP.encodeByte(isTrue)); + + RequestBlocks message = new RequestBlocks(2L, 1, true); + assertThat(message.encode()).isNotEqualTo(encoding); + } + + @Test + public void testEncode_differentStartHash() { + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isFalse), + RLP.encodeElement(hash), + RLP.encodeInt(1), + RLP.encodeByte(isTrue)); + + RequestBlocks message = new RequestBlocks(altHash, 1, true); + assertThat(message.encode()).isNotEqualTo(encoding); + } + + @Test + public void testEncode_differentCount() { + // using height + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isTrue), + RLP.encode(1L), + RLP.encodeInt(1), + RLP.encodeByte(isTrue)); + + RequestBlocks message = new RequestBlocks(1L, 2, true); + assertThat(message.encode()).isNotEqualTo(encoding); + + // using hash + encoding = + RLP.encodeList( + RLP.encodeByte(isFalse), + RLP.encodeElement(hash), + RLP.encodeInt(1), + RLP.encodeByte(isTrue)); + + message = new RequestBlocks(hash, 2, true); + assertThat(message.encode()).isNotEqualTo(encoding); + } + + @Test + public void testEncode_differentOrder() { + // using height + byte[] encoding = + RLP.encodeList( + RLP.encodeByte(isTrue), + RLP.encode(1L), + RLP.encodeInt(1), + RLP.encodeByte(isTrue)); + + RequestBlocks message = new RequestBlocks(1L, 1, false); + assertThat(message.encode()).isNotEqualTo(encoding); + + // using hash + encoding = + RLP.encodeList( + RLP.encodeByte(isFalse), + RLP.encodeElement(hash), + RLP.encodeInt(1), + RLP.encodeByte(isTrue)); + + message = new RequestBlocks(hash, 1, false); + assertThat(message.encode()).isNotEqualTo(encoding); + } +} diff --git a/modAionImpl/test/org/aion/zero/impl/sync/msg/RequestTrieDataTest.java b/modAionImpl/test/org/aion/zero/impl/sync/msg/RequestTrieDataTest.java index 13b4b6b4ff..a0247b495a 100644 --- a/modAionImpl/test/org/aion/zero/impl/sync/msg/RequestTrieDataTest.java +++ b/modAionImpl/test/org/aion/zero/impl/sync/msg/RequestTrieDataTest.java @@ -10,7 +10,9 @@ import java.util.List; import junitparams.JUnitParamsRunner; import junitparams.Parameters; +import org.aion.p2p.Ver; import org.aion.rlp.RLP; +import org.aion.zero.impl.sync.Act; import org.aion.zero.impl.sync.DatabaseType; import org.junit.Test; import org.junit.runner.RunWith; @@ -90,6 +92,38 @@ public void testConstructor_negativeLimit() { new RequestTrieData(nodeKey, STATE, -10); } + @Test(expected = IllegalArgumentException.class) + public void testConstructor_smallKey() { + new RequestTrieData(smallNodeKey, STATE, 10); + } + + @Test(expected = IllegalArgumentException.class) + public void testConstructor_largeKey() { + new RequestTrieData(largeNodeKey, STATE, 10); + } + + @Test + public void testHeader_newObject() { + RequestTrieData message = new RequestTrieData(nodeKey, STATE, 1); + // check message header + assertThat(message.getHeader().getVer()).isEqualTo(Ver.V1); + assertThat(message.getHeader().getAction()).isEqualTo(Act.REQUEST_TRIE_DATA); + } + + @Test + public void testHeader_decode() { + byte[] encoding = + RLP.encodeList( + RLP.encodeElement(nodeKey), + RLP.encodeString(STATE.toString()), + RLP.encodeInt(1)); + RequestTrieData message = RequestTrieData.decode(encoding); + // check message header + assertThat(message).isNotNull(); + assertThat(message.getHeader().getVer()).isEqualTo(Ver.V1); + assertThat(message.getHeader().getAction()).isEqualTo(Act.REQUEST_TRIE_DATA); + } + @Test public void testDecode_nullMessage() { assertThat(RequestTrieData.decode(null)).isNull(); @@ -130,6 +164,12 @@ public void testDecode_additionalValue() { assertThat(RequestTrieData.decode(encoding)).isNull(); } + @Test + public void testDecode_notAList() { + byte[] encoding = RLP.encodeElement(nodeKey); + assertThat(RequestTrieData.decode(encoding)).isNull(); + } + @Test public void testDecode_outOfOrder() { byte[] encoding = diff --git a/modAionImpl/test/org/aion/zero/impl/sync/msg/ResponseBlocksTest.java b/modAionImpl/test/org/aion/zero/impl/sync/msg/ResponseBlocksTest.java new file mode 100644 index 0000000000..d22c815813 --- /dev/null +++ b/modAionImpl/test/org/aion/zero/impl/sync/msg/ResponseBlocksTest.java @@ -0,0 +1,120 @@ +package org.aion.zero.impl.sync.msg; + +import static com.google.common.truth.Truth.assertThat; + +import java.util.Collections; +import java.util.List; +import junitparams.JUnitParamsRunner; +import org.aion.p2p.Ver; +import org.aion.rlp.RLP; +import org.aion.util.TestResources; +import org.aion.zero.impl.sync.Act; +import org.aion.zero.impl.types.AionBlock; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Unit tests for {@link ResponseBlocks} messages. + * + * @author Alexandra Roatis + */ +@RunWith(JUnitParamsRunner.class) +public class ResponseBlocksTest { + + @Test + public void testDecode_nullMessage() { + assertThat(ResponseBlocks.decode(null)).isNull(); + } + + @Test + public void testDecode_emptyMessage() { + assertThat(ResponseBlocks.decode(new byte[0])).isNull(); + } + + @Test + public void testDecode_notAList() { + byte[] encoding = RLP.encodeElement(new byte[] {1, 2, 3}); + assertThat(ResponseBlocks.decode(encoding)).isNull(); + } + + @Test + public void testDecode_notBlocks() { + byte[] encoding = RLP.encodeList(RLP.encodeElement(new byte[] {1, 2, 3})); + assertThat(ResponseBlocks.decode(encoding)).isNull(); + } + + @Test + public void testHeader_newObject() { + ResponseBlocks message = new ResponseBlocks(TestResources.consecutiveBlocks(1)); + // check message header + assertThat(message.getHeader().getVer()).isEqualTo(Ver.V1); + assertThat(message.getHeader().getAction()).isEqualTo(Act.RESPONSE_BLOCKS); + } + + @Test + public void testHeader_decode() { + byte[] encoding = RLP.encodeList(TestResources.consecutiveBlocks(1).get(0).getEncoded()); + ResponseBlocks message = ResponseBlocks.decode(encoding); + // check message header + assertThat(message).isNotNull(); + assertThat(message.getHeader().getVer()).isEqualTo(Ver.V1); + assertThat(message.getHeader().getAction()).isEqualTo(Act.RESPONSE_BLOCKS); + } + + @Test + public void testEncodeDecode_emptyList() { + List blocks = Collections.emptyList(); + + // encode + ResponseBlocks message = new ResponseBlocks(blocks); + assertThat(message.getBlocks()).isEqualTo(blocks); + byte[] encoding = message.encode(); + + // decode + ResponseBlocks decoded = ResponseBlocks.decode(encoding); + assertThat(decoded).isNotNull(); + assertThat(decoded.getBlocks()).containsExactly(blocks.toArray()); + + // equals & hashCode + assertThat(message).isEqualTo(decoded); + assertThat(message.hashCode()).isEqualTo(decoded.hashCode()); + } + + @Test + public void testEncodeDecode_singleElement() { + List blocks = TestResources.consecutiveBlocks(1); + + // encode + ResponseBlocks message = new ResponseBlocks(blocks); + assertThat(message.getBlocks()).isEqualTo(blocks); + byte[] encoding = message.encode(); + + // decode + ResponseBlocks decoded = ResponseBlocks.decode(encoding); + assertThat(decoded).isNotNull(); + assertThat(decoded.getBlocks()).containsExactly(blocks.toArray()); + + // equals & hashCode + assertThat(message).isEqualTo(decoded); + assertThat(message.hashCode()).isEqualTo(decoded.hashCode()); + } + + @Test + public void testEncodeDecode_multipleElements() { + List blocks = TestResources.consecutiveBlocks(10); + + // encode + ResponseBlocks message = new ResponseBlocks(blocks); + assertThat(message.getBlocks()).isEqualTo(blocks); + byte[] encoding = message.encode(); + + // decode + ResponseBlocks decoded = ResponseBlocks.decode(encoding); + assertThat(decoded).isNotNull(); + assertThat(decoded.getBlocks()).containsExactly(blocks.toArray()); + + // equals & hashCode + assertThat(message).isEqualTo(decoded); + assertThat(message.hashCode()).isEqualTo(decoded.hashCode()); + } +} diff --git a/modAionImpl/test/org/aion/zero/impl/sync/msg/ResponseTrieDataTest.java b/modAionImpl/test/org/aion/zero/impl/sync/msg/ResponseTrieDataTest.java index d575b1e54c..5880183a2e 100644 --- a/modAionImpl/test/org/aion/zero/impl/sync/msg/ResponseTrieDataTest.java +++ b/modAionImpl/test/org/aion/zero/impl/sync/msg/ResponseTrieDataTest.java @@ -17,8 +17,10 @@ import java.util.Map; import junitparams.JUnitParamsRunner; import junitparams.Parameters; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.p2p.Ver; import org.aion.rlp.RLP; +import org.aion.types.ByteArrayWrapper; +import org.aion.zero.impl.sync.Act; import org.aion.zero.impl.sync.DatabaseType; import org.junit.Test; import org.junit.runner.RunWith; @@ -176,6 +178,38 @@ public void testConstructor_4Parameters_nullType() { new ResponseTrieData(wrappedNodeKey, leafValue, multipleReferences, null); } + @Test + public void testHeader_newObject_3Parameters() { + ResponseTrieData message = new ResponseTrieData(wrappedAltNodeKey, leafValue, STATE); + // check message header + assertThat(message.getHeader().getVer()).isEqualTo(Ver.V1); + assertThat(message.getHeader().getAction()).isEqualTo(Act.RESPONSE_TRIE_DATA); + } + + @Test + public void testHeader_newObject_4Parameters() { + ResponseTrieData message = + new ResponseTrieData(wrappedAltNodeKey, leafValue, multipleReferences, STATE); + // check message header + assertThat(message.getHeader().getVer()).isEqualTo(Ver.V1); + assertThat(message.getHeader().getAction()).isEqualTo(Act.RESPONSE_TRIE_DATA); + } + + @Test + public void testHeader_decode() { + byte[] encoding = + RLP.encodeList( + RLP.encodeElement(nodeKey), + RLP.encodeElement(leafValue), + RLP.encodeList(encodeReferencedNodes(multipleReferences)), + RLP.encodeString(STATE.toString())); + ResponseTrieData message = ResponseTrieData.decode(encoding); + // check message header + assertThat(message).isNotNull(); + assertThat(message.getHeader().getVer()).isEqualTo(Ver.V1); + assertThat(message.getHeader().getAction()).isEqualTo(Act.RESPONSE_TRIE_DATA); + } + @Test public void testDecode_nullMessage() { assertThat(ResponseTrieData.decode(null)).isNull(); @@ -238,6 +272,12 @@ public void testDecode_additionalValue() { assertThat(ResponseTrieData.decode(encoding)).isNull(); } + @Test + public void testDecode_notAList() { + byte[] encoding = RLP.encodeElement(nodeKey); + assertThat(ResponseTrieData.decode(encoding)).isNull(); + } + @Test public void testDecode_outOfOrder() { byte[] encoding = diff --git a/modAionImpl/test/org/aion/zero/impl/types/A0BlockHeaderTest.java b/modAionImpl/test/org/aion/zero/impl/types/A0BlockHeaderTest.java index a3230a5628..e94bb98e65 100644 --- a/modAionImpl/test/org/aion/zero/impl/types/A0BlockHeaderTest.java +++ b/modAionImpl/test/org/aion/zero/impl/types/A0BlockHeaderTest.java @@ -2,9 +2,9 @@ import static com.google.common.truth.Truth.assertThat; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; +import org.aion.types.Address; import org.aion.crypto.HashUtil; +import org.aion.util.bytes.ByteUtil; import org.aion.zero.exceptions.HeaderStructureException; import org.aion.zero.types.A0BlockHeader; import org.junit.Test; @@ -36,7 +36,7 @@ public void testBlockHeaderFromSafeBuilder() throws Exception { A0BlockHeader.Builder builder = new A0BlockHeader.Builder(); // partial build - builder.withCoinbase(AionAddress.wrap(COINBASE)) + builder.withCoinbase(Address.wrap(COINBASE)) .withStateRoot(STATE_ROOT) .withTxTrieRoot(TRIE_ROOT) .withExtraData(EXTRA_DATA) @@ -73,7 +73,7 @@ public void testBlockHeaderFromUnsafeSource() throws Exception { // partial build builder.fromUnsafeSource() .withStateRoot(STATE_ROOT) - .withCoinbase(AionAddress.wrap(COINBASE)) + .withCoinbase(Address.wrap(COINBASE)) .withTxTrieRoot(TRIE_ROOT) .withExtraData(EXTRA_DATA) .withReceiptTrieRoot(RECEIPT_ROOT) @@ -109,7 +109,7 @@ public void testBlockHeaderFromRLP() throws Exception { A0BlockHeader.Builder builder = new A0BlockHeader.Builder(); builder.fromUnsafeSource() - .withCoinbase(AionAddress.wrap(COINBASE)) + .withCoinbase(Address.wrap(COINBASE)) .withTxTrieRoot(TRIE_ROOT) .withExtraData(EXTRA_DATA) .withReceiptTrieRoot(RECEIPT_ROOT) diff --git a/modAionImpl/test/org/aion/zero/impl/valid/AionPOWRuleTest.java b/modAionImpl/test/org/aion/zero/impl/valid/AionPOWRuleTest.java index b4db90afdd..b0109b1f32 100644 --- a/modAionImpl/test/org/aion/zero/impl/valid/AionPOWRuleTest.java +++ b/modAionImpl/test/org/aion/zero/impl/valid/AionPOWRuleTest.java @@ -6,8 +6,8 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.List; -import org.aion.base.util.ByteUtil; import org.aion.mcf.blockchain.valid.IValidRule; +import org.aion.util.bytes.ByteUtil; import org.aion.zero.types.A0BlockHeader; import org.junit.Before; import org.junit.Test; diff --git a/modAionImpl/test/org/aion/zero/impl/valid/EquihashSolutionRuleTest.java b/modAionImpl/test/org/aion/zero/impl/valid/EquihashSolutionRuleTest.java index 203a7ad0fb..58d1346229 100644 --- a/modAionImpl/test/org/aion/zero/impl/valid/EquihashSolutionRuleTest.java +++ b/modAionImpl/test/org/aion/zero/impl/valid/EquihashSolutionRuleTest.java @@ -1,6 +1,6 @@ // package org.aion.zero.impl.valid; // -// import org.aion.base.util.ByteArrayWrapper; +// import org.aion.types.ByteArrayWrapper; // import org.aion.equihash.EquiUtils; // import org.aion.equihash.EquiValidator; // import org.aion.equihash.Equihash; diff --git a/modAionImpl/test/org/aion/zero/impl/vm/AvmBulkTransactionTest.java b/modAionImpl/test/org/aion/zero/impl/vm/AvmBulkTransactionTest.java index b569486011..9ab68c2515 100644 --- a/modAionImpl/test/org/aion/zero/impl/vm/AvmBulkTransactionTest.java +++ b/modAionImpl/test/org/aion/zero/impl/vm/AvmBulkTransactionTest.java @@ -7,21 +7,22 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.aion.avm.api.ABIDecoder; -import org.aion.avm.api.ABIEncoder; import org.aion.avm.core.dappreading.JarBuilder; +import org.aion.avm.core.util.ABIUtil; import org.aion.avm.core.util.CodeAndArguments; -import org.aion.base.type.AionAddress; -import org.aion.base.vm.VirtualMachineSpecs; +import org.aion.avm.userlib.abi.ABIDecoder; +import org.aion.avm.userlib.abi.ABIEncoder; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.mcf.core.ImportResult; +import org.aion.mcf.valid.TransactionTypeRule; +import org.aion.types.Address; import org.aion.vm.VirtualMachineProvider; -import org.aion.vm.api.interfaces.Address; import org.aion.zero.impl.StandaloneBlockchain; -import org.aion.zero.impl.vm.contracts.Statefulness; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.impl.types.AionBlockSummary; +import org.aion.mcf.tx.TransactionTypes; +import org.aion.zero.impl.vm.contracts.Statefulness; import org.aion.zero.types.AionTransaction; import org.aion.zero.types.AionTxExecSummary; import org.apache.commons.lang3.RandomUtils; @@ -57,6 +58,7 @@ public void setup() { .build(); this.blockchain = bundle.bc; this.deployerKey = bundle.privateKeys.get(0); + TransactionTypeRule.allowAVMContractDeployment(); } @After @@ -133,9 +135,9 @@ public void sendContractCreationAndCallTransactionsInBulkTest() { // Grab the address of the newly deployed contract. Address deployedContract = - AionAddress.wrap(initialSummary.getReceipts().get(0).getTransactionOutput()); + Address.wrap(initialSummary.getReceipts().get(0).getTransactionOutput()); - int numAvmCreateTransactions = 10; + int numAvmCreateTransactions = 2; int numAvmCallTransactions = 10; int numTransactions = numAvmCreateTransactions + numAvmCallTransactions; @@ -178,7 +180,7 @@ public void sendContractCreationAndCallTransactionsInBulkTest() { // The first batch are creates, so grab the new contract addresses. if (i < numAvmCreateTransactions) { contracts.add( - AionAddress.wrap( + Address.wrap( blockSummary .getSummaries() .get(i) @@ -210,13 +212,13 @@ private AionTransaction makeAvmContractCreateTransaction(ECKey sender, BigIntege AionTransaction transaction = newTransaction( nonce, - AionAddress.wrap(sender.getAddress()), + Address.wrap(sender.getAddress()), null, BigInteger.ZERO, jar, 5_000_000, this.energyPrice, - VirtualMachineSpecs.AVM_CREATE_CODE); + TransactionTypes.AVM_CREATE_CODE); transaction.sign(this.deployerKey); return transaction; } @@ -226,26 +228,26 @@ private AionTransaction makeAvmContractCallTransaction( AionTransaction transaction = newTransaction( nonce, - AionAddress.wrap(sender.getAddress()), + Address.wrap(sender.getAddress()), contract, BigInteger.ZERO, abiEncodeMethodCall("incrementCounter"), 2_000_000, this.energyPrice, - VirtualMachineSpecs.AVM_CREATE_CODE); + TransactionTypes.AVM_CREATE_CODE); transaction.sign(this.deployerKey); return transaction; } private AionTransaction makeValueTransferTransaction( ECKey sender, ECKey beneficiary, BigInteger value, BigInteger nonce) { - Address senderAddress = AionAddress.wrap(sender.getAddress()); + Address senderAddress = Address.wrap(sender.getAddress()); AionTransaction transaction = newTransaction( nonce, senderAddress, - AionAddress.wrap(beneficiary.getAddress()), + Address.wrap(beneficiary.getAddress()), value, new byte[0], 2_000_000, @@ -257,7 +259,7 @@ private AionTransaction makeValueTransferTransaction( private int getDeployedStatefulnessCountValue( ECKey sender, BigInteger nonce, Address contract) { - Address senderAddress = AionAddress.wrap(sender.getAddress()); + Address senderAddress = Address.wrap(sender.getAddress()); AionTransaction transaction = newTransaction( @@ -268,13 +270,13 @@ private int getDeployedStatefulnessCountValue( abiEncodeMethodCall("getCount"), 2_000_000, this.energyPrice, - VirtualMachineSpecs.AVM_CREATE_CODE); + TransactionTypes.AVM_CREATE_CODE); transaction.sign(sender); AionBlockSummary summary = sendTransactionsInBulkInSingleBlock(Collections.singletonList(transaction)); return (int) - ABIDecoder.decodeOneObject(summary.getReceipts().get(0).getTransactionOutput()); + ABIUtil.decodeOneObject(summary.getReceipts().get(0).getTransactionOutput()); } private AionBlockSummary sendTransactionsInBulkInSingleBlock( @@ -314,7 +316,7 @@ private BigInteger getNonce(Address address) { } private BigInteger getNonce(ECKey address) { - return getNonce(AionAddress.wrap(address.getAddress())); + return getNonce(Address.wrap(address.getAddress())); } private BigInteger getBalance(Address address) { @@ -322,7 +324,7 @@ private BigInteger getBalance(Address address) { } private BigInteger getBalance(ECKey address) { - return getBalance(AionAddress.wrap(address.getAddress())); + return getBalance(Address.wrap(address.getAddress())); } private ECKey getRandomAccount() { @@ -339,12 +341,13 @@ private List getRandomAccounts(int num) { private byte[] getJarBytes() { return new CodeAndArguments( - JarBuilder.buildJarForMainAndClasses(Statefulness.class), new byte[0]) + JarBuilder.buildJarForMainAndClassesAndUserlib(Statefulness.class), + new byte[0]) .encodeToBytes(); } private byte[] abiEncodeMethodCall(String method, Object... arguments) { - return ABIEncoder.encodeMethodArguments(method, arguments); + return ABIUtil.encodeMethodArguments(method, arguments); } private List getRandomValues(int num, int lowerBound, int upperBound) { diff --git a/modAionImpl/test/org/aion/zero/impl/vm/AvmHelloWorldTest.java b/modAionImpl/test/org/aion/zero/impl/vm/AvmHelloWorldTest.java index cad8d2b896..a6b357648b 100644 --- a/modAionImpl/test/org/aion/zero/impl/vm/AvmHelloWorldTest.java +++ b/modAionImpl/test/org/aion/zero/impl/vm/AvmHelloWorldTest.java @@ -1,24 +1,22 @@ package org.aion.zero.impl.vm; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static com.google.common.truth.Truth.assertThat; import java.math.BigInteger; import java.util.Collections; -import org.aion.avm.api.ABIEncoder; -import org.aion.avm.core.NodeEnvironment; import org.aion.avm.core.dappreading.JarBuilder; import org.aion.avm.core.util.CodeAndArguments; -import org.aion.base.type.AionAddress; -import org.aion.base.vm.VirtualMachineSpecs; +import org.aion.avm.userlib.abi.ABIEncoder; +import org.aion.crypto.AddressSpecs; import org.aion.crypto.ECKey; import org.aion.mcf.core.ImportResult; +import org.aion.types.Address; import org.aion.vm.VirtualMachineProvider; -import org.aion.vm.api.interfaces.Address; import org.aion.zero.impl.StandaloneBlockchain; -import org.aion.zero.impl.vm.contracts.AvmHelloWorld; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.impl.types.AionBlockSummary; +import org.aion.mcf.tx.TransactionTypes; +import org.aion.zero.impl.vm.contracts.AvmHelloWorld; import org.aion.zero.types.AionTransaction; import org.aion.zero.types.AionTxReceipt; import org.apache.commons.lang3.tuple.Pair; @@ -44,11 +42,12 @@ public static void tearDownAvm() { @Before public void setup() { - StandaloneBlockchain.Bundle bundle = new StandaloneBlockchain.Builder() - .withDefaultAccounts() - .withValidatorConfiguration("simple") - .withAvmEnabled() - .build(); + StandaloneBlockchain.Bundle bundle = + new StandaloneBlockchain.Builder() + .withDefaultAccounts() + .withValidatorConfiguration("simple") + .withAvmEnabled() + .build(); this.blockchain = bundle.bc; this.deployerKey = bundle.privateKeys.get(0); } @@ -62,74 +61,107 @@ public void tearDown() { @Test public void testDeployContract() { byte[] jar = getJarBytes(); - AionTransaction transaction = newTransaction( - BigInteger.ZERO, - AionAddress.wrap(deployerKey.getAddress()), - null, - jar, - 5_000_000); + AionTransaction transaction = + newTransaction( + BigInteger.ZERO, + Address.wrap(deployerKey.getAddress()), + null, + jar, + 5_000_000); transaction.sign(this.deployerKey); - AionBlock block = this.blockchain.createNewBlock(this.blockchain.getBestBlock(), Collections.singletonList(transaction), false); - Pair connectResult = this.blockchain.tryToConnectAndFetchSummary(block); + AionBlock block = + this.blockchain.createNewBlock( + this.blockchain.getBestBlock(), + Collections.singletonList(transaction), + false); + Pair connectResult = + this.blockchain.tryToConnectAndFetchSummary(block); AionTxReceipt receipt = connectResult.getRight().getReceipts().get(0); // Check the block was imported, the contract has the Avm prefix, and deployment succeeded. - assertEquals(ImportResult.IMPORTED_BEST, connectResult.getLeft()); - assertEquals(NodeEnvironment.CONTRACT_PREFIX, receipt.getTransactionOutput()[0]); - assertTrue(receipt.isSuccessful()); + assertThat(connectResult.getLeft()).isEqualTo(ImportResult.IMPORTED_BEST); + assertThat(receipt.getTransactionOutput()[0]).isEqualTo(AddressSpecs.A0_IDENTIFIER); + assertThat(receipt.isSuccessful()).isTrue(); + + // verify that the output is indeed the contract address + assertThat(transaction.getContractAddress().toBytes()) + .isEqualTo(receipt.getTransactionOutput()); } @Test public void testDeployAndCallContract() { // Deploy the contract. byte[] jar = getJarBytes(); - AionTransaction transaction = newTransaction( - BigInteger.ZERO, - AionAddress.wrap(deployerKey.getAddress()), - null, - jar, - 5_000_000); + AionTransaction transaction = + newTransaction( + BigInteger.ZERO, + Address.wrap(deployerKey.getAddress()), + null, + jar, + 5_000_000); transaction.sign(this.deployerKey); - AionBlock block = this.blockchain.createNewBlock(this.blockchain.getBestBlock(), Collections.singletonList(transaction), false); - Pair connectResult = this.blockchain.tryToConnectAndFetchSummary(block); + AionBlock block = + this.blockchain.createNewBlock( + this.blockchain.getBestBlock(), + Collections.singletonList(transaction), + false); + Pair connectResult = + this.blockchain.tryToConnectAndFetchSummary(block); AionTxReceipt receipt = connectResult.getRight().getReceipts().get(0); // Check the block was imported, the contract has the Avm prefix, and deployment succeeded. - assertEquals(ImportResult.IMPORTED_BEST, connectResult.getLeft()); - assertEquals(NodeEnvironment.CONTRACT_PREFIX, receipt.getTransactionOutput()[0]); - assertTrue(receipt.isSuccessful()); + assertThat(connectResult.getLeft()).isEqualTo(ImportResult.IMPORTED_BEST); + assertThat(receipt.getTransactionOutput()[0]).isEqualTo(AddressSpecs.A0_IDENTIFIER); + assertThat(receipt.isSuccessful()).isTrue(); - Address contract = AionAddress.wrap(receipt.getTransactionOutput()); + Address contract = Address.wrap(receipt.getTransactionOutput()); + // verify that the output is indeed the contract address + assertThat(transaction.getContractAddress()).isEqualTo(contract); byte[] call = getCallArguments(); - transaction = newTransaction( - BigInteger.ONE, - AionAddress.wrap(deployerKey.getAddress()), - contract, - call, - 2_000_000); + transaction = + newTransaction( + BigInteger.ONE, + Address.wrap(deployerKey.getAddress()), + contract, + call, + 2_000_000); transaction.sign(this.deployerKey); - block = this.blockchain.createNewBlock(this.blockchain.getBestBlock(), Collections.singletonList(transaction), false); + block = + this.blockchain.createNewBlock( + this.blockchain.getBestBlock(), + Collections.singletonList(transaction), + false); connectResult = this.blockchain.tryToConnectAndFetchSummary(block); receipt = connectResult.getRight().getReceipts().get(0); // Check the block was imported and the transaction was successful. - assertEquals(ImportResult.IMPORTED_BEST, connectResult.getLeft()); - assertTrue(receipt.isSuccessful()); + assertThat(connectResult.getLeft()).isEqualTo(ImportResult.IMPORTED_BEST); + assertThat(receipt.isSuccessful()).isTrue(); } private byte[] getCallArguments() { - return ABIEncoder.encodeMethodArguments("sayHello"); + return ABIEncoder.encodeOneString("sayHello"); } private byte[] getJarBytes() { - return new CodeAndArguments(JarBuilder.buildJarForMainAndClasses(AvmHelloWorld.class), new byte[0]).encodeToBytes(); + return new CodeAndArguments( + JarBuilder.buildJarForMainAndClassesAndUserlib(AvmHelloWorld.class), new byte[0]) + .encodeToBytes(); } - private AionTransaction newTransaction(BigInteger nonce, Address sender, Address destination, byte[] data, long energyLimit) { - return new AionTransaction(nonce.toByteArray(), sender, destination, BigInteger.ZERO.toByteArray(), data, energyLimit, 1, VirtualMachineSpecs.AVM_CREATE_CODE); + private AionTransaction newTransaction( + BigInteger nonce, Address sender, Address destination, byte[] data, long energyLimit) { + return new AionTransaction( + nonce.toByteArray(), + sender, + destination, + BigInteger.ZERO.toByteArray(), + data, + energyLimit, + 1, + TransactionTypes.AVM_CREATE_CODE); } - } diff --git a/modAionImpl/test/org/aion/zero/impl/vm/Benchmark.java b/modAionImpl/test/org/aion/zero/impl/vm/Benchmark.java index 3028fba0b7..adc94ded8b 100644 --- a/modAionImpl/test/org/aion/zero/impl/vm/Benchmark.java +++ b/modAionImpl/test/org/aion/zero/impl/vm/Benchmark.java @@ -32,10 +32,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.Hex; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.crypto.ECKeyFac.ECKeyType; @@ -44,11 +43,13 @@ import org.aion.log.LogEnum; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; -import org.aion.mcf.vm.types.DataWord; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.conversions.Hex; import org.aion.vm.BulkExecutor; import org.aion.vm.ExecutionBatch; import org.aion.vm.PostExecutionWork; -import org.aion.vm.api.interfaces.Address; + +import org.aion.vm.exception.VMException; import org.aion.zero.impl.db.AionRepositoryImpl; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.impl.vm.contracts.ContractUtils; @@ -62,7 +63,7 @@ public class Benchmark { private static AionBlock block = createDummyBlock(); private static AionRepositoryImpl db = AionRepositoryImpl.inst(); - private static IRepositoryCache> repo = db.startTracking(); + private static RepositoryCache> repo = db.startTracking(); private static ECKey key; private static Address owner; @@ -78,23 +79,23 @@ public class Benchmark { private static Logger LOGGER = AionLoggerFactory.getLogger(LogEnum.VM.name()); - private static void prepare() throws IOException { + private static void prepare() throws IOException, VMException { long t1 = System.currentTimeMillis(); // create owner account ECKeyFac.setType(ECKeyType.ED25519); key = ECKeyFac.inst().create(); - owner = AionAddress.wrap(key.getAddress()); + owner = Address.wrap(key.getAddress()); repo.createAccount(owner); repo.addBalance(owner, BigInteger.valueOf(1_000_000_000L)); // create transaction byte[] deployer = ContractUtils.getContractDeployer("BenchmarkERC20.sol", "FixedSupplyToken"); - byte[] nonce = DataWord.ZERO.getData(); + byte[] nonce = DataWordImpl.ZERO.getData(); Address from = owner; Address to = null; - byte[] value = DataWord.ZERO.getData(); + byte[] value = DataWordImpl.ZERO.getData(); long nrg = 1_000_000L; long nrgPrice = 1L; AionTransaction tx = new AionTransaction(nonce, from, to, value, deployer, nrg, nrgPrice); @@ -131,15 +132,15 @@ private static List signTransactions(int num) { recipients.add(recipient); // transfer token to random people - byte[] nonce = new DataWord(ownerNonce + i).getData(); + byte[] nonce = new DataWordImpl(ownerNonce + i).getData(); Address from = owner; Address to = contract; - byte[] value = DataWord.ZERO.getData(); + byte[] value = DataWordImpl.ZERO.getData(); byte[] data = ByteUtil.merge( Hex.decode("fbb001d6" + "000000000000000000000000"), recipient, - DataWord.ONE.getData()); + DataWordImpl.ONE.getData()); long nrg = 1_000_000L; long nrgPrice = 1L; AionTransaction tx = new AionTransaction(nonce, from, to, value, data, nrg, nrgPrice); @@ -179,7 +180,7 @@ private static List validateTransactions(List tx return list; } - private static List executeTransactions(List txs) { + private static List executeTransactions(List txs) throws VMException { long t1 = System.currentTimeMillis(); List list = new ArrayList<>(); @@ -216,14 +217,14 @@ private static void flush() { timeFlush = t2 - t1; } - private static void verifyState(int num) { + private static void verifyState(int num) throws VMException { long ownerNonce = repo.getNonce(owner).longValue(); for (int i = 0; i < recipients.size(); i++) { - byte[] nonce = new DataWord(ownerNonce + i).getData(); + byte[] nonce = new DataWordImpl(ownerNonce + i).getData(); Address from = owner; Address to = contract; - byte[] value = DataWord.ZERO.getData(); + byte[] value = DataWordImpl.ZERO.getData(); byte[] data = ByteUtil.merge( Hex.decode("70a08231" + "000000000000000000000000"), recipients.get(i)); @@ -244,11 +245,11 @@ private static void verifyState(int num) { AionTxExecSummary summary = exec.execute().get(0); assertFalse(summary.isFailed()); - assertEquals(1, new DataWord(summary.getReceipt().getTransactionOutput()).longValue()); + assertEquals(1, new DataWordImpl(summary.getReceipt().getTransactionOutput()).longValue()); } } - public static void main(String args[]) throws IOException { + public static void main(String args[]) throws IOException, VMException { int n = 10000; prepare(); List list = signTransactions(n); @@ -271,7 +272,7 @@ private static AionBlock createDummyBlock() { byte[] parentHash = new byte[32]; byte[] coinbase = RandomUtils.nextBytes(Address.SIZE); byte[] logsBloom = new byte[0]; - byte[] difficulty = new DataWord(0x1000000L).getData(); + byte[] difficulty = new DataWordImpl(0x1000000L).getData(); long number = 1; long timestamp = System.currentTimeMillis() / 1000; byte[] extraData = new byte[0]; @@ -285,7 +286,7 @@ private static AionBlock createDummyBlock() { // TODO: set a dummy limit of 5000000 for now return new AionBlock( parentHash, - AionAddress.wrap(coinbase), + Address.wrap(coinbase), logsBloom, difficulty, number, diff --git a/modAionImpl/test/org/aion/zero/impl/vm/ContractIntegTest.java b/modAionImpl/test/org/aion/zero/impl/vm/ContractIntegTest.java index 99c4691784..c1ba61a986 100644 --- a/modAionImpl/test/org/aion/zero/impl/vm/ContractIntegTest.java +++ b/modAionImpl/test/org/aion/zero/impl/vm/ContractIntegTest.java @@ -34,22 +34,23 @@ import java.math.BigInteger; import java.util.Arrays; import java.util.Collections; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.Hex; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.fastvm.FastVmResultCode; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.aion.mcf.vm.Constants; -import org.aion.mcf.vm.types.DataWord; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.conversions.Hex; import org.aion.vm.BulkExecutor; import org.aion.vm.ExecutionBatch; import org.aion.vm.PostExecutionWork; -import org.aion.vm.api.interfaces.Address; + import org.aion.vm.api.interfaces.ResultCode; -import org.aion.zero.db.AionRepositoryCache; +import org.aion.vm.exception.VMException; +import org.aion.zero.impl.db.AionRepositoryCache; import org.aion.zero.impl.StandaloneBlockchain; import org.aion.zero.impl.StandaloneBlockchain.Builder; import org.aion.zero.impl.types.AionBlock; @@ -82,7 +83,7 @@ public void setup() { (new Builder()).withValidatorConfiguration("simple").withDefaultAccounts().build(); blockchain = bundle.bc; deployerKey = bundle.privateKeys.get(0); - deployer = new AionAddress(deployerKey.getAddress()); + deployer = new Address(deployerKey.getAddress()); deployerBalance = Builder.DEFAULT_BALANCE; deployerNonce = BigInteger.ZERO; } @@ -97,7 +98,7 @@ public void tearDown() { } @Test - public void testEmptyContract() throws IOException { + public void testEmptyContract() throws IOException, VMException { String contractName = "EmptyContract"; byte[] deployCode = getDeployCode(contractName); long nrg = 1_000_000; @@ -116,7 +117,7 @@ public void testEmptyContract() throws IOException { assertEquals(BigInteger.ZERO, blockchain.getRepository().getNonce(deployer)); AionBlock block = makeBlock(tx); - IRepositoryCache repo = blockchain.getRepository().startTracking(); + RepositoryCache repo = blockchain.getRepository().startTracking(); ExecutionBatch details = new ExecutionBatch(block, Collections.singletonList(tx)); BulkExecutor exec = @@ -140,7 +141,7 @@ public void testEmptyContract() throws IOException { } @Test - public void testContractDeployCodeIsEmpty() { + public void testContractDeployCodeIsEmpty() throws VMException { long nrg = 1_000_000; long nrgPrice = 1; BigInteger value = BigInteger.ZERO; @@ -157,7 +158,7 @@ public void testContractDeployCodeIsEmpty() { assertEquals(BigInteger.ZERO, blockchain.getRepository().getNonce(deployer)); AionBlock block = makeBlock(tx); - IRepositoryCache repo = blockchain.getRepository().startTracking(); + RepositoryCache repo = blockchain.getRepository().startTracking(); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxExecSummary summary = exec.execute().get(0); assertEquals("", summary.getReceipt().getError()); // "" == SUCCESS @@ -175,7 +176,7 @@ public void testContractDeployCodeIsEmpty() { } @Test - public void testContractDeployCodeIsNonsensical() { + public void testContractDeployCodeIsNonsensical() throws VMException { byte[] deployCode = new byte[1]; deployCode[0] = 0x1; long nrg = 1_000_000; @@ -194,7 +195,7 @@ public void testContractDeployCodeIsNonsensical() { assertEquals(BigInteger.ZERO, blockchain.getRepository().getNonce(deployer)); AionBlock block = makeBlock(tx); - IRepositoryCache repo = blockchain.getRepository().startTracking(); + RepositoryCache repo = blockchain.getRepository().startTracking(); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxExecSummary summary = exec.execute().get(0); assertEquals("OUT_OF_NRG", summary.getReceipt().getError()); @@ -213,7 +214,7 @@ public void testContractDeployCodeIsNonsensical() { } @Test - public void testTransferValueToNonPayableConstructor() throws IOException { + public void testTransferValueToNonPayableConstructor() throws IOException, VMException { String contractName = "EmptyContract"; byte[] deployCode = getDeployCode(contractName); long nrg = 1_000_000; @@ -232,7 +233,7 @@ public void testTransferValueToNonPayableConstructor() throws IOException { assertEquals(BigInteger.ZERO, blockchain.getRepository().getNonce(deployer)); AionBlock block = makeBlock(tx); - IRepositoryCache repo = blockchain.getRepository().startTracking(); + RepositoryCache repo = blockchain.getRepository().startTracking(); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxExecSummary summary = exec.execute().get(0); assertEquals("REVERT", summary.getReceipt().getError()); @@ -252,7 +253,7 @@ public void testTransferValueToNonPayableConstructor() throws IOException { } @Test - public void testTransferValueToPayableConstructor() throws IOException { + public void testTransferValueToPayableConstructor() throws IOException, VMException { String contractName = "PayableConstructor"; byte[] deployCode = getDeployCode(contractName); long nrg = 1_000_000; @@ -271,7 +272,7 @@ public void testTransferValueToPayableConstructor() throws IOException { assertEquals(BigInteger.ZERO, blockchain.getRepository().getNonce(deployer)); AionBlock block = makeBlock(tx); - IRepositoryCache repo = blockchain.getRepository().startTracking(); + RepositoryCache repo = blockchain.getRepository().startTracking(); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxExecSummary summary = exec.execute().get(0); assertEquals("", summary.getReceipt().getError()); @@ -286,7 +287,7 @@ public void testTransferValueToPayableConstructor() throws IOException { } @Test - public void testTransferValueToPayableConstructorInsufficientFunds() throws IOException { + public void testTransferValueToPayableConstructorInsufficientFunds() throws IOException, VMException { String contractName = "PayableConstructor"; byte[] deployCode = getDeployCode(contractName); long nrg = 1_000_000; @@ -305,7 +306,7 @@ public void testTransferValueToPayableConstructorInsufficientFunds() throws IOEx assertEquals(BigInteger.ZERO, blockchain.getRepository().getNonce(deployer)); AionBlock block = makeBlock(tx); - IRepositoryCache repo = blockchain.getRepository().startTracking(); + RepositoryCache repo = blockchain.getRepository().startTracking(); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxExecSummary summary = exec.execute().get(0); assertEquals("INSUFFICIENT_BALANCE", summary.getReceipt().getError()); @@ -324,7 +325,7 @@ public void testTransferValueToPayableConstructorInsufficientFunds() throws IOEx } @Test - public void testConstructorIsCalledOnCodeDeployment() throws IOException { + public void testConstructorIsCalledOnCodeDeployment() throws IOException, VMException { String contractName = "MultiFeatureContract"; byte[] deployCode = ContractUtils.getContractDeployer( @@ -338,7 +339,7 @@ public void testConstructorIsCalledOnCodeDeployment() throws IOException { new AionTransaction( nonce.toByteArray(), null, value.toByteArray(), deployCode, nrg, nrgPrice); - IRepositoryCache repo = blockchain.getRepository().startTracking(); + RepositoryCache repo = blockchain.getRepository().startTracking(); nonce = nonce.add(BigInteger.ONE); Address contract = deployContract(repo, tx, contractName, null, value, nrg, nrgPrice, nonce); @@ -368,7 +369,7 @@ public void testConstructorIsCalledOnCodeDeployment() throws IOException { } @Test - public void testCallFunction() throws IOException { + public void testCallFunction() throws IOException, VMException { String contractName = "MultiFeatureContract"; byte[] deployCode = getDeployCode(contractName); long nrg = 1_000_000; @@ -378,15 +379,15 @@ public void testCallFunction() throws IOException { AionTransaction tx = new AionTransaction( nonce.toByteArray(), null, value.toByteArray(), deployCode, nrg, nrgPrice); - IRepositoryCache repo = blockchain.getRepository().startTracking(); + RepositoryCache repo = blockchain.getRepository().startTracking(); nonce = nonce.add(BigInteger.ONE); Address contract = deployContract(repo, tx, contractName, null, value, nrg, nrgPrice, nonce); // ---------- This command will perform addition. ---------- int num = 53475374; - byte[] input = ByteUtil.merge(Hex.decode("f601704f"), new DataWord(num).getData()); - input = ByteUtil.merge(input, new DataWord(1).getData()); + byte[] input = ByteUtil.merge(Hex.decode("f601704f"), new DataWordImpl(num).getData()); + input = ByteUtil.merge(input, new DataWordImpl(1).getData()); tx = new AionTransaction( nonce.toByteArray(), @@ -408,11 +409,11 @@ public void testCallFunction() throws IOException { // Since input takes in uint8 we only want the last byte of num. Output size is well-defined // at 128 bits, or 16 bytes. int expectedResult = 1111 + (num & 0xFF); - assertEquals(expectedResult, new DataWord(summary.getResult()).intValue()); + assertEquals(expectedResult, new DataWordImpl(summary.getResult()).intValue()); // --------- This command will perform subtraction. ---------- - input = ByteUtil.merge(Hex.decode("f601704f"), new DataWord(num).getData()); - input = ByteUtil.merge(input, new DataWord(0).getData()); + input = ByteUtil.merge(Hex.decode("f601704f"), new DataWordImpl(num).getData()); + input = ByteUtil.merge(input, new DataWordImpl(0).getData()); nonce = nonce.add(BigInteger.ONE); tx = new AionTransaction( @@ -435,11 +436,11 @@ public void testCallFunction() throws IOException { // Since input takes in uint8 we only want the last byte of num. Output size is well-defined // at 128 bits, or 16 bytes. expectedResult = 1111 - (num & 0xFF); - assertEquals(expectedResult, new DataWord(summary.getResult()).intValue()); + assertEquals(expectedResult, new DataWordImpl(summary.getResult()).intValue()); } @Test - public void testOverWithdrawFromContract() throws IOException { + public void testOverWithdrawFromContract() throws IOException, VMException { String contractName = "MultiFeatureContract"; byte[] deployCode = getDeployCode(contractName); long nrg = 1_000_000; @@ -449,7 +450,7 @@ public void testOverWithdrawFromContract() throws IOException { AionTransaction tx = new AionTransaction( nonce.toByteArray(), null, value.toByteArray(), deployCode, nrg, nrgPrice); - IRepositoryCache repo = blockchain.getRepository().startTracking(); + RepositoryCache repo = blockchain.getRepository().startTracking(); nonce = nonce.add(BigInteger.ONE); Address contract = deployContract(repo, tx, contractName, null, value, nrg, nrgPrice, nonce); @@ -459,7 +460,7 @@ public void testOverWithdrawFromContract() throws IOException { repo = blockchain.getRepository().startTracking(); // Contract has no funds, try to withdraw just 1 coin. - byte[] input = ByteUtil.merge(Hex.decode("9424bba3"), new DataWord(1).getData()); + byte[] input = ByteUtil.merge(Hex.decode("9424bba3"), new DataWordImpl(1).getData()); tx = new AionTransaction( nonce.toByteArray(), @@ -486,7 +487,7 @@ public void testOverWithdrawFromContract() throws IOException { } @Test - public void testWithdrawFromContract() throws IOException { + public void testWithdrawFromContract() throws IOException, VMException { String contractName = "MultiFeatureContract"; byte[] deployCode = getDeployCode(contractName); long nrg = 1_000_000; @@ -496,7 +497,7 @@ public void testWithdrawFromContract() throws IOException { AionTransaction tx = new AionTransaction( nonce.toByteArray(), null, value.toByteArray(), deployCode, nrg, nrgPrice); - IRepositoryCache repo = blockchain.getRepository().startTracking(); + RepositoryCache repo = blockchain.getRepository().startTracking(); nonce = nonce.add(BigInteger.ONE); Address contract = deployContract(repo, tx, contractName, null, value, nrg, nrgPrice, nonce); @@ -504,7 +505,7 @@ public void testWithdrawFromContract() throws IOException { BigInteger deployerBalance = repo.getBalance(deployer); // Contract has 2^32 coins, let's withdraw them. - byte[] input = ByteUtil.merge(Hex.decode("9424bba3"), new DataWord(value).getData()); + byte[] input = ByteUtil.merge(Hex.decode("9424bba3"), new DataWordImpl(value).getData()); tx = new AionTransaction( nonce.toByteArray(), @@ -530,7 +531,7 @@ public void testWithdrawFromContract() throws IOException { } @Test - public void testSendContractFundsToOtherAddress() throws IOException { + public void testSendContractFundsToOtherAddress() throws IOException, VMException { String contractName = "MultiFeatureContract"; byte[] deployCode = getDeployCode(contractName); long nrg = 1_000_000; @@ -540,7 +541,7 @@ public void testSendContractFundsToOtherAddress() throws IOException { AionTransaction tx = new AionTransaction( nonce.toByteArray(), null, value.toByteArray(), deployCode, nrg, nrgPrice); - IRepositoryCache repo = blockchain.getRepository().startTracking(); + RepositoryCache repo = blockchain.getRepository().startTracking(); nonce = nonce.add(BigInteger.ONE); Address contract = deployContract(repo, tx, contractName, null, value, nrg, nrgPrice, nonce); @@ -548,12 +549,12 @@ public void testSendContractFundsToOtherAddress() throws IOException { BigInteger deployerBalance = repo.getBalance(deployer); // Create a new account to be our fund recipient. - Address recipient = new AionAddress(RandomUtils.nextBytes(Address.SIZE)); + Address recipient = new Address(RandomUtils.nextBytes(Address.SIZE)); repo.createAccount(recipient); // Contract has 2^13 coins, let's withdraw them. byte[] input = ByteUtil.merge(Hex.decode("8c50612c"), recipient.toBytes()); - input = ByteUtil.merge(input, new DataWord(value).getData()); + input = ByteUtil.merge(input, new DataWordImpl(value).getData()); tx = new AionTransaction( nonce.toByteArray(), @@ -581,7 +582,7 @@ public void testSendContractFundsToOtherAddress() throws IOException { } @Test - public void testSendContractFundsToNonexistentAddress() throws IOException { + public void testSendContractFundsToNonexistentAddress() throws IOException, VMException { String contractName = "MultiFeatureContract"; byte[] deployCode = getDeployCode(contractName); long nrg = 1_000_000; @@ -591,7 +592,7 @@ public void testSendContractFundsToNonexistentAddress() throws IOException { AionTransaction tx = new AionTransaction( nonce.toByteArray(), null, value.toByteArray(), deployCode, nrg, nrgPrice); - IRepositoryCache repo = blockchain.getRepository().startTracking(); + RepositoryCache repo = blockchain.getRepository().startTracking(); nonce = nonce.add(BigInteger.ONE); Address contract = deployContract(repo, tx, contractName, null, value, nrg, nrgPrice, nonce); @@ -599,11 +600,11 @@ public void testSendContractFundsToNonexistentAddress() throws IOException { BigInteger deployerBalance = repo.getBalance(deployer); // Create a new account to be our fund recipient. - Address recipient = new AionAddress(RandomUtils.nextBytes(Address.SIZE)); + Address recipient = new Address(RandomUtils.nextBytes(Address.SIZE)); // Contract has 2^13 coins, let's withdraw them. byte[] input = ByteUtil.merge(Hex.decode("8c50612c"), recipient.toBytes()); - input = ByteUtil.merge(input, new DataWord(value).getData()); + input = ByteUtil.merge(input, new DataWordImpl(value).getData()); tx = new AionTransaction( nonce.toByteArray(), @@ -631,7 +632,7 @@ public void testSendContractFundsToNonexistentAddress() throws IOException { } @Test - public void testCallContractViaAnotherContract() throws IOException { + public void testCallContractViaAnotherContract() throws IOException, VMException { // Deploy the MultiFeatureContract. String contractName = "MultiFeatureContract"; byte[] deployCode = getDeployCode(contractName); @@ -642,7 +643,7 @@ public void testCallContractViaAnotherContract() throws IOException { AionTransaction tx = new AionTransaction( nonce.toByteArray(), null, value.toByteArray(), deployCode, nrg, nrgPrice); - IRepositoryCache repo = blockchain.getRepository().startTracking(); + RepositoryCache repo = blockchain.getRepository().startTracking(); nonce = nonce.add(BigInteger.ONE); Address multiFeatureContract = deployContract(repo, tx, contractName, null, value, nrg, nrgPrice, nonce); @@ -660,7 +661,7 @@ public void testCallContractViaAnotherContract() throws IOException { nonce = nonce.add(BigInteger.ONE); Address callerContract = deployContract(repo, tx, contractName, null, value, nrg, nrgPrice, nonce); - Address recipient = new AionAddress(RandomUtils.nextBytes(Address.SIZE)); + Address recipient = new Address(RandomUtils.nextBytes(Address.SIZE)); deployerBalance = repo.getBalance(deployer); deployerNonce = repo.getNonce(deployer); @@ -696,7 +697,7 @@ public void testCallContractViaAnotherContract() throws IOException { value = BigInteger.TWO.pow(20); input = ByteUtil.merge(Hex.decode("57a60e6b"), recipient.toBytes()); - input = ByteUtil.merge(input, new DataWord(value).getData()); + input = ByteUtil.merge(input, new DataWordImpl(value).getData()); nonce = nonce.add(BigInteger.ONE); tx = new AionTransaction( @@ -722,7 +723,7 @@ public void testCallContractViaAnotherContract() throws IOException { } @Test - public void testRecursiveStackoverflow() throws IOException { + public void testRecursiveStackoverflow() throws IOException, VMException { String contractName = "Recursive"; byte[] deployCode = getDeployCode(contractName); long nrg = Constants.NRG_TRANSACTION_MAX; @@ -732,7 +733,7 @@ public void testRecursiveStackoverflow() throws IOException { AionTransaction tx = new AionTransaction( nonce.toByteArray(), null, value.toByteArray(), deployCode, nrg, nrgPrice); - IRepositoryCache repo = blockchain.getRepository().startTracking(); + RepositoryCache repo = blockchain.getRepository().startTracking(); nonce = nonce.add(BigInteger.ONE); Address contract = deployContract(repo, tx, contractName, null, value, nrg, nrgPrice, nonce); @@ -743,7 +744,7 @@ public void testRecursiveStackoverflow() throws IOException { // First recurse 1 time less than the max and verify this is ok. int numRecurses = Constants.MAX_CALL_DEPTH - 1; byte[] input = ByteUtil.merge(Hex.decode("2d7df21a"), contract.toBytes()); - input = ByteUtil.merge(input, new DataWord(numRecurses + 1).getData()); + input = ByteUtil.merge(input, new DataWordImpl(numRecurses + 1).getData()); tx = new AionTransaction( nonce.toByteArray(), @@ -774,7 +775,7 @@ public void testRecursiveStackoverflow() throws IOException { // Now recurse the max amount of times and ensure we fail. numRecurses = Constants.MAX_CALL_DEPTH; input = ByteUtil.merge(Hex.decode("2d7df21a"), contract.toBytes()); - input = ByteUtil.merge(input, new DataWord(numRecurses + 1).getData()); + input = ByteUtil.merge(input, new DataWordImpl(numRecurses + 1).getData()); nonce = nonce.add(BigInteger.ONE); tx = new AionTransaction( @@ -810,12 +811,12 @@ public void testCallPrecompiledContract() { // AionTransaction tx = // new AionTransaction( // nonce.toByteArray(), - // AionAddress.wrap(ContractFactoryMock.CALL_ME), + // Address.wrap(ContractFactoryMock.CALL_ME), // value.toByteArray(), // tagToSend.getBytes(), // nrg, // nrgPrice); - // IRepositoryCache repo = blockchain.getRepository().startTracking(); + // RepositoryCache repo = blockchain.getRepository().startTracking(); // // tx.sign(deployerKey); // assertFalse(tx.isContractCreationTransaction()); @@ -847,7 +848,7 @@ public void testCallPrecompiledContract() { } @Test - public void testRedeployContractAtExistentContractAddress() throws IOException { + public void testRedeployContractAtExistentContractAddress() throws IOException, VMException { String contractName = "MultiFeatureContract"; byte[] deployCode = getDeployCode(contractName); long nrg = 1_000_000; @@ -893,7 +894,7 @@ public void testCallPrecompiledViaSmartContract() throws IOException { // new AionTransaction( // nonce.toByteArray(), null, value.toByteArray(), deployCode, nrg, // nrgPrice); - // IRepositoryCache repo = blockchain.getRepository().startTracking(); + // RepositoryCache repo = blockchain.getRepository().startTracking(); // nonce = nonce.add(BigInteger.ONE); // Address contract = // deployContract(repo, tx, contractName, null, value, nrg, nrgPrice, nonce); @@ -909,7 +910,7 @@ public void testCallPrecompiledViaSmartContract() throws IOException { // byte[] input = // ByteUtil.merge( // Hex.decode("783efb98"), - // AionAddress.wrap(ContractFactoryMock.CALL_ME).toBytes()); + // Address.wrap(ContractFactoryMock.CALL_ME).toBytes()); // input = ByteUtil.merge(input, msg.getBytes()); // // tx = @@ -952,7 +953,7 @@ public void testCallPrecompiledViaSmartContract() throws IOException { * contract deployer and returns the address of the contract once finished. */ private Address deployContract( - IRepositoryCache repo, + RepositoryCache repo, AionTransaction tx, String contractName, String contractFilename, @@ -960,7 +961,7 @@ private Address deployContract( long nrg, long nrgPrice, BigInteger nonce) - throws IOException { + throws IOException, VMException { tx.sign(deployerKey); assertTrue(tx.isContractCreationTransaction()); @@ -1021,7 +1022,7 @@ private byte[] getBodyCode(String contractName) throws IOException { * after the contract whose name is contractName is deployed to it. */ private void checkStateOfNewContract( - IRepositoryCache repo, + RepositoryCache repo, String contractName, Address contractAddr, byte[] output, @@ -1047,7 +1048,7 @@ private void checkStateOfNewContract( * deployed to it. */ private void checkStateOfNewContract( - IRepositoryCache repo, + RepositoryCache repo, String contractName, String contractFilename, Address contractAddr, @@ -1076,7 +1077,7 @@ private void checkStateOfNewContract( *

    D is default starting amount U is energy used P is energy price V is value transferred */ private void checkStateOfDeployer( - IRepositoryCache repo, + RepositoryCache repo, AionTxExecSummary summary, long nrgPrice, BigInteger value, @@ -1091,7 +1092,7 @@ private void checkStateOfDeployer( * Checks the state of the deployer after a failed attempt to deploy a contract. In this case we * expect the deployer's nonce to still be zero and their balance still default and unchanged. */ - private void checkStateOfDeployerOnBadDeploy(IRepositoryCache repo) { + private void checkStateOfDeployerOnBadDeploy(RepositoryCache repo) { assertEquals(BigInteger.ZERO, repo.getNonce(deployer)); assertEquals(Builder.DEFAULT_BALANCE, repo.getBalance(deployer)); @@ -1102,21 +1103,21 @@ private void checkStateOfDeployerOnBadDeploy(IRepositoryCache repo) { * call to the fastVM and this output is of variable length not predefined length. */ private byte[] extractOutput(byte[] rawOutput) { - int headerLen = new DataWord(Arrays.copyOfRange(rawOutput, 0, DataWord.BYTES)).intValue(); + int headerLen = new DataWordImpl(Arrays.copyOfRange(rawOutput, 0, DataWordImpl.BYTES)).intValue(); int outputLen = - new DataWord( + new DataWordImpl( Arrays.copyOfRange( rawOutput, - (DataWord.BYTES * 2) - headerLen, - DataWord.BYTES * 2)) + (DataWordImpl.BYTES * 2) - headerLen, + DataWordImpl.BYTES * 2)) .intValue(); byte[] output = new byte[outputLen]; - System.arraycopy(rawOutput, DataWord.BYTES * 2, output, 0, outputLen); + System.arraycopy(rawOutput, DataWordImpl.BYTES * 2, output, 0, outputLen); return output; } private BulkExecutor getNewExecutor( - AionTransaction tx, IAionBlock block, IRepositoryCache repo) { + AionTransaction tx, IAionBlock block, RepositoryCache repo) { ExecutionBatch details = new ExecutionBatch(block, Collections.singletonList(tx)); return new BulkExecutor( details, repo, false, true, block.getNrgLimit(), LOGGER_VM, getPostExecutionWork()); diff --git a/modAionImpl/test/org/aion/zero/impl/vm/FvmBulkTransactionTest.java b/modAionImpl/test/org/aion/zero/impl/vm/FvmBulkTransactionTest.java index d88b8493fa..de83fa9684 100644 --- a/modAionImpl/test/org/aion/zero/impl/vm/FvmBulkTransactionTest.java +++ b/modAionImpl/test/org/aion/zero/impl/vm/FvmBulkTransactionTest.java @@ -8,12 +8,12 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.mcf.core.ImportResult; -import org.aion.mcf.vm.types.DataWord; +import org.aion.mcf.vm.types.DataWordImpl; import org.aion.util.conversions.Hex; -import org.aion.vm.api.interfaces.Address; + import org.aion.zero.impl.StandaloneBlockchain; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.impl.types.AionBlockSummary; @@ -152,7 +152,7 @@ private AionTransaction makeFvmContractCreateTransaction(ECKey sender, BigIntege AionTransaction transaction = newTransaction( nonce, - AionAddress.wrap(sender.getAddress()), + Address.wrap(sender.getAddress()), null, BigInteger.ZERO, contractBytes, @@ -172,7 +172,7 @@ private AionTransaction makeFvmContractCallTransaction( AionTransaction transaction = newTransaction( nonce, - AionAddress.wrap(sender.getAddress()), + Address.wrap(sender.getAddress()), contract, BigInteger.ZERO, callBytes, @@ -191,7 +191,7 @@ private int getDeployedTickerCountValue(ECKey sender, BigInteger nonce, Address AionTransaction transaction = newTransaction( nonce, - AionAddress.wrap(sender.getAddress()), + Address.wrap(sender.getAddress()), contract, BigInteger.ZERO, callBytes, @@ -202,7 +202,7 @@ private int getDeployedTickerCountValue(ECKey sender, BigInteger nonce, Address AionBlockSummary summary = sendTransactionsInBulkInSingleBlock(Collections.singletonList(transaction)); - return new DataWord(summary.getReceipts().get(0).getTransactionOutput()).intValue(); + return new DataWordImpl(summary.getReceipts().get(0).getTransactionOutput()).intValue(); } private AionTransaction newTransaction( @@ -230,7 +230,7 @@ private BigInteger getNonce(Address address) { } private BigInteger getNonce(ECKey address) { - return getNonce(AionAddress.wrap(address.getAddress())); + return getNonce(Address.wrap(address.getAddress())); } private BigInteger getBalance(Address address) { @@ -238,6 +238,6 @@ private BigInteger getBalance(Address address) { } private BigInteger getBalance(ECKey address) { - return getBalance(AionAddress.wrap(address.getAddress())); + return getBalance(Address.wrap(address.getAddress())); } } diff --git a/modAionImpl/test/org/aion/zero/impl/vm/InternalTransactionTest.java b/modAionImpl/test/org/aion/zero/impl/vm/InternalTransactionTest.java index 50861adee3..55a0c78312 100644 --- a/modAionImpl/test/org/aion/zero/impl/vm/InternalTransactionTest.java +++ b/modAionImpl/test/org/aion/zero/impl/vm/InternalTransactionTest.java @@ -30,17 +30,19 @@ import java.math.BigInteger; import java.util.Collections; import java.util.List; -import org.aion.base.util.ByteUtil; import org.aion.crypto.ECKey; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.aion.mcf.core.ImportResult; -import org.aion.mcf.vm.types.DataWord; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; +import org.aion.util.bytes.ByteUtil; import org.aion.vm.BulkExecutor; import org.aion.vm.ExecutionBatch; import org.aion.vm.PostExecutionWork; -import org.aion.vm.api.interfaces.Address; + import org.aion.vm.api.interfaces.InternalTransactionInterface; +import org.aion.vm.exception.VMException; import org.aion.zero.impl.BlockContext; import org.aion.zero.impl.StandaloneBlockchain; import org.aion.zero.impl.types.AionTxInfo; @@ -167,7 +169,7 @@ public void testLogs() throws InterruptedException { ByteUtil.merge( ByteUtil.hexStringToBytes("0x2d7df21a"), addressB.toBytes(), - new DataWord(80_000).getData()), + new DataWordImpl(80_000).getData()), 1_000_000L, 1L); tx4.sign(deployerAccount); @@ -194,7 +196,7 @@ public void testLogs() throws InterruptedException { ByteUtil.merge( ByteUtil.hexStringToBytes("0x2d7df21a"), addressB.toBytes(), - new DataWord(20_000).getData()), + new DataWordImpl(20_000).getData()), 1_000_000L, 1L); tx6.sign(deployerAccount); @@ -221,7 +223,7 @@ function f(int n) { } */ @Test - public void testRecursiveCall() throws InterruptedException { + public void testRecursiveCall() throws InterruptedException, VMException { String contractA = "0x605060405234156100105760006000fd5b610015565b60e9806100236000396000f30060506040526000356c01000000000000000000000000900463ffffffff168063ec77996414603157602b565b60006000fd5b3415603c5760006000fd5b605060048080359060100190919050506052565b005b600081131560b9573063ec779964600184036040518263ffffffff166c01000000000000000000000000028152600401808281526010019150506000604051808303816000888881813b151560a75760006000fd5b5af1151560b45760006000fd5b505050505b5b505600a165627a7a7230582033f76d593b80b3468bfb0f873882bc00903a790a9b996cb8ca3bac51295994cd0029"; @@ -265,7 +267,7 @@ public void testRecursiveCall() throws InterruptedException { addressA, new byte[0], ByteUtil.merge( - ByteUtil.hexStringToBytes("0xec779964"), new DataWord(2).getData()), + ByteUtil.hexStringToBytes("0xec779964"), new DataWordImpl(2).getData()), 1_000_000L, 1L); tx2.sign(deployerAccount); @@ -312,7 +314,7 @@ function A() { } */ @Test - public void testNestedCreate() throws InterruptedException { + public void testNestedCreate() throws InterruptedException, VMException { String contractA = "0x60506040523415600f5760006000fd5b5b60166048565b604051809103906000f0801582151615602f5760006000fd5b60006000508282909180600101839055555050505b6057565b604051605a8061009f83390190565b603a806100656000396000f30060506040526008565b60006000fd00a165627a7a72305820c0eea40d4778b01848164e58898e9e8c8ab068ed5ee36ed6f0582d119ecbbede002960506040523415600f5760006000fd5b6013565b603a8060206000396000f30060506040526008565b60006000fd00a165627a7a723058208c13bc92baf844f8574632dca44c49776516cb6cd537b10ed700bf61392b6ae80029"; diff --git a/modAionImpl/test/org/aion/zero/impl/vm/InvalidBlockTest.java b/modAionImpl/test/org/aion/zero/impl/vm/InvalidBlockTest.java new file mode 100644 index 0000000000..fbc003831e --- /dev/null +++ b/modAionImpl/test/org/aion/zero/impl/vm/InvalidBlockTest.java @@ -0,0 +1,100 @@ +package org.aion.zero.impl.vm; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.mongodb.client.model.Collation; +import org.aion.avm.core.dappreading.JarBuilder; +import org.aion.avm.core.util.CodeAndArguments; +import org.aion.crypto.ECKey; +import org.aion.mcf.core.ImportResult; +import org.aion.types.Address; +import org.aion.vm.VirtualMachineProvider; +import org.aion.zero.impl.StandaloneBlockchain; +import org.aion.zero.impl.types.AionBlock; +import org.aion.zero.impl.types.AionBlockSummary; +import org.aion.zero.impl.vm.contracts.Contract; +import org.aion.zero.types.AionTransaction; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class InvalidBlockTest { + private StandaloneBlockchain blockchain; + private ECKey deployerKey; + private long energyPrice = 1; + + @BeforeClass + public static void setupAvm() { + VirtualMachineProvider.initializeAllVirtualMachines(); + } + + @AfterClass + public static void tearDownAvm() { + VirtualMachineProvider.shutdownAllVirtualMachines(); + } + + @Before + public void setup() { + StandaloneBlockchain.Bundle bundle = + new StandaloneBlockchain.Builder() + .withDefaultAccounts() + .withValidatorConfiguration("simple") + .withAvmEnabled() + .build(); + this.blockchain = bundle.bc; + this.deployerKey = bundle.privateKeys.get(0); + } + + @After + public void tearDown() { + this.blockchain = null; + this.deployerKey = null; + } + + @Test + public void test() { + BigInteger nonce = this.blockchain.getRepository().getNonce(Address.wrap(this.deployerKey.getAddress())); + List transactions = makeTransactions(10, nonce); + Collections.shuffle(transactions); + + AionBlock parent = this.blockchain.getBestBlock(); + AionBlock block = this.blockchain.createNewBlock(parent, transactions, false); + + Pair res = this.blockchain.tryToConnectAndFetchSummary(block); + System.out.println(res.getLeft()); + System.out.println(res.getRight().getReceipts()); + } + + private List makeTransactions(int num, BigInteger initialNonce) { + List transactions = new ArrayList<>(); + + byte[] jar = new CodeAndArguments(JarBuilder.buildJarForMainAndClassesAndUserlib(Contract.class), new byte[0]).encodeToBytes(); + BigInteger nonce = initialNonce; + + for (int i = 0; i < num; i++) { + + AionTransaction transaction = new AionTransaction( + nonce.toByteArray(), + Address.wrap(this.deployerKey.getAddress()), + null, + BigInteger.ZERO.toByteArray(), + jar, + 5_000_000L, + 10_000_000_000L, + (byte) 0x0f); + transaction.sign(this.deployerKey); + + transactions.add(transaction); + nonce = nonce.add(BigInteger.ONE); + } + + return transactions; + } + +} \ No newline at end of file diff --git a/modAionImpl/test/org/aion/zero/impl/vm/OldTxExecutorTest.java b/modAionImpl/test/org/aion/zero/impl/vm/OldTxExecutorTest.java index 15f3f0e2f4..d18d3950f1 100644 --- a/modAionImpl/test/org/aion/zero/impl/vm/OldTxExecutorTest.java +++ b/modAionImpl/test/org/aion/zero/impl/vm/OldTxExecutorTest.java @@ -30,22 +30,23 @@ import java.math.BigInteger; import java.util.Collections; import java.util.List; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.base.util.Hex; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; import org.aion.crypto.ECKeyFac; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; -import org.aion.mcf.vm.types.DataWord; import org.aion.solidity.CompilationResult; import org.aion.solidity.Compiler; import org.aion.solidity.Compiler.Options; +import org.aion.util.conversions.Hex; import org.aion.vm.BulkExecutor; import org.aion.vm.ExecutionBatch; import org.aion.vm.PostExecutionWork; -import org.aion.vm.api.interfaces.Address; + +import org.aion.vm.exception.VMException; import org.aion.zero.impl.StandaloneBlockchain; import org.aion.zero.impl.db.AionRepositoryImpl; import org.aion.zero.impl.types.AionBlock; @@ -83,7 +84,7 @@ public void tearDown() { } @Test - public void testCallTransaction() throws IOException { + public void testCallTransaction() throws IOException, VMException { Compiler.Result r = Compiler.getInstance() .compile( @@ -92,25 +93,25 @@ public void testCallTransaction() throws IOException { String deployer = cr.contracts.get("Ticker").bin; // deployer String contract = deployer.substring(deployer.indexOf("60506040", 1)); // contract - byte[] txNonce = DataWord.ZERO.getData(); + byte[] txNonce = DataWordImpl.ZERO.getData(); Address from = - AionAddress.wrap( + Address.wrap( Hex.decode( "1111111111111111111111111111111111111111111111111111111111111111")); Address to = - AionAddress.wrap( + Address.wrap( Hex.decode( "2222222222222222222222222222222222222222222222222222222222222222")); - byte[] value = DataWord.ZERO.getData(); + byte[] value = DataWordImpl.ZERO.getData(); byte[] data = Hex.decode("c0004213"); - long nrg = new DataWord(100000L).longValue(); - long nrgPrice = DataWord.ONE.longValue(); + long nrg = new DataWordImpl(100000L).longValue(); + long nrgPrice = DataWordImpl.ONE.longValue(); AionTransaction tx = new AionTransaction(txNonce, from, to, value, data, nrg, nrgPrice); AionBlock block = createDummyBlock(); AionRepositoryImpl repo = blockchain.getRepository(); - IRepositoryCache cache = repo.startTracking(); + RepositoryCache cache = repo.startTracking(); cache.addBalance(from, BigInteger.valueOf(100_000).multiply(tx.nrgPrice().value())); cache.createAccount(to); cache.saveCode(to, Hex.decode(contract)); @@ -134,7 +135,7 @@ public void testCallTransaction() throws IOException { } @Test - public void testCreateTransaction() throws IOException { + public void testCreateTransaction() throws IOException, VMException { Compiler.Result r = Compiler.getInstance() .compile( @@ -143,13 +144,13 @@ public void testCreateTransaction() throws IOException { String deployer = cr.contracts.get("Ticker").bin; System.out.println(deployer); - byte[] txNonce = DataWord.ZERO.getData(); + byte[] txNonce = DataWordImpl.ZERO.getData(); Address from = - AionAddress.wrap( + Address.wrap( Hex.decode( "1111111111111111111111111111111111111111111111111111111111111111")); - Address to = AionAddress.EMPTY_ADDRESS(); - byte[] value = DataWord.ZERO.getData(); + Address to = null; + byte[] value = DataWordImpl.ZERO.getData(); byte[] data = Hex.decode(deployer); long nrg = 500_000L; long nrgPrice = 1; @@ -158,7 +159,7 @@ public void testCreateTransaction() throws IOException { AionBlock block = createDummyBlock(); AionRepositoryImpl repoTop = blockchain.getRepository(); - IRepositoryCache> repo = repoTop.startTracking(); + RepositoryCache> repo = repoTop.startTracking(); repo.addBalance(from, BigInteger.valueOf(500_000L).multiply(tx.nrgPrice().value())); ExecutionBatch details = new ExecutionBatch(block, Collections.singletonList(tx)); @@ -180,7 +181,7 @@ public void testCreateTransaction() throws IOException { } @Test - public void testPerformance() throws IOException { + public void testPerformance() throws IOException, VMException { Compiler.Result r = Compiler.getInstance() .compile( @@ -189,26 +190,26 @@ public void testPerformance() throws IOException { String deployer = cr.contracts.get("Ticker").bin; // deployer String contract = deployer.substring(deployer.indexOf("60506040", 1)); // contract - byte[] txNonce = DataWord.ZERO.getData(); + byte[] txNonce = DataWordImpl.ZERO.getData(); Address from = - AionAddress.wrap( + Address.wrap( Hex.decode( "1111111111111111111111111111111111111111111111111111111111111111")); Address to = - AionAddress.wrap( + Address.wrap( Hex.decode( "2222222222222222222222222222222222222222222222222222222222222222")); - byte[] value = DataWord.ZERO.getData(); + byte[] value = DataWordImpl.ZERO.getData(); byte[] data = Hex.decode("c0004213"); - long nrg = new DataWord(100000L).longValue(); - long nrgPrice = DataWord.ONE.longValue(); + long nrg = new DataWordImpl(100000L).longValue(); + long nrgPrice = DataWordImpl.ONE.longValue(); AionTransaction tx = new AionTransaction(txNonce, from, to, value, data, nrg, nrgPrice); tx.sign(ECKeyFac.inst().create()); AionBlock block = createDummyBlock(); AionRepositoryImpl repoTop = blockchain.getRepository(); - IRepositoryCache repo = repoTop.startTracking(); + RepositoryCache repo = repoTop.startTracking(); repo.addBalance(from, BigInteger.valueOf(100_000).multiply(tx.nrgPrice().value())); repo.createAccount(to); repo.saveCode(to, Hex.decode(contract)); @@ -234,26 +235,26 @@ public void testPerformance() throws IOException { } @Test - public void testBasicTransactionCost() { - byte[] txNonce = DataWord.ZERO.getData(); + public void testBasicTransactionCost() throws VMException { + byte[] txNonce = DataWordImpl.ZERO.getData(); Address from = - AionAddress.wrap( + Address.wrap( Hex.decode( "1111111111111111111111111111111111111111111111111111111111111111")); Address to = - AionAddress.wrap( + Address.wrap( Hex.decode( "2222222222222222222222222222222222222222222222222222222222222222")); - byte[] value = DataWord.ONE.getData(); + byte[] value = DataWordImpl.ONE.getData(); byte[] data = new byte[0]; - long nrg = new DataWord(100000L).longValue(); - long nrgPrice = DataWord.ONE.longValue(); + long nrg = new DataWordImpl(100000L).longValue(); + long nrgPrice = DataWordImpl.ONE.longValue(); AionTransaction tx = new AionTransaction(txNonce, from, to, value, data, nrg, nrgPrice); AionBlock block = createDummyBlock(); AionRepositoryImpl repoTop = blockchain.getRepository(); - IRepositoryCache repo = repoTop.startTracking(); + RepositoryCache repo = repoTop.startTracking(); repo.addBalance(from, BigInteger.valueOf(1_000_000_000L)); repo.flush(); @@ -277,7 +278,7 @@ private static AionBlock createDummyBlock() { byte[] parentHash = new byte[32]; byte[] coinbase = RandomUtils.nextBytes(Address.SIZE); byte[] logsBloom = new byte[0]; - byte[] difficulty = new DataWord(0x1000000L).getData(); + byte[] difficulty = new DataWordImpl(0x1000000L).getData(); long number = 1; long timestamp = System.currentTimeMillis() / 1000; byte[] extraData = new byte[0]; @@ -291,7 +292,7 @@ private static AionBlock createDummyBlock() { // TODO: set a dummy limit of 5000000 for now return new AionBlock( parentHash, - AionAddress.wrap(coinbase), + Address.wrap(coinbase), logsBloom, difficulty, number, diff --git a/modAionImpl/test/org/aion/zero/impl/vm/OpcodeIntegTest.java b/modAionImpl/test/org/aion/zero/impl/vm/OpcodeIntegTest.java index 8718b962fe..7d8afa3c85 100644 --- a/modAionImpl/test/org/aion/zero/impl/vm/OpcodeIntegTest.java +++ b/modAionImpl/test/org/aion/zero/impl/vm/OpcodeIntegTest.java @@ -33,20 +33,22 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.Hex; + +import org.aion.interfaces.db.RepositoryCache; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; -import org.aion.mcf.vm.types.DataWord; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.conversions.Hex; import org.aion.vm.BulkExecutor; import org.aion.vm.ExecutionBatch; import org.aion.vm.PostExecutionWork; -import org.aion.vm.api.interfaces.Address; + import org.aion.vm.api.interfaces.IExecutionLog; import org.aion.vm.api.interfaces.InternalTransactionInterface; +import org.aion.vm.exception.VMException; import org.aion.zero.impl.BlockContext; import org.aion.zero.impl.StandaloneBlockchain; import org.aion.zero.impl.StandaloneBlockchain.Builder; @@ -76,7 +78,7 @@ public void setup() { .build(); blockchain = bundle.bc; deployerKey = bundle.privateKeys.get(0); - deployer = new AionAddress(deployerKey.getAddress()); + deployer = new Address(deployerKey.getAddress()); deployerBalance = Builder.DEFAULT_BALANCE; } @@ -91,14 +93,14 @@ public void tearDown() { // ====================== test repo & track flushing over multiple levels ====================== @Test - public void testNoRevert() throws IOException { - IRepositoryCache repo = blockchain.getRepository().startTracking(); + public void testNoRevert() throws IOException, VMException { + RepositoryCache repo = blockchain.getRepository().startTracking(); Address D = deployContract(repo, "F", "F.sol", BigInteger.ZERO); long nrg = 1_000_000; long nrgPrice = 1; BigInteger nonce = BigInteger.ONE; - byte[] input = ByteUtil.merge(Hex.decode("f854bb89"), new DataWord(6).getData()); + byte[] input = ByteUtil.merge(Hex.decode("f854bb89"), new DataWordImpl(6).getData()); AionTransaction tx = new AionTransaction( nonce.toByteArray(), @@ -121,29 +123,29 @@ public void testNoRevert() throws IOException { // Check that the logs from our internal transactions are as we expect. List logs = summary.getReceipt().getLogInfoList(); assertEquals(12, logs.size()); - assertArrayEquals(new DataWord(0).getData(), logs.get(0).getData()); - assertArrayEquals(new DataWord(6).getData(), logs.get(1).getData()); - assertArrayEquals(new DataWord(5).getData(), logs.get(2).getData()); - assertArrayEquals(new DataWord(4).getData(), logs.get(3).getData()); - assertArrayEquals(new DataWord(3).getData(), logs.get(4).getData()); - assertArrayEquals(new DataWord(2).getData(), logs.get(5).getData()); - assertArrayEquals(new DataWord(1).getData(), logs.get(6).getData()); - assertArrayEquals(new DataWord(1).getData(), logs.get(7).getData()); - assertArrayEquals(new DataWord(1).getData(), logs.get(8).getData()); - assertArrayEquals(new DataWord(1).getData(), logs.get(9).getData()); - assertArrayEquals(new DataWord(1).getData(), logs.get(10).getData()); - assertArrayEquals(new DataWord(1).getData(), logs.get(11).getData()); + assertArrayEquals(new DataWordImpl(0).getData(), logs.get(0).getData()); + assertArrayEquals(new DataWordImpl(6).getData(), logs.get(1).getData()); + assertArrayEquals(new DataWordImpl(5).getData(), logs.get(2).getData()); + assertArrayEquals(new DataWordImpl(4).getData(), logs.get(3).getData()); + assertArrayEquals(new DataWordImpl(3).getData(), logs.get(4).getData()); + assertArrayEquals(new DataWordImpl(2).getData(), logs.get(5).getData()); + assertArrayEquals(new DataWordImpl(1).getData(), logs.get(6).getData()); + assertArrayEquals(new DataWordImpl(1).getData(), logs.get(7).getData()); + assertArrayEquals(new DataWordImpl(1).getData(), logs.get(8).getData()); + assertArrayEquals(new DataWordImpl(1).getData(), logs.get(9).getData()); + assertArrayEquals(new DataWordImpl(1).getData(), logs.get(10).getData()); + assertArrayEquals(new DataWordImpl(1).getData(), logs.get(11).getData()); } @Test - public void testRevertAtBottomLevel() throws IOException { - IRepositoryCache repo = blockchain.getRepository().startTracking(); + public void testRevertAtBottomLevel() throws IOException, VMException { + RepositoryCache repo = blockchain.getRepository().startTracking(); Address D = deployContract(repo, "F", "F.sol", BigInteger.ZERO); long nrg = 1_000_000; long nrgPrice = 1; BigInteger nonce = BigInteger.ONE; - byte[] input = ByteUtil.merge(Hex.decode("8256cff3"), new DataWord(5).getData()); + byte[] input = ByteUtil.merge(Hex.decode("8256cff3"), new DataWordImpl(5).getData()); AionTransaction tx = new AionTransaction( nonce.toByteArray(), @@ -166,25 +168,25 @@ public void testRevertAtBottomLevel() throws IOException { // Check that the logs from our internal transactions are as we expect. List logs = summary.getReceipt().getLogInfoList(); assertEquals(8, logs.size()); - assertArrayEquals(new DataWord(0).getData(), logs.get(0).getData()); - assertArrayEquals(new DataWord(5).getData(), logs.get(1).getData()); - assertArrayEquals(new DataWord(4).getData(), logs.get(2).getData()); - assertArrayEquals(new DataWord(3).getData(), logs.get(3).getData()); - assertArrayEquals(new DataWord(2).getData(), logs.get(4).getData()); - assertArrayEquals(new DataWord(2).getData(), logs.get(5).getData()); - assertArrayEquals(new DataWord(2).getData(), logs.get(6).getData()); - assertArrayEquals(new DataWord(2).getData(), logs.get(7).getData()); + assertArrayEquals(new DataWordImpl(0).getData(), logs.get(0).getData()); + assertArrayEquals(new DataWordImpl(5).getData(), logs.get(1).getData()); + assertArrayEquals(new DataWordImpl(4).getData(), logs.get(2).getData()); + assertArrayEquals(new DataWordImpl(3).getData(), logs.get(3).getData()); + assertArrayEquals(new DataWordImpl(2).getData(), logs.get(4).getData()); + assertArrayEquals(new DataWordImpl(2).getData(), logs.get(5).getData()); + assertArrayEquals(new DataWordImpl(2).getData(), logs.get(6).getData()); + assertArrayEquals(new DataWordImpl(2).getData(), logs.get(7).getData()); } @Test - public void testRevertAtMidLevel() throws IOException { - IRepositoryCache repo = blockchain.getRepository().startTracking(); + public void testRevertAtMidLevel() throws IOException, VMException { + RepositoryCache repo = blockchain.getRepository().startTracking(); Address D = deployContract(repo, "F", "F.sol", BigInteger.ZERO); long nrg = 1_000_000; long nrgPrice = 1; BigInteger nonce = BigInteger.ONE; - byte[] input = ByteUtil.merge(Hex.decode("10462fd0"), new DataWord(7).getData()); + byte[] input = ByteUtil.merge(Hex.decode("10462fd0"), new DataWordImpl(7).getData()); AionTransaction tx = new AionTransaction( nonce.toByteArray(), @@ -207,21 +209,21 @@ public void testRevertAtMidLevel() throws IOException { // Check that the logs from our internal transactions are as we expect. List logs = summary.getReceipt().getLogInfoList(); assertEquals(8, logs.size()); - assertArrayEquals(new DataWord(0).getData(), logs.get(0).getData()); - assertArrayEquals(new DataWord(7).getData(), logs.get(1).getData()); - assertArrayEquals(new DataWord(6).getData(), logs.get(2).getData()); - assertArrayEquals(new DataWord(5).getData(), logs.get(3).getData()); - assertArrayEquals(new DataWord(4).getData(), logs.get(4).getData()); - assertArrayEquals(new DataWord(4).getData(), logs.get(5).getData()); - assertArrayEquals(new DataWord(4).getData(), logs.get(6).getData()); - assertArrayEquals(new DataWord(4).getData(), logs.get(7).getData()); + assertArrayEquals(new DataWordImpl(0).getData(), logs.get(0).getData()); + assertArrayEquals(new DataWordImpl(7).getData(), logs.get(1).getData()); + assertArrayEquals(new DataWordImpl(6).getData(), logs.get(2).getData()); + assertArrayEquals(new DataWordImpl(5).getData(), logs.get(3).getData()); + assertArrayEquals(new DataWordImpl(4).getData(), logs.get(4).getData()); + assertArrayEquals(new DataWordImpl(4).getData(), logs.get(5).getData()); + assertArrayEquals(new DataWordImpl(4).getData(), logs.get(6).getData()); + assertArrayEquals(new DataWordImpl(4).getData(), logs.get(7).getData()); } // ======================================= test CALLCODE ======================================= @Test - public void testCallcodeStorage() throws IOException { - IRepositoryCache repo = blockchain.getRepository().startTracking(); + public void testCallcodeStorage() throws IOException, VMException { + RepositoryCache repo = blockchain.getRepository().startTracking(); BigInteger n = new BigInteger("7638523"); Address D = deployContract(repo, "D", "D.sol", BigInteger.ZERO); Address E = deployContract(repo, "E", "D.sol", BigInteger.ZERO); @@ -232,7 +234,7 @@ public void testCallcodeStorage() throws IOException { long nrgPrice = 1; BigInteger nonce = BigInteger.TWO; byte[] input = ByteUtil.merge(Hex.decode("5cce9fc2"), E.toBytes()); // use CALLCODE on E. - input = ByteUtil.merge(input, new DataWord(n).getData()); // pass in 'n' also. + input = ByteUtil.merge(input, new DataWordImpl(n).getData()); // pass in 'n' also. AionTransaction tx = new AionTransaction( @@ -300,8 +302,8 @@ public void testCallcodeStorage() throws IOException { } @Test - public void testCallcodeActors() throws IOException { - IRepositoryCache repo = blockchain.getRepository().startTracking(); + public void testCallcodeActors() throws IOException, VMException { + RepositoryCache repo = blockchain.getRepository().startTracking(); Address D = deployContract(repo, "D", "D.sol", BigInteger.ZERO); Address E = deployContract(repo, "E", "D.sol", BigInteger.ZERO); @@ -312,7 +314,7 @@ public void testCallcodeActors() throws IOException { long nrgPrice = 1; BigInteger nonce = BigInteger.TWO; byte[] input = ByteUtil.merge(Hex.decode("5cce9fc2"), E.toBytes()); // use CALLCODE on E. - input = ByteUtil.merge(input, new DataWord(0).getData()); // pass in 'n' also. + input = ByteUtil.merge(input, new DataWordImpl(0).getData()); // pass in 'n' also. AionTransaction tx = new AionTransaction( @@ -342,8 +344,8 @@ public void testCallcodeActors() throws IOException { } @Test - public void testCallcodeValueTransfer() throws IOException { - IRepositoryCache repo = blockchain.getRepository().startTracking(); + public void testCallcodeValueTransfer() throws IOException, VMException { + RepositoryCache repo = blockchain.getRepository().startTracking(); Address D = deployContract(repo, "D", "D.sol", BigInteger.ZERO); Address E = deployContract(repo, "E", "D.sol", BigInteger.ZERO); @@ -357,7 +359,7 @@ public void testCallcodeValueTransfer() throws IOException { BigInteger value = new BigInteger("2387653"); BigInteger nonce = BigInteger.TWO; byte[] input = ByteUtil.merge(Hex.decode("5cce9fc2"), E.toBytes()); // use CALLCODE on E. - input = ByteUtil.merge(input, new DataWord(0).getData()); // pass in 'n' also. + input = ByteUtil.merge(input, new DataWordImpl(0).getData()); // pass in 'n' also. AionTransaction tx = new AionTransaction( @@ -385,8 +387,8 @@ public void testCallcodeValueTransfer() throws IOException { // ===================================== test DELEGATECALL ===================================== @Test - public void testDelegateCallStorage() throws IOException { - IRepositoryCache repo = blockchain.getRepository().startTracking(); + public void testDelegateCallStorage() throws IOException, VMException { + RepositoryCache repo = blockchain.getRepository().startTracking(); Address D = deployContract(repo, "D", "D.sol", BigInteger.ZERO); Address E = deployContract(repo, "E", "D.sol", BigInteger.ZERO); BigInteger n = new BigInteger("23786523"); @@ -398,7 +400,7 @@ public void testDelegateCallStorage() throws IOException { BigInteger nonce = BigInteger.TWO; byte[] input = ByteUtil.merge(Hex.decode("32817e1d"), E.toBytes()); // use DELEGATECALL on E. - input = ByteUtil.merge(input, new DataWord(n).getData()); // pass in 'n' also. + input = ByteUtil.merge(input, new DataWordImpl(n).getData()); // pass in 'n' also. AionTransaction tx = new AionTransaction( @@ -460,8 +462,8 @@ public void testDelegateCallStorage() throws IOException { } @Test - public void testDelegateCallActors() throws IOException { - IRepositoryCache repo = blockchain.getRepository().startTracking(); + public void testDelegateCallActors() throws IOException, VMException { + RepositoryCache repo = blockchain.getRepository().startTracking(); Address D = deployContract(repo, "D", "D.sol", BigInteger.ZERO); Address E = deployContract(repo, "E", "D.sol", BigInteger.ZERO); BigInteger n = new BigInteger("23786523"); @@ -473,7 +475,7 @@ public void testDelegateCallActors() throws IOException { BigInteger nonce = BigInteger.TWO; byte[] input = ByteUtil.merge(Hex.decode("32817e1d"), E.toBytes()); // use DELEGATECALL on E. - input = ByteUtil.merge(input, new DataWord(n).getData()); // pass in 'n' also. + input = ByteUtil.merge(input, new DataWordImpl(n).getData()); // pass in 'n' also. AionTransaction tx = new AionTransaction( @@ -499,8 +501,8 @@ public void testDelegateCallActors() throws IOException { } @Test - public void testDelegateCallValueTransfer() throws IOException { - IRepositoryCache repo = blockchain.getRepository().startTracking(); + public void testDelegateCallValueTransfer() throws IOException, VMException { + RepositoryCache repo = blockchain.getRepository().startTracking(); Address D = deployContract(repo, "D", "D.sol", BigInteger.ZERO); Address E = deployContract(repo, "E", "D.sol", BigInteger.ZERO); BigInteger n = new BigInteger("23786523"); @@ -516,7 +518,7 @@ public void testDelegateCallValueTransfer() throws IOException { BigInteger nonce = BigInteger.TWO; byte[] input = ByteUtil.merge(Hex.decode("32817e1d"), E.toBytes()); // use DELEGATECALL on E. - input = ByteUtil.merge(input, new DataWord(n).getData()); // pass in 'n' also. + input = ByteUtil.merge(input, new DataWordImpl(n).getData()); // pass in 'n' also. AionTransaction tx = new AionTransaction( @@ -544,8 +546,8 @@ public void testDelegateCallValueTransfer() throws IOException { // ============================= test CALL, CALLCODE, DELEGATECALL ============================= @Test - public void testOpcodesActors() throws IOException { - IRepositoryCache repo = blockchain.getRepository().startTracking(); + public void testOpcodesActors() throws IOException, VMException { + RepositoryCache repo = blockchain.getRepository().startTracking(); Address callerContract = deployContract(repo, "Caller", "Opcodes.sol", BigInteger.ZERO); Address calleeContract = deployContract(repo, "Callee", "Opcodes.sol", BigInteger.ZERO); @@ -591,10 +593,10 @@ public void testOpcodesActors() throws IOException { // ======================================= test SUICIDE ======================================== @Test - public void testSuicideRecipientExists() throws IOException { - IRepositoryCache repo = blockchain.getRepository().startTracking(); + public void testSuicideRecipientExists() throws IOException, VMException { + RepositoryCache repo = blockchain.getRepository().startTracking(); BigInteger balance = new BigInteger("32522224"); - Address recipient = new AionAddress(RandomUtils.nextBytes(Address.SIZE)); + Address recipient = new Address(RandomUtils.nextBytes(Address.SIZE)); repo.createAccount(recipient); Address contract = deployContract(repo, "Suicide", "Suicide.sol", BigInteger.ZERO); @@ -638,10 +640,10 @@ public void testSuicideRecipientExists() throws IOException { } @Test - public void testSuicideRecipientNewlyCreated() throws IOException { - IRepositoryCache repo = blockchain.getRepository().startTracking(); + public void testSuicideRecipientNewlyCreated() throws IOException, VMException { + RepositoryCache repo = blockchain.getRepository().startTracking(); BigInteger balance = new BigInteger("32522224"); - Address recipient = new AionAddress(RandomUtils.nextBytes(Address.SIZE)); + Address recipient = new Address(RandomUtils.nextBytes(Address.SIZE)); Address contract = deployContract(repo, "Suicide", "Suicide.sol", BigInteger.ZERO); repo.addBalance(contract, balance); @@ -691,8 +693,8 @@ public void testSuicideRecipientNewlyCreated() throws IOException { * Deploys the contract named contractName in the file named contractFilename with value value. */ private Address deployContract( - IRepositoryCache repo, String contractName, String contractFilename, BigInteger value) - throws IOException { + RepositoryCache repo, String contractName, String contractFilename, BigInteger value) + throws IOException, VMException { byte[] deployCode = ContractUtils.getContractDeployer(contractFilename, contractName); long nrg = 1_000_000; @@ -715,7 +717,7 @@ private Address deployContract( *

    Returns the address of the newly deployed contract. */ private Address deployContract( - IRepositoryCache repo, + RepositoryCache repo, AionTransaction tx, String contractName, String contractFilename, @@ -723,7 +725,7 @@ private Address deployContract( long nrg, long nrgPrice, BigInteger expectedNonce) - throws IOException { + throws IOException, VMException { tx.sign(deployerKey); assertTrue(tx.isContractCreationTransaction()); @@ -758,7 +760,7 @@ private Address deployContract( * equal to whatever value was transferred to it when deployed. */ private void checkStateOfNewContract( - IRepositoryCache repo, + RepositoryCache repo, String contractName, String contractFilename, Address contractAddr, @@ -777,7 +779,7 @@ private void checkStateOfNewContract( * the prior balance minus the tx cost and the value transferred. */ private void checkStateOfDeployer( - IRepositoryCache repo, + RepositoryCache repo, BigInteger priorBalance, long nrgUsed, long nrgPrice, @@ -801,12 +803,12 @@ private void verifyLogData(byte[] data, Address owner, Address caller, Address o assertArrayEquals( Arrays.copyOfRange(data, Address.SIZE * 2, Address.SIZE * 3), origin.toBytes()); assertArrayEquals( - Arrays.copyOfRange(data, data.length - DataWord.BYTES, data.length), - DataWord.ZERO.getData()); + Arrays.copyOfRange(data, data.length - DataWordImpl.BYTES, data.length), + DataWordImpl.ZERO.getData()); } private BulkExecutor getNewExecutor( - AionTransaction tx, IAionBlock block, IRepositoryCache repo) { + AionTransaction tx, IAionBlock block, RepositoryCache repo) { ExecutionBatch details = new ExecutionBatch(block, Collections.singletonList(tx)); return new BulkExecutor( details, repo, false, true, block.getNrgLimit(), LOGGER_VM, getPostExecutionWork()); diff --git a/modAionImpl/test/org/aion/zero/impl/vm/SolidityTypeTest.java b/modAionImpl/test/org/aion/zero/impl/vm/SolidityTypeTest.java index 1628ee32ff..a9c8f1c573 100644 --- a/modAionImpl/test/org/aion/zero/impl/vm/SolidityTypeTest.java +++ b/modAionImpl/test/org/aion/zero/impl/vm/SolidityTypeTest.java @@ -30,13 +30,11 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.Hex; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; -import org.aion.mcf.vm.types.DataWord; import org.aion.solidity.CompilationResult; import org.aion.solidity.Compiler; import org.aion.solidity.Compiler.Options; @@ -50,10 +48,13 @@ import org.aion.solidity.SolidityType.IntType; import org.aion.solidity.SolidityType.StaticArrayType; import org.aion.solidity.SolidityType.StringType; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.conversions.Hex; import org.aion.vm.BulkExecutor; import org.aion.vm.ExecutionBatch; import org.aion.vm.PostExecutionWork; -import org.aion.vm.api.interfaces.Address; + +import org.aion.vm.exception.VMException; import org.aion.zero.impl.StandaloneBlockchain; import org.aion.zero.impl.db.AionRepositoryImpl; import org.aion.zero.impl.types.AionBlock; @@ -87,23 +88,23 @@ public void tearDown() { } private AionTransaction createTransaction(byte[] callData) { - byte[] txNonce = DataWord.ZERO.getData(); + byte[] txNonce = DataWordImpl.ZERO.getData(); Address from = - AionAddress.wrap( + Address.wrap( Hex.decode( "1111111111111111111111111111111111111111111111111111111111111111")); Address to = - AionAddress.wrap( + Address.wrap( Hex.decode( "2222222222222222222222222222222222222222222222222222222222222222")); - byte[] value = DataWord.ZERO.getData(); + byte[] value = DataWordImpl.ZERO.getData(); byte[] data = callData; - long nrg = new DataWord(100000L).longValue(); - long nrgPrice = DataWord.ONE.longValue(); + long nrg = new DataWordImpl(100000L).longValue(); + long nrgPrice = DataWordImpl.ONE.longValue(); return new AionTransaction(txNonce, from, to, value, data, nrg, nrgPrice); } - private IRepositoryCache createRepository(AionTransaction tx) throws IOException { + private RepositoryCache createRepository(AionTransaction tx) throws IOException { Result r = Compiler.getInstance() .compile(ContractUtils.readContract("SolidityType.sol"), Options.BIN); @@ -112,7 +113,7 @@ private IRepositoryCache createRepository(AionTransaction tx) throws IOException String contract = deployer.substring(deployer.indexOf("60506040", 1)); AionRepositoryImpl repo = blockchain.getRepository(); - IRepositoryCache track = repo.startTracking(); + RepositoryCache track = repo.startTracking(); track.addBalance( tx.getSenderAddress(), tx.nrgPrice().value().multiply(BigInteger.valueOf(500_000L))); @@ -123,13 +124,13 @@ private IRepositoryCache createRepository(AionTransaction tx) throws IOException } @Test - public void testBool() throws IOException { + public void testBool() throws IOException, VMException { byte[] params = new BoolType().encode(true); System.out.println(Hex.toHexString(params)); AionTransaction tx = createTransaction(ByteUtil.merge(Hex.decode("e8dde232"), params)); AionBlock block = createDummyBlock(); - IRepositoryCache repo = createRepository(tx); + RepositoryCache repo = createRepository(tx); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxReceipt receipt = exec.execute().get(0).getReceipt(); @@ -140,14 +141,14 @@ public void testBool() throws IOException { } @Test - public void testInt() throws IOException { + public void testInt() throws IOException, VMException { BigInteger bi = new BigInteger(1, Hex.decode("ffffffffffffffffffffffff")); byte[] params = new IntType("int96").encode(bi); System.out.println(Hex.toHexString(params)); AionTransaction tx = createTransaction(ByteUtil.merge(Hex.decode("6761755c"), params)); AionBlock block = createDummyBlock(); - IRepositoryCache repo = createRepository(tx); + RepositoryCache repo = createRepository(tx); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxReceipt receipt = exec.execute().get(0).getReceipt(); @@ -159,14 +160,14 @@ public void testInt() throws IOException { } @Test - public void testAddress() throws IOException { + public void testAddress() throws IOException, VMException { byte[] x = Hex.decode("1122334455667788112233445566778811223344556677881122334455667788"); byte[] params = new AddressType().encode(x); System.out.println(Hex.toHexString(params)); AionTransaction tx = createTransaction(ByteUtil.merge(Hex.decode("42f45790"), params)); AionBlock block = createDummyBlock(); - IRepositoryCache repo = createRepository(tx); + RepositoryCache repo = createRepository(tx); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxReceipt receipt = exec.execute().get(0).getReceipt(); @@ -177,7 +178,7 @@ public void testAddress() throws IOException { } @Test - public void testFixedBytes1() throws IOException { + public void testFixedBytes1() throws IOException, VMException { byte[] x = Hex.decode("1122334455"); SolidityType type = new Bytes32Type("bytes5"); byte[] params = type.encode(x); @@ -185,7 +186,7 @@ public void testFixedBytes1() throws IOException { AionTransaction tx = createTransaction(ByteUtil.merge(Hex.decode("faa068d1"), params)); AionBlock block = createDummyBlock(); - IRepositoryCache repo = createRepository(tx); + RepositoryCache repo = createRepository(tx); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxReceipt receipt = exec.execute().get(0).getReceipt(); @@ -196,7 +197,7 @@ public void testFixedBytes1() throws IOException { } @Test - public void testFixedBytes2() throws IOException { + public void testFixedBytes2() throws IOException, VMException { byte[] x = Hex.decode("1122334455667788112233445566778811223344"); SolidityType type = new Bytes32Type("bytes20"); byte[] params = type.encode(x); @@ -204,7 +205,7 @@ public void testFixedBytes2() throws IOException { AionTransaction tx = createTransaction(ByteUtil.merge(Hex.decode("877b277f"), params)); AionBlock block = createDummyBlock(); - IRepositoryCache repo = createRepository(tx); + RepositoryCache repo = createRepository(tx); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxReceipt receipt = exec.execute().get(0).getReceipt(); @@ -215,7 +216,7 @@ public void testFixedBytes2() throws IOException { } @Test - public void testString1() throws IOException { + public void testString1() throws IOException, VMException { String x = "hello, world!"; SolidityType type = new StringType(); byte[] params = @@ -224,7 +225,7 @@ public void testString1() throws IOException { AionTransaction tx = createTransaction(ByteUtil.merge(Hex.decode("61cb5a01"), params)); AionBlock block = createDummyBlock(); - IRepositoryCache repo = createRepository(tx); + RepositoryCache repo = createRepository(tx); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxReceipt receipt = exec.execute().get(0).getReceipt(); @@ -235,7 +236,7 @@ public void testString1() throws IOException { } @Test - public void testString2() throws IOException { + public void testString2() throws IOException, VMException { String x = "hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!"; SolidityType type = new StringType(); byte[] params = @@ -244,7 +245,7 @@ public void testString2() throws IOException { AionTransaction tx = createTransaction(ByteUtil.merge(Hex.decode("61cb5a01"), params)); AionBlock block = createDummyBlock(); - IRepositoryCache repo = createRepository(tx); + RepositoryCache repo = createRepository(tx); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxReceipt receipt = exec.execute().get(0).getReceipt(); @@ -255,7 +256,7 @@ public void testString2() throws IOException { } @Test - public void testBytes1() throws IOException { + public void testBytes1() throws IOException, VMException { byte[] x = Hex.decode("1122334455667788"); SolidityType type = new BytesType(); byte[] params = @@ -264,7 +265,7 @@ public void testBytes1() throws IOException { AionTransaction tx = createTransaction(ByteUtil.merge(Hex.decode("61cb5a01"), params)); AionBlock block = createDummyBlock(); - IRepositoryCache repo = createRepository(tx); + RepositoryCache repo = createRepository(tx); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxReceipt receipt = exec.execute().get(0).getReceipt(); @@ -275,7 +276,7 @@ public void testBytes1() throws IOException { } @Test - public void testBytes2() throws IOException { + public void testBytes2() throws IOException, VMException { byte[] x = Hex.decode( "11223344556677881122334455667788112233445566778811223344556677881122334455667788"); @@ -286,7 +287,7 @@ public void testBytes2() throws IOException { AionTransaction tx = createTransaction(ByteUtil.merge(Hex.decode("61cb5a01"), params)); AionBlock block = createDummyBlock(); - IRepositoryCache repo = createRepository(tx); + RepositoryCache repo = createRepository(tx); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxReceipt receipt = exec.execute().get(0).getReceipt(); @@ -297,7 +298,7 @@ public void testBytes2() throws IOException { } @Test - public void testStaticArray1() throws IOException { + public void testStaticArray1() throws IOException, VMException { List x = new ArrayList<>(); x.add(BigInteger.valueOf(1L)); x.add(BigInteger.valueOf(2L)); @@ -309,7 +310,7 @@ public void testStaticArray1() throws IOException { AionTransaction tx = createTransaction(ByteUtil.merge(Hex.decode("97e934e2"), params)); AionBlock block = createDummyBlock(); - IRepositoryCache repo = createRepository(tx); + RepositoryCache repo = createRepository(tx); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxReceipt receipt = exec.execute().get(0).getReceipt(); @@ -324,7 +325,7 @@ public void testStaticArray1() throws IOException { } @Test - public void testStaticArray2() throws IOException { + public void testStaticArray2() throws IOException, VMException { List x = new ArrayList<>(); x.add(Hex.decode("1122334455667788112233445566778811223344")); x.add(Hex.decode("2122334455667788112233445566778811223344")); @@ -336,7 +337,7 @@ public void testStaticArray2() throws IOException { AionTransaction tx = createTransaction(ByteUtil.merge(Hex.decode("e4bef5c9"), params)); AionBlock block = createDummyBlock(); - IRepositoryCache repo = createRepository(tx); + RepositoryCache repo = createRepository(tx); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxReceipt receipt = exec.execute().get(0).getReceipt(); @@ -351,7 +352,7 @@ public void testStaticArray2() throws IOException { } @Test - public void testDynamicArray1() throws IOException { + public void testDynamicArray1() throws IOException, VMException { List x = new ArrayList<>(); x.add(BigInteger.valueOf(1L)); x.add(BigInteger.valueOf(2L)); @@ -364,7 +365,7 @@ public void testDynamicArray1() throws IOException { AionTransaction tx = createTransaction(ByteUtil.merge(Hex.decode("8c0c5523"), params)); AionBlock block = createDummyBlock(); - IRepositoryCache repo = createRepository(tx); + RepositoryCache repo = createRepository(tx); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxReceipt receipt = exec.execute().get(0).getReceipt(); @@ -379,7 +380,7 @@ public void testDynamicArray1() throws IOException { } @Test - public void testDynamicArray2() throws IOException { + public void testDynamicArray2() throws IOException, VMException { List x = new ArrayList<>(); x.add(Hex.decode("1122334455667788112233445566778811223344")); x.add(Hex.decode("2122334455667788112233445566778811223344")); @@ -392,7 +393,7 @@ public void testDynamicArray2() throws IOException { AionTransaction tx = createTransaction(ByteUtil.merge(Hex.decode("97c3b2db"), params)); AionBlock block = createDummyBlock(); - IRepositoryCache repo = createRepository(tx); + RepositoryCache repo = createRepository(tx); BulkExecutor exec = getNewExecutor(tx, block, repo); AionTxReceipt receipt = exec.execute().get(0).getReceipt(); @@ -407,7 +408,7 @@ public void testDynamicArray2() throws IOException { } private BulkExecutor getNewExecutor( - AionTransaction tx, IAionBlock block, IRepositoryCache repo) { + AionTransaction tx, IAionBlock block, RepositoryCache repo) { ExecutionBatch details = new ExecutionBatch(block, Collections.singletonList(tx)); return new BulkExecutor( details, repo, false, true, block.getNrgLimit(), LOGGER_VM, getPostExecutionWork()); @@ -417,7 +418,7 @@ private static AionBlock createDummyBlock() { byte[] parentHash = new byte[32]; byte[] coinbase = RandomUtils.nextBytes(Address.SIZE); byte[] logsBloom = new byte[0]; - byte[] difficulty = new DataWord(0x1000000L).getData(); + byte[] difficulty = new DataWordImpl(0x1000000L).getData(); long number = 1; long timestamp = System.currentTimeMillis() / 1000; byte[] extraData = new byte[0]; @@ -431,7 +432,7 @@ private static AionBlock createDummyBlock() { // TODO: set a dummy limit of 5000000 for now return new AionBlock( parentHash, - AionAddress.wrap(coinbase), + Address.wrap(coinbase), logsBloom, difficulty, number, diff --git a/modAionImpl/test/org/aion/zero/impl/vm/StatefulnessTest.java b/modAionImpl/test/org/aion/zero/impl/vm/StatefulnessTest.java index 8d54a0a20e..a69efc7774 100644 --- a/modAionImpl/test/org/aion/zero/impl/vm/StatefulnessTest.java +++ b/modAionImpl/test/org/aion/zero/impl/vm/StatefulnessTest.java @@ -5,21 +5,21 @@ import java.math.BigInteger; import java.util.Arrays; -import java.util.Collections; -import org.aion.avm.api.ABIEncoder; -import org.aion.avm.core.NodeEnvironment; import org.aion.avm.core.dappreading.JarBuilder; +import org.aion.avm.core.util.ABIUtil; import org.aion.avm.core.util.CodeAndArguments; -import org.aion.base.type.AionAddress; -import org.aion.base.vm.VirtualMachineSpecs; +import org.aion.avm.userlib.abi.ABIEncoder; +import org.aion.crypto.AddressSpecs; import org.aion.crypto.ECKey; import org.aion.mcf.core.ImportResult; +import org.aion.mcf.valid.TransactionTypeRule; +import org.aion.types.Address; import org.aion.vm.VirtualMachineProvider; -import org.aion.vm.api.interfaces.Address; import org.aion.zero.impl.StandaloneBlockchain; -import org.aion.zero.impl.vm.contracts.Statefulness; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.impl.types.AionBlockSummary; +import org.aion.mcf.tx.TransactionTypes; +import org.aion.zero.impl.vm.contracts.Statefulness; import org.aion.zero.types.AionTransaction; import org.aion.zero.types.AionTxReceipt; import org.apache.commons.lang3.RandomUtils; @@ -28,7 +28,6 @@ import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; // These tests are ignored for now because in order for them to pass we need the clock drift buffer @@ -61,7 +60,8 @@ public void setup() { .build(); this.blockchain = bundle.bc; this.deployerKey = bundle.privateKeys.get(0); - this.deployer = AionAddress.wrap(this.deployerKey.getAddress()); + this.deployer = Address.wrap(this.deployerKey.getAddress()); + TransactionTypeRule.allowAVMContractDeployment(); } @After @@ -75,7 +75,7 @@ public void testDeployContract() { AionTxReceipt receipt = deployContract(); // Check the contract has the Avm prefix, and deployment succeeded. - assertEquals(NodeEnvironment.CONTRACT_PREFIX, receipt.getTransactionOutput()[0]); + assertEquals(AddressSpecs.A0_IDENTIFIER, receipt.getTransactionOutput()[0]); assertTrue(receipt.isSuccessful()); } @@ -87,9 +87,9 @@ public void testStateOfActorsAfterDeployment() { AionTxReceipt receipt = deployContract(); // Check the contract has the Avm prefix, and deployment succeeded, and grab the address. - assertEquals(NodeEnvironment.CONTRACT_PREFIX, receipt.getTransactionOutput()[0]); + assertEquals(AddressSpecs.A0_IDENTIFIER, receipt.getTransactionOutput()[0]); assertTrue(receipt.isSuccessful()); - Address contract = AionAddress.wrap(receipt.getTransactionOutput()); + Address contract = Address.wrap(receipt.getTransactionOutput()); BigInteger deployerBalanceAfterDeployment = getBalance(this.deployer); BigInteger deployerNonceAfterDeployment = getNonce(this.deployer); @@ -113,9 +113,9 @@ public void testUsingCallInContract() { AionTxReceipt receipt = deployContract(); // Check the contract has the Avm prefix, and deployment succeeded, and grab the address. - assertEquals(NodeEnvironment.CONTRACT_PREFIX, receipt.getTransactionOutput()[0]); + assertEquals(AddressSpecs.A0_IDENTIFIER, receipt.getTransactionOutput()[0]); assertTrue(receipt.isSuccessful()); - Address contract = AionAddress.wrap(receipt.getTransactionOutput()); + Address contract = Address.wrap(receipt.getTransactionOutput()); BigInteger deployerInitialNonce = getNonce(this.deployer); BigInteger contractInitialNonce = getNonce(contract); @@ -142,7 +142,7 @@ public void testUsingCallInContract() { assertEquals(contractInitialNonce, getNonce(contract)); // Generate a random beneficiary to transfer funds to via the contract. - Address beneficiary = randomAionAddress(); + Address beneficiary = randomAddress(); long valueForContractToSend = fundsToSendToContract.longValue() / 2; // Call the contract to send value using an internal call. @@ -183,7 +183,7 @@ private AionTxReceipt deployContract() { jar, 5_000_000, this.energyPrice, - VirtualMachineSpecs.AVM_CREATE_CODE); + TransactionTypes.AVM_CREATE_CODE); transaction.sign(this.deployerKey); return sendTransactions(transaction); @@ -199,7 +199,7 @@ private AionTxReceipt callContract(Address contract, String method, Object... ar abiEncodeMethodCall(method, arguments), 2_000_000, this.energyPrice, - VirtualMachineSpecs.AVM_CREATE_CODE); + TransactionTypes.AVM_CREATE_CODE); transaction.sign(this.deployerKey); return sendTransactions(transaction); @@ -237,12 +237,12 @@ private AionTxReceipt sendTransactions(AionTransaction... transactions) { private byte[] getJarBytes() { return new CodeAndArguments( - JarBuilder.buildJarForMainAndClasses(Statefulness.class), new byte[0]) + JarBuilder.buildJarForMainAndClassesAndUserlib(Statefulness.class), new byte[0]) .encodeToBytes(); } private byte[] abiEncodeMethodCall(String method, Object... arguments) { - return ABIEncoder.encodeMethodArguments(method, arguments); + return ABIUtil.encodeMethodArguments(method, arguments); } private AionTransaction newTransaction( @@ -273,9 +273,9 @@ private BigInteger getNonce(Address address) { return this.blockchain.getRepository().getNonce(address); } - private Address randomAionAddress() { + private Address randomAddress() { byte[] bytes = RandomUtils.nextBytes(32); bytes[0] = (byte) 0xa0; - return AionAddress.wrap(bytes); + return Address.wrap(bytes); } } diff --git a/modAionImpl/test/org/aion/zero/impl/vm/TransactionExecutorTest.java b/modAionImpl/test/org/aion/zero/impl/vm/TransactionExecutorTest.java index 43605db7b5..98d0035a5b 100644 --- a/modAionImpl/test/org/aion/zero/impl/vm/TransactionExecutorTest.java +++ b/modAionImpl/test/org/aion/zero/impl/vm/TransactionExecutorTest.java @@ -27,23 +27,32 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.io.IOException; import java.math.BigInteger; import java.util.Arrays; import java.util.Collections; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.base.util.Hex; +import java.util.List; + +import org.aion.fastvm.FastVmResultCode; +import org.aion.fastvm.FastVmTransactionResult; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.interfaces.tx.Transaction; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.aion.mcf.core.ImportResult; -import org.aion.mcf.vm.types.DataWord; +import org.aion.util.conversions.Hex; import org.aion.vm.BulkExecutor; import org.aion.vm.ExecutionBatch; import org.aion.vm.PostExecutionWork; -import org.aion.vm.api.interfaces.Address; + +import org.aion.vm.api.interfaces.TransactionResult; +import org.aion.vm.exception.VMException; import org.aion.zero.impl.BlockContext; import org.aion.zero.impl.StandaloneBlockchain; import org.aion.zero.impl.StandaloneBlockchain.Builder; @@ -74,7 +83,7 @@ public void setup() { .build(); blockchain = bundle.bc; deployerKey = bundle.privateKeys.get(0); - deployer = new AionAddress(deployerKey.getAddress()); + deployer = new Address(deployerKey.getAddress()); } @After @@ -84,8 +93,22 @@ public void tearDown() { deployer = null; } + @Test(expected = VMException.class) + public void testExecutorFatal() throws VMException { + BulkExecutor be = mock(BulkExecutor.class); + TransactionResult rt = new FastVmTransactionResult(FastVmResultCode.VM_INTERNAL_ERROR, 0); + when(be.execute()).thenThrow(new VMException(rt.toString())); + + try { + be.execute(); + } catch (VMException e) { + System.out.println(e.toString()); + throw e; + } + } + @Test - public void testExecutor() throws IOException { + public void testExecutor() throws IOException, VMException { Address to = getNewRecipient(true); byte[] deployCode = ContractUtils.getContractDeployer("ByteArrayMap.sol", "ByteArrayMap"); long nrg = 1_000_000; @@ -104,7 +127,7 @@ public void testExecutor() throws IOException { blockchain.createNewBlockContext( blockchain.getBestBlock(), Collections.singletonList(tx), false); - IRepositoryCache repo = blockchain.getRepository().startTracking(); + RepositoryCache repo = blockchain.getRepository().startTracking(); ExecutionBatch details = new ExecutionBatch(context.block, Collections.singletonList(tx)); BulkExecutor exec = new BulkExecutor( @@ -183,7 +206,7 @@ public void testExecutorBlind() throws IOException { } @Test - public void testDeployedCodeFunctionality() throws IOException { + public void testDeployedCodeFunctionality() throws IOException, VMException { Address contract = deployByteArrayContract(); byte[] callingCode = Hex.decode(f_func); BigInteger nonce = blockchain.getRepository().getNonce(deployer); @@ -201,7 +224,7 @@ public void testDeployedCodeFunctionality() throws IOException { BlockContext context = blockchain.createNewBlockContext( blockchain.getBestBlock(), Collections.singletonList(tx), false); - IRepositoryCache repo = blockchain.getRepository().startTracking(); + RepositoryCache repo = blockchain.getRepository().startTracking(); ExecutionBatch details = new ExecutionBatch(context.block, Collections.singletonList(tx)); BulkExecutor exec = new BulkExecutor( @@ -259,9 +282,10 @@ public void testDeployedCodeFunctionality() throws IOException { // // I'm guessing: first data word is the number of bytes that follows. Then those // following // // bytes denote the size of the output, which follows these last bytes. - // int len = new DataWord(Arrays.copyOfRange(output, 0, DataWord.BYTES)).intValue(); + // int len = new DataWordImpl(Arrays.copyOfRange(output, 0, + // DataWordImpl.BYTES)).intValue(); // byte[] outputLen = new byte[len]; - // System.arraycopy(output, DataWord.BYTES, outputLen, 0, len); + // System.arraycopy(output, DataWordImpl.BYTES, outputLen, 0, len); // int outputSize = new BigInteger(outputLen).intValue(); // // byte[] expected = new byte[1024]; @@ -269,7 +293,7 @@ public void testDeployedCodeFunctionality() throws IOException { // expected[1023] = 'b'; // // byte[] out = new byte[outputSize]; - // System.arraycopy(output, DataWord.BYTES + len, out, 0, outputSize); + // System.arraycopy(output, DataWordImpl.BYTES + len, out, 0, outputSize); byte[] expected = new byte[1024]; expected[0] = 'a'; @@ -281,7 +305,7 @@ public void testDeployedCodeFunctionality() throws IOException { } @Test - public void testGfunction() throws IOException { + public void testGfunction() throws IOException, VMException { Address contract = deployByteArrayContract(); byte[] callingCode = Hex.decode(g_func); BigInteger nonce = blockchain.getRepository().getNonce(deployer); @@ -299,7 +323,7 @@ public void testGfunction() throws IOException { BlockContext context = blockchain.createNewBlockContext( blockchain.getBestBlock(), Collections.singletonList(tx), false); - IRepositoryCache repo = blockchain.getRepository().startTracking(); + RepositoryCache repo = blockchain.getRepository().startTracking(); ExecutionBatch details = new ExecutionBatch(context.block, Collections.singletonList(tx)); BulkExecutor exec = @@ -349,19 +373,19 @@ private Address deployByteArrayContract() throws IOException { } private Address getNewRecipient(boolean isContractCreation) { - return (isContractCreation) ? null : new AionAddress(RandomUtils.nextBytes(Address.SIZE)); + return (isContractCreation) ? null : new Address(RandomUtils.nextBytes(Address.SIZE)); } private byte[] extractActualOutput(byte[] rawOutput) { // I'm guessing: first data word is the number of bytes that follows. Then those following // bytes denote the size of the output, which follows these last bytes. - int len = new DataWord(Arrays.copyOfRange(rawOutput, 0, DataWord.BYTES)).intValue(); + int len = new DataWordImpl(Arrays.copyOfRange(rawOutput, 0, DataWordImpl.BYTES)).intValue(); byte[] outputLen = new byte[len]; - System.arraycopy(rawOutput, DataWord.BYTES, outputLen, 0, len); + System.arraycopy(rawOutput, DataWordImpl.BYTES, outputLen, 0, len); int outputSize = new BigInteger(outputLen).intValue(); byte[] out = new byte[outputSize]; - System.arraycopy(rawOutput, DataWord.BYTES + len, out, 0, outputSize); + System.arraycopy(rawOutput, DataWordImpl.BYTES + len, out, 0, outputSize); return out; } diff --git a/modAionImpl/test/org/aion/zero/impl/vm/VMTxStateAlignTest.java b/modAionImpl/test/org/aion/zero/impl/vm/VMTxStateAlignTest.java new file mode 100644 index 0000000000..5b15d54621 --- /dev/null +++ b/modAionImpl/test/org/aion/zero/impl/vm/VMTxStateAlignTest.java @@ -0,0 +1,195 @@ +package org.aion.zero.impl.vm; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import org.aion.crypto.ECKey; +import org.aion.mcf.core.ImportResult; +import org.aion.precompiled.ContractFactory; +import org.aion.types.Address; +import org.aion.util.conversions.Hex; +import org.aion.vm.VirtualMachineProvider; +import org.aion.zero.impl.StandaloneBlockchain; +import org.aion.zero.impl.types.AionBlock; +import org.aion.zero.impl.types.AionBlockSummary; +import org.aion.zero.impl.vm.contracts.ContractUtils; +import org.aion.zero.types.AionTransaction; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class VMTxStateAlignTest { + private StandaloneBlockchain blockchainWoAVM; + + private List deployerKeys; + private int deployerNum = 5; + private List

    deployers; + private long energyPrice = 1; + + @BeforeClass + public static void setupVM() { + VirtualMachineProvider.initializeAllVirtualMachines(); + } + + @AfterClass + public static void tearDownVM() { + VirtualMachineProvider.shutdownAllVirtualMachines(); + } + + @Before + public void setup() { + StandaloneBlockchain.Bundle bundle = + new StandaloneBlockchain.Builder() + .withDefaultAccounts() + .withValidatorConfiguration("simple") + .build(); + this.blockchainWoAVM = bundle.bc; + deployerKeys = bundle.privateKeys; + + deployers = new ArrayList<>(); + for (int i = 0; i < deployerNum && i < deployerKeys.size(); i++) { + Address deployerAddr = Address.wrap(this.deployerKeys.get(i).getAddress()); + deployers.add(deployerAddr); + } + } + + @After + public void tearDown() { + this.blockchainWoAVM = null; + this.deployerKeys = null; + this.deployers = null; + } + + @Test + public void testDeployAndCallContractStatesAlign() throws IOException { + List txList = new ArrayList<>(); + List
    deployAddr = new ArrayList<>(); + + for (int i = 0; i < this.deployerKeys.size() && i < deployerNum; i++) { + ECKey senderKey = this.deployerKeys.get(i); + txList.add(makeFvmContractCreateTransaction(senderKey, BigInteger.ZERO)); + deployAddr.add(txList.get(i).getContractAddress()); + } + + AionBlock deplayBlock = genNewBlock(txList, blockchainWoAVM); + tryImportNewBlock(blockchainWoAVM, deplayBlock); + + txList.clear(); + + ECKey sender = this.deployerKeys.get(deployerKeys.size() - 1); + txList.add(makePrecompiledContractTransaction(sender, BigInteger.ZERO)); + + for (int i = 0; i < this.deployerKeys.size() && i < deployerNum; i++) { + ECKey senderKey = this.deployerKeys.get(i); + txList.add( + makeFvmContractCallTransaction(senderKey, BigInteger.ONE, deployAddr.get(i))); + } + + AionBlock callBlock = genNewBlock(txList, blockchainWoAVM); + tryImportNewBlock(blockchainWoAVM, callBlock); + + // Does not initial in the setup call due to the avmenable in the StandaloneBlockchain is a + // static variable. + StandaloneBlockchain.Bundle bundleAVM = + new StandaloneBlockchain.Builder() + .withDefaultAccounts(deployerKeys) + .withAvmEnabled() + .withValidatorConfiguration("simple") + .build(); + StandaloneBlockchain blockchainWithAVM = bundleAVM.bc; + + tryImportNewBlock(blockchainWithAVM, deplayBlock); + tryImportNewBlock(blockchainWithAVM, callBlock); + } + + private AionTransaction makePrecompiledContractTransaction(ECKey sender, BigInteger nonce) { + AionTransaction transaction = + newTransaction( + nonce, + Address.wrap(sender.getAddress()), + ContractFactory.getBlake2bHashContractAddress(), + BigInteger.ONE, + new byte[10], + 2_000_000, + this.energyPrice, + (byte) 0x01); + transaction.sign(sender); + return transaction; + } + + // Deploys the Ticker.sol contract. + private AionTransaction makeFvmContractCreateTransaction(ECKey sender, BigInteger nonce) + throws IOException { + byte[] contractBytes = ContractUtils.getContractDeployer("Ticker.sol", "Ticker"); + + AionTransaction transaction = + newTransaction( + nonce, + Address.wrap(sender.getAddress()), + null, + BigInteger.ZERO, + contractBytes, + 5_000_000, + this.energyPrice, + (byte) 0x01); + transaction.sign(sender); + return transaction; + } + + private AionTransaction makeFvmContractCallTransaction( + ECKey sender, BigInteger nonce, Address contract) { + // This hash will call the 'ticking' function of the deployed contract (this increments a + // counter). + byte[] callBytes = Hex.decode("dae29f29"); + + AionTransaction transaction = + newTransaction( + nonce, + Address.wrap(sender.getAddress()), + contract, + BigInteger.ZERO, + callBytes, + 2_000_000, + this.energyPrice, + (byte) 0x01); + transaction.sign(sender); + return transaction; + } + + private AionTransaction newTransaction( + BigInteger nonce, + Address sender, + Address destination, + BigInteger value, + byte[] data, + long energyLimit, + long energyPrice, + byte vm) { + return new AionTransaction( + nonce.toByteArray(), + sender, + destination, + value.toByteArray(), + data, + energyLimit, + energyPrice, + vm); + } + + private AionBlock genNewBlock(List transactions, StandaloneBlockchain bc) { + AionBlock parentBlock = bc.getBestBlock(); + return bc.createBlock(parentBlock, transactions, false, parentBlock.getTimestamp()); + } + + private void tryImportNewBlock(StandaloneBlockchain bc, AionBlock block) { + Pair connectResult = bc.tryToConnectAndFetchSummary(block); + assertEquals(ImportResult.IMPORTED_BEST, connectResult.getLeft()); + connectResult.getRight(); + } +} diff --git a/modAionImpl/test/org/aion/zero/impl/vm/contracts/AvmHelloWorld.java b/modAionImpl/test/org/aion/zero/impl/vm/contracts/AvmHelloWorld.java index 18651fc323..6de7034b5f 100644 --- a/modAionImpl/test/org/aion/zero/impl/vm/contracts/AvmHelloWorld.java +++ b/modAionImpl/test/org/aion/zero/impl/vm/contracts/AvmHelloWorld.java @@ -1,7 +1,7 @@ package org.aion.zero.impl.vm.contracts; -import org.aion.avm.api.ABIDecoder; import org.aion.avm.api.BlockchainRuntime; +import org.aion.avm.userlib.abi.ABIDecoder; public class AvmHelloWorld { @@ -10,7 +10,17 @@ public static void sayHello() { } public static byte[] main() { - return ABIDecoder.decodeAndRunWithClass(AvmHelloWorld.class, BlockchainRuntime.getData()); + ABIDecoder decoder = new ABIDecoder(BlockchainRuntime.getData()); + String methodName = decoder.decodeMethodName(); + if (methodName == null) { + return new byte[0]; + } else { + if (methodName.equals("sayHello")) { + sayHello(); + return new byte[0]; + } else { + return new byte[0]; + } + } } - } diff --git a/modAionImpl/test/org/aion/zero/impl/vm/contracts/Contract.java b/modAionImpl/test/org/aion/zero/impl/vm/contracts/Contract.java new file mode 100644 index 0000000000..189ce89268 --- /dev/null +++ b/modAionImpl/test/org/aion/zero/impl/vm/contracts/Contract.java @@ -0,0 +1,38 @@ +package org.aion.zero.impl.vm.contracts; + +import org.aion.avm.api.Address; +import org.aion.avm.api.BlockchainRuntime; +import org.aion.avm.userlib.abi.ABIDecoder; + +public final class Contract { + private static final Address owner = BlockchainRuntime.getCaller(); + + public static boolean isOwner() { + return BlockchainRuntime.getCaller().equals(owner); + } + + public static void transfer(Address address) { + BlockchainRuntime.call(address, BlockchainRuntime.getValue(), new byte[0], BlockchainRuntime.getRemainingEnergy()); + } + + public static void output() { + BlockchainRuntime.println("Owner is: " + owner); + BlockchainRuntime.log(owner.unwrap(), "message".getBytes()); + } + + public static byte[] main() { + ABIDecoder decoder = new ABIDecoder(BlockchainRuntime.getData()); + String methodName = decoder.decodeMethodName(); + if (methodName == null) { + return new byte[0]; + } else { + if (methodName.equals("transfer")) { + transfer(decoder.decodeOneAddress()); + return new byte[0]; + } else { + return new byte[0]; + } + } + } + +} \ No newline at end of file diff --git a/modAionImpl/test/org/aion/zero/impl/vm/contracts/ContractUtils.java b/modAionImpl/test/org/aion/zero/impl/vm/contracts/ContractUtils.java index 98995a4752..42b7e28cac 100644 --- a/modAionImpl/test/org/aion/zero/impl/vm/contracts/ContractUtils.java +++ b/modAionImpl/test/org/aion/zero/impl/vm/contracts/ContractUtils.java @@ -3,10 +3,10 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import org.aion.base.util.Hex; import org.aion.solidity.CompilationResult; import org.aion.solidity.Compiler; import org.aion.solidity.Compiler.Options; +import org.aion.util.conversions.Hex; public class ContractUtils { /** diff --git a/modAionImpl/test/org/aion/zero/impl/vm/contracts/NonpayableConstructor.sol b/modAionImpl/test/org/aion/zero/impl/vm/contracts/NonpayableConstructor.sol new file mode 100644 index 0000000000..12cbca9016 --- /dev/null +++ b/modAionImpl/test/org/aion/zero/impl/vm/contracts/NonpayableConstructor.sol @@ -0,0 +1,7 @@ +pragma solidity ^0.4.8; + +contract NonpayableConstructor { + + function NonpayableConstructor() {} + +} diff --git a/modAionImpl/test/org/aion/zero/impl/vm/contracts/NonpayableFallbackContract.sol b/modAionImpl/test/org/aion/zero/impl/vm/contracts/NonpayableFallbackContract.sol new file mode 100644 index 0000000000..6107624aef --- /dev/null +++ b/modAionImpl/test/org/aion/zero/impl/vm/contracts/NonpayableFallbackContract.sol @@ -0,0 +1,7 @@ +pragma solidity ^0.4.8; + +contract NonpayableFallbackContract { + + function() {} + +} diff --git a/modAionImpl/test/org/aion/zero/impl/vm/contracts/PayableConstructor.sol b/modAionImpl/test/org/aion/zero/impl/vm/contracts/PayableConstructor.sol index f7a51fdb46..eb0efcdc19 100644 --- a/modAionImpl/test/org/aion/zero/impl/vm/contracts/PayableConstructor.sol +++ b/modAionImpl/test/org/aion/zero/impl/vm/contracts/PayableConstructor.sol @@ -4,4 +4,4 @@ contract PayableConstructor { function PayableConstructor() payable {} -} \ No newline at end of file +} diff --git a/modAionImpl/test/org/aion/zero/impl/vm/contracts/PayableContract.sol b/modAionImpl/test/org/aion/zero/impl/vm/contracts/PayableContract.sol new file mode 100644 index 0000000000..41ab51e22b --- /dev/null +++ b/modAionImpl/test/org/aion/zero/impl/vm/contracts/PayableContract.sol @@ -0,0 +1,11 @@ +pragma solidity ^0.4.8; + +contract PayableContract { + + function PayableContract() payable {} + + function notPayableFunction() {} + + function payableFunction() payable {} + +} diff --git a/modAionImpl/test/org/aion/zero/impl/vm/contracts/PayableFallbackContract.sol b/modAionImpl/test/org/aion/zero/impl/vm/contracts/PayableFallbackContract.sol new file mode 100644 index 0000000000..696a027f9e --- /dev/null +++ b/modAionImpl/test/org/aion/zero/impl/vm/contracts/PayableFallbackContract.sol @@ -0,0 +1,7 @@ +pragma solidity ^0.4.8; + +contract PayableFallbackContract { + + function() payable {} + +} diff --git a/modAionImpl/test/org/aion/zero/impl/vm/contracts/Statefulness.java b/modAionImpl/test/org/aion/zero/impl/vm/contracts/Statefulness.java index 600832c312..8d60535a2d 100644 --- a/modAionImpl/test/org/aion/zero/impl/vm/contracts/Statefulness.java +++ b/modAionImpl/test/org/aion/zero/impl/vm/contracts/Statefulness.java @@ -1,15 +1,32 @@ package org.aion.zero.impl.vm.contracts; import java.math.BigInteger; -import org.aion.avm.api.ABIDecoder; import org.aion.avm.api.Address; import org.aion.avm.api.BlockchainRuntime; +import org.aion.avm.userlib.abi.ABIDecoder; +import org.aion.avm.userlib.abi.ABIEncoder; public class Statefulness { private static int counter = 0; public static byte[] main() { - return ABIDecoder.decodeAndRunWithClass(Statefulness.class, BlockchainRuntime.getData()); + ABIDecoder decoder = new ABIDecoder(BlockchainRuntime.getData()); + String methodName = decoder.decodeMethodName(); + if (methodName == null) { + return new byte[0]; + } else { + if (methodName.equals("transferValue")) { + transferValue(decoder.decodeOneByteArray(), decoder.decodeOneLong()); + return new byte[0]; + } else if (methodName.equals("getCount")) { + return ABIEncoder.encodeOneInteger(getCount()); + } else if (methodName.equals("incrementCounter")) { + incrementCounter(); + return new byte[0]; + } else { + return new byte[0]; + } + } } public static void transferValue(byte[] beneficiary, long amount) { diff --git a/modApiServer/build.gradle b/modApiServer/build.gradle index de73ace917..a4d9c293a0 100644 --- a/modApiServer/build.gradle +++ b/modApiServer/build.gradle @@ -14,16 +14,18 @@ sourceSets { } dependencies { - compile project(':modAionBase') + compile project(':aion_vm_api') + compile 'network.aion:util4j:0.4.0' + compile 'network.aion:log4j:0.4.0' + compile 'network.aion:crypto4j:0.4.0' + compile project(':modAion') compile project(':modAionImpl') compile project(':aion_fastvm') compile project(':modMcf') - compile project(':modLogger') compile project(':modP2p') compile project(':modEvtMgr') compile project(':modEvtMgrImpl') - compile project(':modCrypto') compile project(':3rdParty.libnzmq') compile 'org.json:json:20180813' compile group: 'com.google.protobuf', name: 'protobuf-java', version: '3.5.0' @@ -39,7 +41,7 @@ dependencies { testCompile 'junit:junit:4.12' testCompile 'org.hamcrest:hamcrest-all:1.3' testCompile "org.mockito:mockito-core:2.23.0" - + testCompile project(':modVM') testRuntimeOnly project(':modTxPoolImpl') } diff --git a/modApiServer/src/module-info.java b/modApiServer/src/module-info.java index 8a38078f1d..adf8957e4d 100644 --- a/modApiServer/src/module-info.java +++ b/modApiServer/src/module-info.java @@ -1,5 +1,4 @@ module aion.apiserver { - requires aion.base; requires aion.zero.impl; requires aion.log; requires aion.p2p; @@ -20,6 +19,7 @@ requires com.google.common; requires jdk.unsupported; requires aion.vm.api; + requires aion.util; requires libnzmq; exports org.aion.api.server.pb; diff --git a/modApiServer/src/org/aion/api/server/Api.java b/modApiServer/src/org/aion/api/server/Api.java index a7233a8c1f..dcb83410c7 100644 --- a/modApiServer/src/org/aion/api/server/Api.java +++ b/modApiServer/src/org/aion/api/server/Api.java @@ -10,8 +10,7 @@ import java.util.NoSuchElementException; import org.aion.api.server.types.CompiContrInfo; import org.aion.api.server.types.CompiledContr; -import org.aion.base.type.AionAddress; -import org.aion.base.util.TypeConverter; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; @@ -22,7 +21,7 @@ import org.aion.solidity.CompilationResult; import org.aion.solidity.CompilationResult.Contract; import org.aion.solidity.Compiler; -import org.aion.vm.api.interfaces.Address; +import org.aion.util.string.StringUtils; import org.aion.zero.impl.blockchain.AionPendingStateImpl; import org.slf4j.Logger; @@ -60,7 +59,7 @@ public abstract class Api> { protected boolean unlockAccount( final String _address, final String _password, final int _duration) { - return this.ACCOUNT_MANAGER.unlockAccount(AionAddress.wrap(_address), _password, _duration); + return this.ACCOUNT_MANAGER.unlockAccount(Address.wrap(_address), _password, _duration); } public boolean unlockAccount( @@ -77,7 +76,7 @@ public List getAccounts() { } protected ECKey getAccountKey(final String _address) { - return ACCOUNT_MANAGER.getKey(AionAddress.wrap(_address)); + return ACCOUNT_MANAGER.getKey(Address.wrap(_address)); } @SuppressWarnings("rawtypes") @@ -136,7 +135,7 @@ private Map processCompileRsp(Compiler.Result res, String for (Entry stringContractEntry : result.contracts.entrySet()) { CompiledContr ret = new CompiledContr(); Contract Contract = stringContractEntry.getValue(); - ret.code = TypeConverter.toJsonHex(Contract.bin); + ret.code = StringUtils.toJsonHex(Contract.bin); ret.info = new CompiContrInfo(); ret.info.source = source; ret.info.language = "Solidity"; diff --git a/modApiServer/src/org/aion/api/server/ApiAion.java b/modApiServer/src/org/aion/api/server/ApiAion.java index 1879b486c8..fa9973b472 100644 --- a/modApiServer/src/org/aion/api/server/ApiAion.java +++ b/modApiServer/src/org/aion/api/server/ApiAion.java @@ -20,12 +20,10 @@ import org.aion.api.server.types.Fltr; import org.aion.api.server.types.SyncInfo; import org.aion.api.server.types.TxRecpt; -import org.aion.base.type.AionAddress; -import org.aion.base.type.ITransaction; -import org.aion.base.type.ITxReceipt; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.TypeConverter; +import org.aion.interfaces.tx.Transaction; +import org.aion.interfaces.tx.TxReceipt; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.ECKey; import org.aion.evtmgr.IEvent; import org.aion.evtmgr.IEventMgr; @@ -34,7 +32,8 @@ import org.aion.evtmgr.impl.evt.EventBlock; import org.aion.evtmgr.impl.evt.EventTx; import org.aion.mcf.blockchain.TxResponse; -import org.aion.vm.api.interfaces.Address; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.string.StringUtils; import org.aion.zero.impl.AionGenesis; import org.aion.zero.impl.AionHub; import org.aion.zero.impl.BlockContext; @@ -51,6 +50,7 @@ import org.aion.zero.types.AionTxReceipt; public abstract class ApiAion extends Api { + public static final int SYNC_TOLERANCE = 1; // these variables get accessed by the api worker threads. // need to guarantee one of: @@ -110,11 +110,11 @@ public void run() { } else if (e.getEventType() == IHandler.TYPE.TX0.getValue()) { if (e.getCallbackType() == EventTx.CALLBACK.PENDINGTXUPDATE0.getValue()) { pendingTxUpdate( - (ITxReceipt) e.getFuncArgs().get(0), + (TxReceipt) e.getFuncArgs().get(0), GETSTATE((int) e.getFuncArgs().get(1))); } else if (e.getCallbackType() == EventTx.CALLBACK.PENDINGTXRECEIVED0.getValue()) { - for (ITransaction tx : (List) e.getFuncArgs().get(0)) { + for (Transaction tx : (List) e.getFuncArgs().get(0)) { pendingTxReceived(tx); } } @@ -130,9 +130,9 @@ public void run() { protected abstract void onBlock(AionBlockSummary cbs); - protected abstract void pendingTxReceived(ITransaction _tx); + protected abstract void pendingTxReceived(Transaction _tx); - protected abstract void pendingTxUpdate(ITxReceipt _txRcpt, EventTx.STATE _state); + protected abstract void pendingTxUpdate(TxReceipt _txRcpt, EventTx.STATE _state); // General Level public byte getApiVersion() { @@ -145,7 +145,7 @@ protected Map getInstalledFltrs() { public String getCoinbase() { String coinbase = CfgAion.inst().getConsensus().getMinerAddress(); - return TypeConverter.toJsonHex(coinbase); + return StringUtils.toJsonHex(coinbase); } @Override @@ -218,12 +218,25 @@ protected Map.Entry getBlockWithTotalDifficulty(long blkN } } - protected SyncInfo getSync() { + /** + * Returns a {@link SyncInfo} object that reports whether or not syncing has started. + * + *

    Since a node is never really 'done' syncing, we consider a node to be done if it is within + * {@value SYNC_TOLERANCE} blocks of the network best block number. + * + * @param localBestBlockNumber The current block number of the local node. + * @param networkBestBlockNumber The current block number of the network. + * @return the syncing statistics. + */ + protected SyncInfo getSyncInfo(long localBestBlockNumber, long networkBestBlockNumber) { SyncInfo sync = new SyncInfo(); - sync.done = this.ac.isSyncComplete(); + + sync.done = localBestBlockNumber + SYNC_TOLERANCE >= networkBestBlockNumber; + sync.chainStartingBlkNumber = this.ac.getInitialStartingBlockNumber().orElse(0L); - sync.networkBestBlkNumber = this.ac.getNetworkBestBlockNumber().orElse(0L); - sync.chainBestBlkNumber = this.ac.getLocalBestBlockNumber().orElse(0L); + sync.chainBestBlkNumber = localBestBlockNumber; + sync.networkBestBlkNumber = networkBestBlockNumber; + return sync; } @@ -441,8 +454,7 @@ protected byte[] doCall(ArgTxCall _params) { } protected long estimateNrg(ArgTxCall params) { - Address fromAddr = - (params.getFrom().isEmptyAddress()) ? AionAddress.ZERO_ADDRESS() : params.getFrom(); + Address fromAddr = (params.getFrom() == null) ? Address.ZERO_ADDRESS() : params.getFrom(); AionTransaction tx = new AionTransaction( params.getNonce().toByteArray(), @@ -467,7 +479,7 @@ protected ApiTxResponse createContract(ArgTxCall _params) { Address from = _params.getFrom(); - if (from == null || from.isEmptyAddress()) { + if (from == null) { LOG.error(""); return (new ApiTxResponse(TxResponse.INVALID_FROM)); } @@ -485,7 +497,7 @@ protected ApiTxResponse createContract(ArgTxCall _params) { !(_params.getNonce().equals(BigInteger.ZERO)) ? _params.getNonce().toByteArray() : pendingState - .bestPendingStateNonce(AionAddress.wrap(key.getAddress())) + .bestPendingStateNonce(Address.wrap(key.getAddress())) .toByteArray(); AionTransaction tx = @@ -512,7 +524,7 @@ protected ApiTxResponse createContract(ArgTxCall _params) { // Transaction Level public BigInteger getBalance(String _address) { - return this.ac.getRepository().getBalance(AionAddress.wrap(_address)); + return this.ac.getRepository().getBalance(Address.wrap(_address)); } public BigInteger getBalance(Address _address) { @@ -520,7 +532,7 @@ public BigInteger getBalance(Address _address) { } public BigInteger getNonce(String _address) { - return this.ac.getRepository().getNonce(AionAddress.wrap(_address)); + return this.ac.getRepository().getNonce(Address.wrap(_address)); } public BigInteger getNonce(Address _address) { @@ -535,7 +547,7 @@ protected ApiTxResponse sendTransaction(ArgTxCall _params) { Address from = _params.getFrom(); - if (from == null || from.isEmptyAddress()) { + if (from == null) { LOG.error(""); return (new ApiTxResponse(TxResponse.INVALID_FROM)); } @@ -553,7 +565,7 @@ protected ApiTxResponse sendTransaction(ArgTxCall _params) { (!_params.getNonce().equals(BigInteger.ZERO)) ? _params.getNonce().toByteArray() : pendingState - .bestPendingStateNonce(AionAddress.wrap(key.getAddress())) + .bestPendingStateNonce(Address.wrap(key.getAddress())) .toByteArray(); AionTransaction tx = @@ -597,7 +609,7 @@ protected AionTransaction signTransaction(ArgTxCall _params, String _address) { LOG.error(""); return null; } else { - address = AionAddress.wrap(_address); + address = Address.wrap(_address); } ECKey key = getAccountKey(address.toString()); @@ -612,7 +624,7 @@ protected AionTransaction signTransaction(ArgTxCall _params, String _address) { (!_params.getNonce().equals(BigInteger.ZERO)) ? _params.getNonce().toByteArray() : pendingState - .bestPendingStateNonce(AionAddress.wrap(key.getAddress())) + .bestPendingStateNonce(Address.wrap(key.getAddress())) .toByteArray(); AionTransaction tx = @@ -651,8 +663,8 @@ protected String[] getBootNodes() { // } // private synchronized BigInteger getTxNonce(ECKey key, boolean add) { - // return add ? nm.getNonceAndAdd(AionAddress.wrap(key.getAddress())) : - // nm.getNonce(AionAddress.wrap(key.getAddress())); + // return add ? nm.getNonceAndAdd(Address.wrap(key.getAddress())) : + // nm.getNonce(Address.wrap(key.getAddress())); // } public boolean isMining() { diff --git a/modApiServer/src/org/aion/api/server/ApiTxResponse.java b/modApiServer/src/org/aion/api/server/ApiTxResponse.java index a5ba15092e..1ffa681265 100644 --- a/modApiServer/src/org/aion/api/server/ApiTxResponse.java +++ b/modApiServer/src/org/aion/api/server/ApiTxResponse.java @@ -1,7 +1,7 @@ package org.aion.api.server; import org.aion.mcf.blockchain.TxResponse; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; public class ApiTxResponse { diff --git a/modApiServer/src/org/aion/api/server/IApiAion.java b/modApiServer/src/org/aion/api/server/IApiAion.java index b018d9c547..9867c9d380 100644 --- a/modApiServer/src/org/aion/api/server/IApiAion.java +++ b/modApiServer/src/org/aion/api/server/IApiAion.java @@ -5,7 +5,7 @@ import org.aion.api.server.pb.TxWaitingMappingUpdate; import org.aion.api.server.types.Fltr; import org.aion.api.server.types.TxPendingStatus; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; import org.aion.zero.types.AionTxReceipt; public interface IApiAion { diff --git a/modApiServer/src/org/aion/api/server/nrgprice/INrgPriceAdvisor.java b/modApiServer/src/org/aion/api/server/nrgprice/INrgPriceAdvisor.java index 7224e6f509..3b99bbda79 100644 --- a/modApiServer/src/org/aion/api/server/nrgprice/INrgPriceAdvisor.java +++ b/modApiServer/src/org/aion/api/server/nrgprice/INrgPriceAdvisor.java @@ -1,9 +1,9 @@ package org.aion.api.server.nrgprice; -import org.aion.base.type.IBlock; -import org.aion.base.type.ITransaction; +import org.aion.interfaces.block.Block; +import org.aion.interfaces.tx.Transaction; -public interface INrgPriceAdvisor { +public interface INrgPriceAdvisor { /* Is the recommendation engine hungry for more data? * Recommendations prescribed by engine while hungry are left up to the engine itself */ diff --git a/modApiServer/src/org/aion/api/server/nrgprice/NrgPriceAdvisor.java b/modApiServer/src/org/aion/api/server/nrgprice/NrgPriceAdvisor.java index 85ec845d97..021fb8088b 100644 --- a/modApiServer/src/org/aion/api/server/nrgprice/NrgPriceAdvisor.java +++ b/modApiServer/src/org/aion/api/server/nrgprice/NrgPriceAdvisor.java @@ -1,9 +1,9 @@ package org.aion.api.server.nrgprice; -import org.aion.base.type.IBlock; -import org.aion.base.type.ITransaction; +import org.aion.interfaces.block.Block; +import org.aion.interfaces.tx.Transaction; -public abstract class NrgPriceAdvisor +public abstract class NrgPriceAdvisor implements INrgPriceAdvisor { protected long defaultPrice; diff --git a/modApiServer/src/org/aion/api/server/nrgprice/strategy/NrgBlockPrice.java b/modApiServer/src/org/aion/api/server/nrgprice/strategy/NrgBlockPrice.java index 805580e655..da48275dc4 100644 --- a/modApiServer/src/org/aion/api/server/nrgprice/strategy/NrgBlockPrice.java +++ b/modApiServer/src/org/aion/api/server/nrgprice/strategy/NrgBlockPrice.java @@ -4,10 +4,9 @@ import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import org.aion.api.server.nrgprice.NrgPriceAdvisor; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; -import org.aion.vm.api.interfaces.Address; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.types.AionTransaction; import org.slf4j.Logger; diff --git a/modApiServer/src/org/aion/api/server/nrgprice/strategy/NrgBlockPriceAveraging.java b/modApiServer/src/org/aion/api/server/nrgprice/strategy/NrgBlockPriceAveraging.java index 7c2a986b51..b933aee04a 100644 --- a/modApiServer/src/org/aion/api/server/nrgprice/strategy/NrgBlockPriceAveraging.java +++ b/modApiServer/src/org/aion/api/server/nrgprice/strategy/NrgBlockPriceAveraging.java @@ -5,10 +5,9 @@ import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import org.aion.api.server.nrgprice.NrgPriceAdvisor; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; -import org.aion.vm.api.interfaces.Address; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.types.AionTransaction; import org.slf4j.Logger; diff --git a/modApiServer/src/org/aion/api/server/pb/ApiAion0.java b/modApiServer/src/org/aion/api/server/pb/ApiAion0.java index e37f70880c..4218500c4d 100644 --- a/modApiServer/src/org/aion/api/server/pb/ApiAion0.java +++ b/modApiServer/src/org/aion/api/server/pb/ApiAion0.java @@ -1,7 +1,5 @@ package org.aion.api.server.pb; -import static org.aion.base.util.ByteUtil.EMPTY_BYTE_ARRAY; - import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import java.math.BigInteger; @@ -29,6 +27,8 @@ import org.aion.api.server.pb.Message.Funcs; import org.aion.api.server.pb.Message.Retcode; import org.aion.api.server.pb.Message.Servs; +import org.aion.api.server.rpc.RpcError; +import org.aion.api.server.rpc.RpcMsg; import org.aion.api.server.types.ArgTxCall; import org.aion.api.server.types.CompiledContr; import org.aion.api.server.types.EvtContract; @@ -39,15 +39,12 @@ import org.aion.api.server.types.TxPendingStatus; import org.aion.api.server.types.TxRecpt; import org.aion.api.server.types.TxRecptLg; -import org.aion.base.type.AionAddress; -import org.aion.base.type.Hash256; -import org.aion.base.type.IBlock; -import org.aion.base.type.ITransaction; -import org.aion.base.type.ITxReceipt; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.Hex; -import org.aion.base.util.TypeConverter; +import org.aion.interfaces.block.Block; +import org.aion.interfaces.tx.Transaction; +import org.aion.interfaces.tx.TxReceipt; +import org.aion.types.Address; + +import org.aion.types.ByteArrayWrapper; import org.aion.equihash.EquihashMiner; import org.aion.evtmgr.IEvent; import org.aion.evtmgr.IHandler; @@ -58,7 +55,10 @@ import org.aion.mcf.account.Keystore; import org.aion.p2p.INode; import org.aion.solidity.Abi; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Hash256; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.conversions.Hex; +import org.aion.util.string.StringUtils; import org.aion.vm.api.interfaces.IExecutionLog; import org.aion.zero.impl.AionBlockchainImpl; import org.aion.zero.impl.AionHub; @@ -73,6 +73,8 @@ import org.apache.commons.collections4.map.LRUMap; import org.json.JSONArray; +import static org.aion.util.bytes.ByteUtil.EMPTY_BYTE_ARRAY; + @SuppressWarnings("Duplicates") public class ApiAion0 extends ApiAion implements IApiAion { @@ -128,7 +130,7 @@ protected void onBlock(AionBlockSummary cbs) { contractAddress, ByteUtil.toHexString( lg))) { - IBlock + Block blk = (cbs) .getBlock(); @@ -177,7 +179,7 @@ protected void onBlock(AionBlockSummary cbs) { } } - protected void pendingTxReceived(ITransaction _tx) { + protected void pendingTxReceived(Transaction _tx) { installedFilters .values() .forEach( @@ -188,7 +190,7 @@ protected void pendingTxReceived(ITransaction _tx) { }); } - protected void pendingTxUpdate(ITxReceipt _txRcpt, EventTx.STATE _state) { + protected void pendingTxUpdate(TxReceipt _txRcpt, EventTx.STATE _state) { ByteArrayWrapper txHashW = ByteArrayWrapper.wrap( ((AionTxReceipt) _txRcpt).getTransaction().getTransactionHash()); @@ -246,8 +248,7 @@ protected void pendingTxUpdate(ITxReceipt _txRcpt, EventTx.STATE _state) { new TxWaitingMappingUpdate( txHashW, _state.getValue(), ((AionTxReceipt) _txRcpt))); } catch (InterruptedException e) { - LOG.error( - "ApiAion0.onPendingTransactionUpdate txWait.put exception", e.getMessage()); + LOG.error("ApiAion0.onPendingTransactionUpdate txWait.put exception", e); } } } @@ -399,7 +400,7 @@ public byte[] process(byte[] request, byte[] socketId) { .newBuilder() .setMinerAddr( ByteString.copyFrom( - TypeConverter.StringHexToByteArray(cb))) + StringUtils.StringHexToByteArray(cb))) .build(); byte[] retHeader = @@ -429,7 +430,7 @@ public byte[] process(byte[] request, byte[] socketId) { ArgTxCall params = new ArgTxCall( - AionAddress.wrap(req.getFrom().toByteArray()), + Address.wrap(req.getFrom().toByteArray()), null, Hex.decode(new String(bytes).substring(2)), BigInteger.ZERO, @@ -474,8 +475,7 @@ public byte[] process(byte[] request, byte[] socketId) { } } catch (Exception e) { - LOG.error( - "ApiAion0.process.ContractDeploy exception [{}] ", e.getMessage()); + LOG.error("ApiAion0.process.ContractDeploy exception [{}] ", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE, msgHash); } @@ -493,7 +493,7 @@ public byte[] process(byte[] request, byte[] socketId) { List accounts = this.getAccounts(); ArrayList al = new ArrayList<>(); for (String s : accounts) { - al.add(ByteString.copyFrom(TypeConverter.StringHexToByteArray(s))); + al.add(ByteString.copyFrom(StringUtils.StringHexToByteArray(s))); } Message.rsp_accounts rsp = Message.rsp_accounts.newBuilder().addAllAccout(al).build(); @@ -531,11 +531,11 @@ public byte[] process(byte[] request, byte[] socketId) { Message.req_unlockAccount req = Message.req_unlockAccount.parseFrom(data); result = this.unlockAccount( - AionAddress.wrap(req.getAccount().toByteArray()), + Address.wrap(req.getAccount().toByteArray()), req.getPassword(), req.getDuration()); } catch (InvalidProtocolBufferException e) { - LOG.error("ApiAion0.process.unlockAccount exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.unlockAccount exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -558,11 +558,11 @@ public byte[] process(byte[] request, byte[] socketId) { try { Message.req_getBalance req = Message.req_getBalance.parseFrom(data); - Address addr = AionAddress.wrap(req.getAddress().toByteArray()); + Address addr = Address.wrap(req.getAddress().toByteArray()); balance = this.getBalance(addr); } catch (InvalidProtocolBufferException e) { - LOG.error("ApiAion0.process.getbalance exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.getbalance exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -589,11 +589,11 @@ public byte[] process(byte[] request, byte[] socketId) { try { Message.req_getNonce req = Message.req_getNonce.parseFrom(data); - Address addr = AionAddress.wrap(req.getAddress().toByteArray()); + Address addr = Address.wrap(req.getAddress().toByteArray()); nonce = this.getNonce(addr); } catch (InvalidProtocolBufferException e) { - LOG.error("ApiAionA0.process.getNonce exception: [{}]", e.getMessage()); + LOG.error("ApiAionA0.process.getNonce exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Message.Retcode.r_fail_function_exception_VALUE); } @@ -626,8 +626,7 @@ public byte[] process(byte[] request, byte[] socketId) { ApiUtil.toReturnHeader(getApiVersion(), Retcode.r_success_VALUE); return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error( - "ApiAion0.process.getEnergyPrice exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.getEnergyPrice exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -700,7 +699,7 @@ public byte[] process(byte[] request, byte[] socketId) { } } catch (InvalidProtocolBufferException e) { - LOG.error("ApiAion0.process.compile exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.compile exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -776,7 +775,7 @@ public byte[] process(byte[] request, byte[] socketId) { } } catch (InvalidProtocolBufferException e) { - LOG.error("ApiAion0.process.compile exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.compile exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -796,8 +795,8 @@ public byte[] process(byte[] request, byte[] socketId) { ArgTxCall params = new ArgTxCall( - AionAddress.wrap(req.getFrom().toByteArray()), - AionAddress.wrap(req.getTo().toByteArray()), + Address.wrap(req.getFrom().toByteArray()), + Address.wrap(req.getTo().toByteArray()), req.getData().toByteArray(), new BigInteger(req.getNonce().toByteArray()), new BigInteger(req.getValue().toByteArray()), @@ -806,8 +805,7 @@ public byte[] process(byte[] request, byte[] socketId) { result = this.sendTransaction(params); } catch (InvalidProtocolBufferException e) { - LOG.error( - "ApiAion0.process.sendTransaction exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.sendTransaction exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE, msgHash); } @@ -825,7 +823,7 @@ public byte[] process(byte[] request, byte[] socketId) { Message.req_getCode req; try { req = Message.req_getCode.parseFrom(data); - Address to = AionAddress.wrap(req.getAddress().toByteArray()); + Address to = Address.wrap(req.getAddress().toByteArray()); byte[] code = this.getCode(to); if (code == null) { @@ -843,7 +841,7 @@ public byte[] process(byte[] request, byte[] socketId) { return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error("ApiAion0.process.getCode exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.getCode exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -876,8 +874,7 @@ public byte[] process(byte[] request, byte[] socketId) { .newBuilder() .setAddress( ByteString.copyFrom( - AionAddress.wrap(log.address) - .toBytes())) + Address.wrap(log.address).toBytes())) .setData( ByteString.copyFrom( ByteUtil.hexStringToBytes(log.data))) @@ -926,9 +923,7 @@ public byte[] process(byte[] request, byte[] socketId) { return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error( - "ApiAion0.process.getTransactionReceipt exception: [{}]", - e.getMessage()); + LOG.error("ApiAion0.process.getTransactionReceipt exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -946,8 +941,8 @@ public byte[] process(byte[] request, byte[] socketId) { try { req = Message.req_call.parseFrom(data); - Address from = AionAddress.wrap(req.getFrom().toByteArray()); - Address to = AionAddress.wrap(req.getTo().toByteArray()); + Address from = Address.wrap(req.getFrom().toByteArray()); + Address to = Address.wrap(req.getTo().toByteArray()); BigInteger value = new BigInteger(req.getValue().toByteArray()); byte[] d = req.getData().toByteArray(); @@ -972,7 +967,7 @@ public byte[] process(byte[] request, byte[] socketId) { return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error("ApiAion0.process.call exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.call exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -994,9 +989,7 @@ public byte[] process(byte[] request, byte[] socketId) { return createBlockMsg(blk); } catch (Exception e) { - LOG.error( - "ApiAion0.process.getBlockByNumber exception: [{}]", - e.getMessage()); + LOG.error("ApiAion0.process.getBlockByNumber exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1023,8 +1016,7 @@ public byte[] process(byte[] request, byte[] socketId) { AionBlock blk = this.getBlockByHash(hash); return createBlockMsg(blk); } catch (Exception e) { - LOG.error( - "ApiAion0.process.getBlockByHash exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.getBlockByHash exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1063,7 +1055,7 @@ public byte[] process(byte[] request, byte[] socketId) { } catch (Exception e) { LOG.error( "ApiAion0.process.getTransactionByBlockHashAndIndex exception: [{}]", - e.getMessage()); + e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1102,7 +1094,7 @@ public byte[] process(byte[] request, byte[] socketId) { } catch (Exception e) { LOG.error( "ApiAion0.process.getTransactionByBlockNumberAndIndex exception: [{}]", - e.getMessage()); + e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1144,7 +1136,7 @@ public byte[] process(byte[] request, byte[] socketId) { } catch (Exception e) { LOG.error( "ApiAion0.process.getBlockTransactionCountByNumber exception: [{}]", - e.getMessage()); + e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1162,7 +1154,7 @@ public byte[] process(byte[] request, byte[] socketId) { try { req = Message.req_getTransactionCount.parseFrom(data); long blkNr = req.getBlocknumber(); - Address addr = AionAddress.wrap(req.getAddress().toByteArray()); + Address addr = Address.wrap(req.getAddress().toByteArray()); if (blkNr < -1) { return ApiUtil.toReturnHeader( @@ -1186,9 +1178,7 @@ public byte[] process(byte[] request, byte[] socketId) { return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error( - "ApiAion0.process.getTransactionCount exception: [{}]", - e.getMessage()); + LOG.error("ApiAion0.process.getTransactionCount exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1229,9 +1219,7 @@ public byte[] process(byte[] request, byte[] socketId) { return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error( - "ApiAion0.process.getTransactionCount exception: [{}]", - e.getMessage()); + LOG.error("ApiAion0.process.getTransactionCount exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1268,9 +1256,7 @@ public byte[] process(byte[] request, byte[] socketId) { return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error( - "ApiAion0.process.getTransactionCount exception: [{}]", - e.getMessage()); + LOG.error("ApiAion0.process.getTransactionCount exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1310,8 +1296,7 @@ public byte[] process(byte[] request, byte[] socketId) { ApiUtil.toReturnHeader(getApiVersion(), Retcode.r_success_VALUE); return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error( - "ApiAion0.process.getActiveNodes exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.getActiveNodes exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1339,8 +1324,7 @@ public byte[] process(byte[] request, byte[] socketId) { ApiUtil.toReturnHeader(getApiVersion(), Retcode.r_success_VALUE); return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error( - "ApiAion0.process.getStaticNodes exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.getStaticNodes exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1362,8 +1346,7 @@ public byte[] process(byte[] request, byte[] socketId) { ApiUtil.toReturnHeader(getApiVersion(), Retcode.r_success_VALUE); return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error( - "ApiAion0.process.getSolcVersion exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.getSolcVersion exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1376,17 +1359,34 @@ public byte[] process(byte[] request, byte[] socketId) { } try { + Optional localBestBlockNumber = this.ac.getLocalBestBlockNumber(); + Optional networkBestBlockNumber = this.ac.getNetworkBestBlockNumber(); + + // Check that we actually have real values in our hands. + if (!localBestBlockNumber.isPresent()) { + LOG.error("Unable to determine the local node's best block number!"); + return ApiUtil.toReturnHeader(getApiVersion(), Retcode.r_fail_VALUE); + } + if (!networkBestBlockNumber.isPresent()) { + LOG.error("Unable to determine the network's best block number!"); + return ApiUtil.toReturnHeader(getApiVersion(), Retcode.r_fail_VALUE); + } + + SyncInfo syncInfo = + this.getSyncInfo( + localBestBlockNumber.get(), networkBestBlockNumber.get()); + Message.rsp_isSyncing rsp = Message.rsp_isSyncing .newBuilder() - .setSyncing(!this.getSync().done) + .setSyncing(!syncInfo.done) .build(); byte[] retHeader = ApiUtil.toReturnHeader(getApiVersion(), Retcode.r_success_VALUE); return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error("ApiAion0.process.syncing exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.syncing exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1398,15 +1398,30 @@ public byte[] process(byte[] request, byte[] socketId) { getApiVersion(), Retcode.r_fail_service_call_VALUE); } - SyncInfo sync = this.getSync(); + Optional localBestBlockNumber = this.ac.getLocalBestBlockNumber(); + Optional networkBestBlockNumber = this.ac.getNetworkBestBlockNumber(); + + // Check that we actually have real values in our hands. + if (!localBestBlockNumber.isPresent()) { + LOG.error("Unable to determine the local node's best block number!"); + return ApiUtil.toReturnHeader(getApiVersion(), Retcode.r_fail_VALUE); + } + if (!networkBestBlockNumber.isPresent()) { + LOG.error("Unable to determine the network's best block number!"); + return ApiUtil.toReturnHeader(getApiVersion(), Retcode.r_fail_VALUE); + } + + SyncInfo syncInfo = + this.getSyncInfo( + localBestBlockNumber.get(), networkBestBlockNumber.get()); try { Message.rsp_syncInfo rsp = Message.rsp_syncInfo .newBuilder() - .setChainBestBlock(sync.chainBestBlkNumber) - .setNetworkBestBlock(sync.networkBestBlkNumber) - .setSyncing(!sync.done) + .setChainBestBlock(syncInfo.chainBestBlkNumber) + .setNetworkBestBlock(syncInfo.networkBestBlkNumber) + .setSyncing(!syncInfo.done) .setMaxImportBlocks(24) .build(); @@ -1414,7 +1429,7 @@ public byte[] process(byte[] request, byte[] socketId) { ApiUtil.toReturnHeader(getApiVersion(), Retcode.r_success_VALUE); return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error("ApiAion0.process.syncInfo exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.syncInfo exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1449,7 +1464,7 @@ public byte[] process(byte[] request, byte[] socketId) { pKeyList.add(ByteString.copyFrom(pKey)); } - addressList.add(ByteString.copyFrom(AionAddress.wrap(addr).toBytes())); + addressList.add(ByteString.copyFrom(Address.wrap(addr).toBytes())); } Message.rsp_accountCreate rsp = @@ -1464,7 +1479,7 @@ public byte[] process(byte[] request, byte[] socketId) { return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error("ApiAion0.process.accountCreate exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.accountCreate exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1489,10 +1504,10 @@ public byte[] process(byte[] request, byte[] socketId) { Message.req_accountlock req = Message.req_accountlock.parseFrom(data); result = this.lockAccount( - AionAddress.wrap(req.getAccount().toByteArray()), + Address.wrap(req.getAccount().toByteArray()), req.getPassword()); } catch (InvalidProtocolBufferException e) { - LOG.error("ApiAion0.process.lockAccount exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.lockAccount exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1542,8 +1557,8 @@ public byte[] process(byte[] request, byte[] socketId) { ArgTxCall params = new ArgTxCall( - AionAddress.wrap(req.getFrom().toByteArray()), - AionAddress.wrap(req.getTo().toByteArray()), + Address.wrap(req.getFrom().toByteArray()), + Address.wrap(req.getTo().toByteArray()), req.getData().toByteArray(), BigInteger.ZERO, new BigInteger(req.getValue().toByteArray()), @@ -1552,7 +1567,7 @@ public byte[] process(byte[] request, byte[] socketId) { result = this.estimateNrg(params); } catch (InvalidProtocolBufferException e) { - LOG.error("ApiAion0.process.estimateNrg exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.estimateNrg exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE, msgHash); } @@ -1579,8 +1594,7 @@ public byte[] process(byte[] request, byte[] socketId) { try { req = Message.req_exportAccounts.parseFrom(data); } catch (Exception e) { - LOG.error( - "ApiAion0.process.exportAccounts exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.exportAccounts exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1590,7 +1604,7 @@ public byte[] process(byte[] request, byte[] socketId) { i < req.getKeyFileList().size() && i < ACCOUNT_CREATE_LIMIT; i++) { addrMap.put( - AionAddress.wrap(req.getKeyFile(i).getAddress().toByteArray()), + Address.wrap(req.getKeyFile(i).getAddress().toByteArray()), req.getKeyFile(i).getPassword()); } @@ -1640,7 +1654,7 @@ public byte[] process(byte[] request, byte[] socketId) { try { req = Message.req_importAccounts.parseFrom(data); } catch (Exception e) { - LOG.error("ApiAion0.process.importAccount exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.importAccount exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1694,8 +1708,7 @@ public byte[] process(byte[] request, byte[] socketId) { result = this.sendTransaction(encodedTx); } catch (Exception e) { - LOG.error( - "ApiAion0.process.rawTransaction exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.rawTransaction exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE, msgHash); } @@ -1758,7 +1771,7 @@ public byte[] process(byte[] request, byte[] socketId) { return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error("ApiAion0.process.eventRegister exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.eventRegister exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1811,8 +1824,7 @@ public byte[] process(byte[] request, byte[] socketId) { return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error( - "ApiAion0.process.eventDeregister exception: [{}]", e.getMessage()); + LOG.error("ApiAion0.process.eventDeregister exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -1865,9 +1877,7 @@ public byte[] process(byte[] request, byte[] socketId) { return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } } catch (Exception e) { - LOG.error( - "ApiAion0.process.getBlockDetailsByNumber exception: [{}]", - e.getMessage()); + LOG.error("ApiAion0.process.getBlockDetailsByNumber exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -2081,9 +2091,7 @@ public byte[] process(byte[] request, byte[] socketId) { ApiUtil.toReturnHeader(getApiVersion(), Retcode.r_success_VALUE); return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error( - "ApiAion0.process.getBlockDetailsByNumber exception: [{}]", - e.getMessage()); + LOG.error("ApiAion0.process.getBlockDetailsByNumber exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -2305,9 +2313,7 @@ public byte[] process(byte[] request, byte[] socketId) { ApiUtil.toReturnHeader(getApiVersion(), Retcode.r_success_VALUE); return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error( - "ApiAion0.process.getBlockDetailsByNumber exception: [{}]", - e.getMessage()); + LOG.error("ApiAion0.process.getBlockDetailsByNumber exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -2360,9 +2366,7 @@ public byte[] process(byte[] request, byte[] socketId) { return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } } catch (Exception e) { - LOG.error( - "ApiAion0.process.getBlockDetailsByLatest exception: [{}]", - e.getMessage()); + LOG.error("ApiAion0.process.getBlockDetailsByLatest exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -2415,9 +2419,7 @@ public byte[] process(byte[] request, byte[] socketId) { return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } } catch (Exception e) { - LOG.error( - "ApiAion0.process.getBlocksByLatest exception: [{}]", - e.getMessage()); + LOG.error("ApiAion0.process.getBlocksByLatest exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -2446,8 +2448,7 @@ public byte[] process(byte[] request, byte[] socketId) { a -> { BigInteger b = this.getBalance( - AionAddress.wrap( - a.toByteArray())); + Address.wrap(a.toByteArray())); Message.t_AccountDetail.Builder builder = Message.t_AccountDetail.newBuilder(); @@ -2479,9 +2480,7 @@ public byte[] process(byte[] request, byte[] socketId) { return ApiUtil.combineRetMsg(retHeader, rsp.toByteArray()); } catch (Exception e) { - LOG.error( - "ApiAion0.process.getBlockDetailsByNumber exception: [{}]", - e.getMessage()); + LOG.error("ApiAion0.process.getBlockDetailsByNumber exception: [{}]", e); return ApiUtil.toReturnHeader( getApiVersion(), Retcode.r_fail_function_exception_VALUE); } @@ -2654,7 +2653,7 @@ private Message.t_TxDetail getTxDetailsObj( log -> { List topics = new ArrayList<>(); for (int i = 0; i < log.getTopics().size(); i++) { - topics.add(TypeConverter.toJsonHex(log.getTopics().get(i))); + topics.add(StringUtils.toJsonHex(log.getTopics().get(i))); } return Message.t_LgEle @@ -2675,7 +2674,11 @@ private Message.t_TxDetail getTxDetailsObj( Message.t_TxDetail .newBuilder() .setData(ByteString.copyFrom(t.getData())) - .setTo(ByteString.copyFrom(t.getDestinationAddress().toBytes())) + .setTo( + ByteString.copyFrom( + t.getDestinationAddress() == null + ? EMPTY_BYTE_ARRAY + : t.getDestinationAddress().toBytes())) .setFrom(ByteString.copyFrom(t.getSenderAddress().toBytes())) .setNonce(ByteString.copyFrom(t.getNonce())) .setValue(ByteString.copyFrom(t.getValue())) @@ -2834,7 +2837,10 @@ block_timestamp bigint(64), + ByteUtil.toHexString(t.getSenderAddress().toBytes()) + "'," + "'" - + ByteUtil.toHexString(t.getDestinationAddress().toBytes()) + + ByteUtil.toHexString( + t.getDestinationAddress() == null + ? EMPTY_BYTE_ARRAY + : t.getDestinationAddress().toBytes()) + "'," + nrgConsumed + "," @@ -2925,7 +2931,7 @@ private List getRsp_getBlockDetails( .size(); i++) { topics.add( - TypeConverter + StringUtils .toJsonHex( log.getTopics() .get( @@ -2963,8 +2969,12 @@ private List getRsp_getBlockDetails( .getData())) .setTo( ByteString.copyFrom( - tx.getDestinationAddress() - .toBytes())) + tx + .getDestinationAddress() + == null + ? EMPTY_BYTE_ARRAY + : tx.getDestinationAddress() + .toBytes())) .setFrom( ByteString.copyFrom( tx.getSenderAddress() diff --git a/modApiServer/src/org/aion/api/server/pb/TxWaitingMappingUpdate.java b/modApiServer/src/org/aion/api/server/pb/TxWaitingMappingUpdate.java index 1e614236f3..b24e675917 100644 --- a/modApiServer/src/org/aion/api/server/pb/TxWaitingMappingUpdate.java +++ b/modApiServer/src/org/aion/api/server/pb/TxWaitingMappingUpdate.java @@ -1,6 +1,6 @@ package org.aion.api.server.pb; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; import org.aion.zero.types.AionTxReceipt; public class TxWaitingMappingUpdate { diff --git a/modApiServer/src/org/aion/api/server/rpc/ApiWeb3Aion.java b/modApiServer/src/org/aion/api/server/rpc/ApiWeb3Aion.java index d03d880a03..8cfa7ae872 100644 --- a/modApiServer/src/org/aion/api/server/rpc/ApiWeb3Aion.java +++ b/modApiServer/src/org/aion/api/server/rpc/ApiWeb3Aion.java @@ -1,8 +1,9 @@ package org.aion.api.server.rpc; import static java.util.stream.Collectors.toList; -import static org.aion.base.util.ByteUtil.hexStringToBytes; -import static org.aion.base.util.ByteUtil.toHexString; +import static org.aion.util.HexConvert.hexStringToBytes; +import static org.aion.util.bytes.ByteUtil.EMPTY_BYTE_ARRAY; +import static org.aion.util.conversions.Hex.toHexString; import com.github.benmanes.caffeine.cache.CacheLoader; import com.github.benmanes.caffeine.cache.Caffeine; @@ -20,6 +21,7 @@ import java.util.List; import java.util.ListIterator; import java.util.Map; +import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -39,15 +41,12 @@ import org.aion.api.server.types.SyncInfo; import org.aion.api.server.types.Tx; import org.aion.api.server.types.TxRecpt; -import org.aion.base.db.IRepository; -import org.aion.base.type.AionAddress; -import org.aion.base.type.Hash256; -import org.aion.base.type.ITransaction; -import org.aion.base.type.ITxReceipt; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.TypeConverter; -import org.aion.base.util.Utils; +import org.aion.interfaces.db.Repository; +import org.aion.interfaces.tx.Transaction; +import org.aion.interfaces.tx.TxReceipt; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.ECKey; import org.aion.crypto.HashUtil; import org.aion.evtmgr.IEventMgr; @@ -66,9 +65,10 @@ import org.aion.mcf.config.CfgTx; import org.aion.mcf.core.AccountState; import org.aion.mcf.core.ImportResult; -import org.aion.mcf.vm.types.DataWord; import org.aion.p2p.INode; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Hash256; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.string.StringUtils; import org.aion.vm.api.interfaces.IExecutionLog; import org.aion.zero.impl.AionBlockchainImpl; import org.aion.zero.impl.BlockContext; @@ -98,6 +98,8 @@ @SuppressWarnings({"Duplicates", "WeakerAccess"}) public class ApiWeb3Aion extends ApiAion { + private static final int SYNC_TOLERANCE = 1; + private final int OPS_RECENT_ENTITY_COUNT = 32; private final int OPS_RECENT_ENTITY_CACHE_TIME_SECONDS = 4; @@ -138,7 +140,7 @@ protected void onBlock(AionBlockSummary cbs) { } } - protected void pendingTxReceived(ITransaction _tx) { + protected void pendingTxReceived(Transaction _tx) { if (isFilterEnabled) { // not absolutely neccessary to do eviction on installedFilters here, since we're doing // it already @@ -156,13 +158,13 @@ protected void pendingTxReceived(ITransaction _tx) { "", f.getSize(), f.getType().name(), - TypeConverter.toJsonHex(_tx.getTransactionHash())); + StringUtils.toJsonHex(_tx.getTransactionHash())); } }); } } - protected void pendingTxUpdate(ITxReceipt _txRcpt, EventTx.STATE _state) { + protected void pendingTxUpdate(TxReceipt _txRcpt, EventTx.STATE _state) { // commenting this out because of lack support for old web3 client that we are using // TODO: re-enable this when we upgrade our web3 client /* @@ -248,7 +250,7 @@ public AionBlock load(ByteArrayWrapper blockHash) { .build( new CacheLoader<>() { public MinerStatsView load(String key) { // no checked exception - Address miner = new AionAddress(key); + Address miner = new Address(key); return new MinerStatsView( STRATUM_RECENT_BLK_COUNT, miner.toBytes()) .update(); @@ -309,7 +311,7 @@ public RpcMsg web3_sha3(Object _params) { } return new RpcMsg( - TypeConverter.toJsonHex(HashUtil.keccak256(ByteUtil.hexStringToBytes(_data)))); + StringUtils.toJsonHex(HashUtil.keccak256(ByteUtil.hexStringToBytes(_data)))); } public RpcMsg net_version() { @@ -329,23 +331,51 @@ public RpcMsg eth_protocolVersion() { return new RpcMsg(p2pProtocolVersion()); } + /** + * Returns an {@link RpcMsg} containing 'false' if the node is done syncing to the network + * (since a node is never really 'done' syncing, we consider a node to be done if it is within + * {@value SYNC_TOLERANCE} blocks of the network best block number). + * + *

    Otherwise, if the sync is still syncing, a {@link RpcMsg} is returned with some basic + * statistics relating to the sync: the block number the node was at when syncing began; the + * current block number of the node; the current block number of the network. + * + *

    If either the local block number or network block number cannot be determined, an {@link + * RpcMsg} is returned with an {@link RpcError#INTERNAL_ERROR} code and its 'result' will be a + * more descriptive string indicating what went wrong. + * + * @return the syncing statistics. + */ public RpcMsg eth_syncing() { - SyncInfo syncInfo = getSync(); - if (!syncInfo.done) { - JSONObject obj = new JSONObject(); - // create obj for when syncing is completed - obj.put( - "startingBlock", - new NumericalValue(syncInfo.chainStartingBlkNumber).toHexString()); - obj.put("currentBlock", new NumericalValue(syncInfo.chainBestBlkNumber).toHexString()); - obj.put( - "highestBlock", - new NumericalValue(syncInfo.networkBestBlkNumber).toHexString()); - return new RpcMsg(obj); - } else { - // create obj for when syncing is ongoing - return new RpcMsg(false); + Optional localBestBlockNumber = this.ac.getLocalBestBlockNumber(); + Optional networkBestBlockNumber = this.ac.getNetworkBestBlockNumber(); + + // Check that we actually have real values in our hands. + if (!localBestBlockNumber.isPresent()) { + return new RpcMsg( + "Unable to determine the local node's best block number!", + RpcError.INTERNAL_ERROR); + } + if (!networkBestBlockNumber.isPresent()) { + return new RpcMsg( + "Unable to determine the network's best block number!", + RpcError.INTERNAL_ERROR); } + + SyncInfo syncInfo = getSyncInfo(localBestBlockNumber.get(), networkBestBlockNumber.get()); + + return (syncInfo.done) ? new RpcMsg(false) : new RpcMsg(syncInfoToJson(syncInfo)); + } + + private JSONObject syncInfoToJson(SyncInfo syncInfo) { + JSONObject syncInfoAsJson = new JSONObject(); + syncInfoAsJson.put( + "startingBlock", new NumericalValue(syncInfo.chainStartingBlkNumber).toHexString()); + syncInfoAsJson.put( + "currentBlock", new NumericalValue(syncInfo.chainBestBlkNumber).toHexString()); + syncInfoAsJson.put( + "highestBlock", new NumericalValue(syncInfo.networkBestBlkNumber).toHexString()); + return syncInfoAsJson; } public RpcMsg eth_coinbase() { @@ -377,7 +407,7 @@ public RpcMsg eth_submitHashrate(Object _params) { } public RpcMsg eth_gasPrice() { - return new RpcMsg(TypeConverter.toJsonHex(getRecommendedNrgPrice())); + return new RpcMsg(StringUtils.toJsonHex(getRecommendedNrgPrice())); } public RpcMsg eth_accounts() { @@ -402,14 +432,14 @@ public RpcMsg eth_getBalance(Object _params) { return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid parameters"); } - Address address = new AionAddress(_address); + Address address = new Address(_address); String bnOrId = "latest"; if (!JSONObject.NULL.equals(_bnOrId)) { bnOrId = _bnOrId + ""; } - IRepository repo = getRepoByJsonBlockId(bnOrId); + Repository repo = getRepoByJsonBlockId(bnOrId); if (repo == null) // invalid bnOrId { return new RpcMsg( @@ -422,7 +452,7 @@ public RpcMsg eth_getBalance(Object _params) { } BigInteger balance = repo.getBalance(address); - return new RpcMsg(TypeConverter.toJsonHex(balance)); + return new RpcMsg(StringUtils.toJsonHex(balance)); } public RpcMsg eth_getStorageAt(Object _params) { @@ -441,17 +471,17 @@ public RpcMsg eth_getStorageAt(Object _params) { return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid parameters"); } - Address address = new AionAddress(_address); + Address address = new Address(_address); String bnOrId = "latest"; if (!JSONObject.NULL.equals(_bnOrId)) { bnOrId = _bnOrId + ""; } - DataWord key; + DataWordImpl key; try { - key = new DataWord(ByteUtil.hexStringToBytes(_index)); + key = new DataWordImpl(ByteUtil.hexStringToBytes(_index)); } catch (Exception e) { // invalid key LOG.debug("eth_getStorageAt: invalid storageIndex. Must be <= 16 bytes."); @@ -459,7 +489,7 @@ public RpcMsg eth_getStorageAt(Object _params) { null, RpcError.INVALID_PARAMS, "Invalid storageIndex. Must be <= 16 bytes."); } - IRepository repo = getRepoByJsonBlockId(bnOrId); + Repository repo = getRepoByJsonBlockId(bnOrId); if (repo == null) // invalid bnOrId { return new RpcMsg( @@ -473,7 +503,7 @@ public RpcMsg eth_getStorageAt(Object _params) { ByteArrayWrapper storageValue = repo.getStorageValue(address, key.toWrapper()); if (storageValue != null) { - return new RpcMsg(TypeConverter.toJsonHex(storageValue.getData())); + return new RpcMsg(StringUtils.toJsonHex(storageValue.getData())); } else { return new RpcMsg(null, RpcError.EXECUTION_ERROR, "Storage value not found"); } @@ -492,14 +522,14 @@ public RpcMsg eth_getTransactionCount(Object _params) { return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid parameters"); } - Address address = new AionAddress(_address); + Address address = new Address(_address); String bnOrId = "latest"; if (!JSONObject.NULL.equals(_bnOrId)) { bnOrId = _bnOrId + ""; } - IRepository repo = getRepoByJsonBlockId(bnOrId); + Repository repo = getRepoByJsonBlockId(bnOrId); if (repo == null) // invalid bnOrId { return new RpcMsg( @@ -511,7 +541,7 @@ public RpcMsg eth_getTransactionCount(Object _params) { + "State may have been pruned; please check your db pruning settings in the configuration file."); } - return new RpcMsg(TypeConverter.toJsonHex(repo.getNonce(address))); + return new RpcMsg(StringUtils.toJsonHex(repo.getNonce(address))); } public RpcMsg eth_getBlockTransactionCountByHash(Object _params) { @@ -531,7 +561,7 @@ public RpcMsg eth_getBlockTransactionCountByHash(Object _params) { } long n = b.getTransactionsList().size(); - return new RpcMsg(TypeConverter.toJsonHex(n)); + return new RpcMsg(StringUtils.toJsonHex(n)); } public RpcMsg eth_getBlockTransactionCountByNumber(Object _params) { @@ -552,7 +582,7 @@ public RpcMsg eth_getBlockTransactionCountByNumber(Object _params) { // pending transactions if (bn == BEST_PENDING_BLOCK) { long pendingTxCount = this.ac.getAionHub().getPendingState().getPendingTxSize(); - return new RpcMsg(TypeConverter.toJsonHex(pendingTxCount)); + return new RpcMsg(StringUtils.toJsonHex(pendingTxCount)); } AionBlock b = this.ac.getBlockchain().getBlockByNumber(bn); @@ -563,7 +593,7 @@ public RpcMsg eth_getBlockTransactionCountByNumber(Object _params) { List list = b.getTransactionsList(); long n = list.size(); - return new RpcMsg(TypeConverter.toJsonHex(n)); + return new RpcMsg(StringUtils.toJsonHex(n)); } public RpcMsg eth_getCode(Object _params) { @@ -579,14 +609,14 @@ public RpcMsg eth_getCode(Object _params) { return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid parameters"); } - Address address = new AionAddress(_address); + Address address = new Address(_address); String bnOrId = "latest"; if (!JSONObject.NULL.equals(_bnOrId)) { bnOrId = _bnOrId + ""; } - IRepository repo = getRepoByJsonBlockId(bnOrId); + Repository repo = getRepoByJsonBlockId(bnOrId); if (repo == null) // invalid bnOrId { return new RpcMsg( @@ -599,7 +629,7 @@ public RpcMsg eth_getCode(Object _params) { } byte[] code = repo.getCode(address); - return new RpcMsg(TypeConverter.toJsonHex(code)); + return new RpcMsg(StringUtils.toJsonHex(code)); } public RpcMsg eth_sign(Object _params) { @@ -615,7 +645,7 @@ public RpcMsg eth_sign(Object _params) { return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid parameters"); } - Address address = AionAddress.wrap(_address); + Address address = Address.wrap(_address); ECKey key = getAccountKey(address.toString()); if (key == null) { return new RpcMsg(null, RpcError.NOT_ALLOWED, "Account not unlocked."); @@ -625,7 +655,7 @@ public RpcMsg eth_sign(Object _params) { String message = "\u0019Aion Signed Message:\n" + _message.length() + _message; byte[] messageHash = HashUtil.keccak256(message.getBytes()); - return new RpcMsg(TypeConverter.toJsonHex(key.sign(messageHash).getSignature())); + return new RpcMsg(StringUtils.toJsonHex(key.sign(messageHash).getSignature())); } /** @@ -657,18 +687,23 @@ public RpcMsg eth_signTransaction(Object _params) { AionTransaction tx = signTransaction(txParams, _address); if (tx != null) { JSONObject obj = new JSONObject(); - obj.put("raw", TypeConverter.toJsonHex(tx.getEncoded())); + obj.put("raw", StringUtils.toJsonHex(tx.getEncoded())); JSONObject txObj = new JSONObject(); - txObj.put("nonce", TypeConverter.toJsonHex(tx.getNonce())); - txObj.put("gasPrice", TypeConverter.toJsonHex(tx.getEnergyPrice())); - txObj.put("nrgPrice", TypeConverter.toJsonHex(tx.getEnergyPrice())); - txObj.put("gas", TypeConverter.toJsonHex(tx.getEnergyLimit())); - txObj.put("nrg", TypeConverter.toJsonHex(tx.getEnergyLimit())); - txObj.put("to", TypeConverter.toJsonHex(tx.getDestinationAddress().toString())); - txObj.put("value", TypeConverter.toJsonHex(tx.getValue())); - txObj.put("input", TypeConverter.toJsonHex(tx.getData())); - txObj.put("hash", TypeConverter.toJsonHex(tx.getTransactionHash())); + txObj.put("nonce", StringUtils.toJsonHex(tx.getNonce())); + txObj.put("gasPrice", StringUtils.toJsonHex(tx.getEnergyPrice())); + txObj.put("nrgPrice", StringUtils.toJsonHex(tx.getEnergyPrice())); + txObj.put("gas", StringUtils.toJsonHex(tx.getEnergyLimit())); + txObj.put("nrg", StringUtils.toJsonHex(tx.getEnergyLimit())); + txObj.put( + "to", + StringUtils.toJsonHex( + tx.getDestinationAddress() == null + ? EMPTY_BYTE_ARRAY + : tx.getDestinationAddress().toBytes())); + txObj.put("value", StringUtils.toJsonHex(tx.getValue())); + txObj.put("input", StringUtils.toJsonHex(tx.getData())); + txObj.put("hash", StringUtils.toJsonHex(tx.getTransactionHash())); obj.put("tx", txObj); return new RpcMsg(obj); @@ -686,7 +721,7 @@ private RpcMsg processTxResponse(ApiTxResponse rsp) { case CACHED_NONCE: case ALREADY_SEALED: case REPAID: - return new RpcMsg(TypeConverter.toJsonHex(rsp.getTxHash())); + return new RpcMsg(StringUtils.toJsonHex(rsp.getTxHash())); case INVALID_TX: case INVALID_TX_NRG_PRICE: case INVALID_FROM: @@ -784,7 +819,7 @@ public RpcMsg eth_call(Object _params) { AionTxReceipt receipt = this.ac.callConstant(tx, b); - return new RpcMsg(TypeConverter.toJsonHex(receipt.getTransactionOutput())); + return new RpcMsg(StringUtils.toJsonHex(receipt.getTransactionOutput())); } public RpcMsg eth_estimateGas(Object _params) { @@ -1000,7 +1035,7 @@ public RpcMsg eth_getTransactionReceipt(Object _params) { return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid parameters"); } - byte[] txHash = TypeConverter.StringHexToByteArray(_hash); + byte[] txHash = StringUtils.StringHexToByteArray(_hash); TxRecpt r = getTransactionReceipt(txHash); // commenting this out because of lack support for old web3 client that we are using @@ -1168,7 +1203,7 @@ public RpcMsg eth_newFilter(Object _params) { long id = fltrIndex.getAndIncrement(); installedFilters.put(id, filter); - return new RpcMsg(TypeConverter.toJsonHex(id)); + return new RpcMsg(StringUtils.toJsonHex(id)); } public RpcMsg eth_newBlockFilter() { @@ -1178,7 +1213,7 @@ public RpcMsg eth_newBlockFilter() { long id = fltrIndex.getAndIncrement(); installedFilters.put(id, new FltrBlk()); - return new RpcMsg(TypeConverter.toJsonHex(id)); + return new RpcMsg(StringUtils.toJsonHex(id)); } public RpcMsg eth_newPendingTransactionFilter() { @@ -1188,7 +1223,7 @@ public RpcMsg eth_newPendingTransactionFilter() { long id = fltrIndex.getAndIncrement(); installedFilters.put(id, new FltrTx()); - return new RpcMsg(TypeConverter.toJsonHex(id)); + return new RpcMsg(StringUtils.toJsonHex(id)); } public RpcMsg eth_uninstallFilter(Object _params) { @@ -1206,7 +1241,7 @@ public RpcMsg eth_uninstallFilter(Object _params) { } return new RpcMsg( - installedFilters.remove(TypeConverter.StringHexToBigInteger(_id).longValue()) + installedFilters.remove(StringUtils.StringHexToBigInteger(_id).longValue()) != null); } @@ -1236,7 +1271,7 @@ public RpcMsg eth_getFilterChanges(Object _params) { return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid parameters"); } - long id = TypeConverter.StringHexToBigInteger(_id).longValue(); + long id = StringUtils.StringHexToBigInteger(_id).longValue(); Fltr filter = installedFilters.get(id); if (filter == null) { @@ -1310,7 +1345,7 @@ public RpcMsg personal_lockAccount(Object _params) { return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid parameters"); } - return new RpcMsg(lockAccount(AionAddress.wrap(_account), _password)); + return new RpcMsg(lockAccount(Address.wrap(_account), _password)); } public RpcMsg personal_newAccount(Object _params) { @@ -1325,7 +1360,7 @@ public RpcMsg personal_newAccount(Object _params) { String address = Keystore.create(_password); - return new RpcMsg(TypeConverter.toJsonHex(address)); + return new RpcMsg(StringUtils.toJsonHex(address)); } /* ------------------------------------------------------------------------- @@ -1814,7 +1849,7 @@ public RpcMsg ops_getAccountState(Object _params) { Address address; try { - address = new AionAddress(_address); + address = new Address(_address); } catch (Exception e) { return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid address provided."); } @@ -1834,8 +1869,8 @@ public RpcMsg ops_getAccountState(Object _params) { JSONObject response = new JSONObject(); response.put("address", address.toString()); response.put("blockNumber", latestBlkNum); - response.put("balance", TypeConverter.toJsonHex(balance)); - response.put("nonce", TypeConverter.toJsonHex(nonce)); + response.put("balance", StringUtils.toJsonHex(balance)); + response.put("nonce", StringUtils.toJsonHex(nonce)); return new RpcMsg(response); } @@ -2021,14 +2056,14 @@ ChainHeadView update() { /* if (hashQueue.peekFirst() != null) { - System.out.println("[" + 0 + "]: " + TypeConverter.toJsonHex(hashQueue.peekFirst()) + " - " + blocks.get(hashQueue.peekFirst()).getNumber()); + System.out.println("[" + 0 + "]: " + StringUtils.toJsonHex(hashQueue.peekFirst()) + " - " + blocks.get(hashQueue.peekFirst()).getNumber()); System.out.println("----------------------------------------------------------"); System.out.println("isParentHashMatch? " + FastByteComparisons.equal(hashQueue.peekFirst(), blk.getParentHash())); System.out.println("blk.getNumber() " + blk.getNumber()); } System.out.println("blkNum: " + blk.getNumber() + - " parentHash: " + TypeConverter.toJsonHex(blk.getParentHash()) + - " blkHash: " + TypeConverter.toJsonHex(blk.getHash())); + " parentHash: " + StringUtils.toJsonHex(blk.getParentHash()) + + " blkHash: " + StringUtils.toJsonHex(blk.getHash())); */ while (!Arrays.equals(hashQueue.peekFirst(), blk.getParentHash()) @@ -2040,8 +2075,8 @@ ChainHeadView update() { itr++; /* System.out.println("blkNum: " + blk.getNumber() + - " parentHash: " + TypeConverter.toJsonHex(blk.getParentHash()) + - " blkHash: " + TypeConverter.toJsonHex(blk.getHash())); + " parentHash: " + StringUtils.toJsonHex(blk.getParentHash()) + + " blkHash: " + StringUtils.toJsonHex(blk.getHash())); */ } @@ -2071,10 +2106,10 @@ ChainHeadView update() { } /* - System.out.println("[" + 0 + "]: " + TypeConverter.toJsonHex(hashQueue.peekFirst()) + " - " + blocks.get(hashQueue.peekFirst()).getNumber()); + System.out.println("[" + 0 + "]: " + StringUtils.toJsonHex(hashQueue.peekFirst()) + " - " + blocks.get(hashQueue.peekFirst()).getNumber()); System.out.println("----------------------------------------------------------"); for (int i = hashQueue.size() - 1; i >= 0; i--) { - System.out.println("[" + i + "]: " + TypeConverter.toJsonHex(hashQueue.get(i)) + " - " + blocks.get(hashQueue.get(i)).getNumber()); + System.out.println("[" + i + "]: " + StringUtils.toJsonHex(hashQueue.get(i)) + " - " + blocks.get(hashQueue.get(i)).getNumber()); } */ this.response = buildResponse(); @@ -2129,7 +2164,7 @@ public RpcMsg ops_getTransaction(Object _params) { return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid parameters"); } - byte[] txHash = TypeConverter.StringHexToByteArray(_hash); + byte[] txHash = StringUtils.StringHexToByteArray(_hash); if (txHash == null) { return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid parameters"); @@ -2156,26 +2191,31 @@ public RpcMsg ops_getTransaction(Object _params) { JSONObject result = new JSONObject(); result.put("timestampVal", block.getTimestamp()); - result.put("transactionHash", TypeConverter.toJsonHex(tx.getTransactionHash())); + result.put("transactionHash", StringUtils.toJsonHex(tx.getTransactionHash())); result.put("blockNumber", block.getNumber()); - result.put("blockHash", TypeConverter.toJsonHex(block.getHash())); - result.put("nonce", TypeConverter.toJsonHex(tx.getNonce())); - result.put("fromAddr", TypeConverter.toJsonHex(tx.getSenderAddress().toBytes())); - result.put("toAddr", TypeConverter.toJsonHex(tx.getDestinationAddress().toBytes())); - result.put("value", TypeConverter.toJsonHex(tx.getValue())); + result.put("blockHash", StringUtils.toJsonHex(block.getHash())); + result.put("nonce", StringUtils.toJsonHex(tx.getNonce())); + result.put("fromAddr", StringUtils.toJsonHex(tx.getSenderAddress().toBytes())); + result.put( + "toAddr", + StringUtils.toJsonHex( + tx.getDestinationAddress() == null + ? EMPTY_BYTE_ARRAY + : tx.getDestinationAddress().toBytes())); + result.put("value", StringUtils.toJsonHex(tx.getValue())); result.put("nrgPrice", tx.getEnergyPrice()); result.put("nrgConsumed", txInfo.getReceipt().getEnergyUsed()); - result.put("data", TypeConverter.toJsonHex(tx.getData())); + result.put("data", StringUtils.toJsonHex(tx.getData())); result.put("transactionIndex", txInfo.getIndex()); JSONArray logs = new JSONArray(); for (IExecutionLog l : txInfo.getReceipt().getLogInfoList()) { JSONObject log = new JSONObject(); log.put("address", l.getSourceAddress().toString()); - log.put("data", TypeConverter.toJsonHex(l.getData())); + log.put("data", StringUtils.toJsonHex(l.getData())); JSONArray topics = new JSONArray(); for (byte[] topic : l.getTopics()) { - topics.put(TypeConverter.toJsonHex(topic)); + topics.put(StringUtils.toJsonHex(topic)); } log.put("topics", topics); logs.put(log); @@ -2246,26 +2286,26 @@ public RpcMsg ops_getBlock(Object _params) { blk.put("blockNumber", block.getNumber()); blk.put("numTransactions", block.getTransactionsList().size()); - blk.put("blockHash", TypeConverter.toJsonHex(block.getHash())); - blk.put("parentHash", TypeConverter.toJsonHex(block.getParentHash())); - blk.put("minerAddress", TypeConverter.toJsonHex(block.getCoinbase().toBytes())); + blk.put("blockHash", StringUtils.toJsonHex(block.getHash())); + blk.put("parentHash", StringUtils.toJsonHex(block.getParentHash())); + blk.put("minerAddress", StringUtils.toJsonHex(block.getCoinbase().toBytes())); - blk.put("receiptTxRoot", TypeConverter.toJsonHex(block.getReceiptsRoot())); - blk.put("txTrieRoot", TypeConverter.toJsonHex(block.getTxTrieRoot())); - blk.put("stateRoot", TypeConverter.toJsonHex(block.getStateRoot())); + blk.put("receiptTxRoot", StringUtils.toJsonHex(block.getReceiptsRoot())); + blk.put("txTrieRoot", StringUtils.toJsonHex(block.getTxTrieRoot())); + blk.put("stateRoot", StringUtils.toJsonHex(block.getStateRoot())); - blk.put("difficulty", TypeConverter.toJsonHex(block.getDifficulty())); + blk.put("difficulty", StringUtils.toJsonHex(block.getDifficulty())); blk.put("totalDifficulty", totalDiff.toString(16)); - blk.put("nonce", TypeConverter.toJsonHex(block.getNonce())); + blk.put("nonce", StringUtils.toJsonHex(block.getNonce())); blk.put("blockReward", blkReward); blk.put("nrgConsumed", block.getNrgConsumed()); blk.put("nrgLimit", block.getNrgLimit()); blk.put("size", block.size()); - blk.put("bloom", TypeConverter.toJsonHex(block.getLogBloom())); - blk.put("extraData", TypeConverter.toJsonHex(block.getExtraData())); - blk.put("solution", TypeConverter.toJsonHex(block.getHeader().getSolution())); + blk.put("bloom", StringUtils.toJsonHex(block.getLogBloom())); + blk.put("extraData", StringUtils.toJsonHex(block.getExtraData())); + blk.put("solution", StringUtils.toJsonHex(block.getHeader().getSolution())); JSONObject result = new JSONObject(); result.put("blk", blk); @@ -2275,10 +2315,14 @@ public RpcMsg ops_getBlock(Object _params) { for (AionTransaction tx : block.getTransactionsList()) { // transactionHash, fromAddr, toAddr, value, timestampVal, blockNumber, blockHash JSONArray t = new JSONArray(); - t.put(TypeConverter.toJsonHex(tx.getTransactionHash())); - t.put(TypeConverter.toJsonHex(tx.getSenderAddress().toBytes())); - t.put(TypeConverter.toJsonHex(tx.getDestinationAddress().toBytes())); - t.put(TypeConverter.toJsonHex(tx.getValue())); + t.put(StringUtils.toJsonHex(tx.getTransactionHash())); + t.put(StringUtils.toJsonHex(tx.getSenderAddress().toBytes())); + t.put( + StringUtils.toJsonHex( + tx.getDestinationAddress() == null + ? EMPTY_BYTE_ARRAY + : tx.getDestinationAddress().toBytes())); + t.put(StringUtils.toJsonHex(tx.getValue())); t.put(block.getTimestamp()); t.put(block.getNumber()); @@ -2304,7 +2348,7 @@ public RpcMsg ops_getTransactionReceiptByTransactionHash(Object _params) { return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid parameters"); } - byte[] transactionHash = TypeConverter.StringHexToByteArray(_transactionHash); + byte[] transactionHash = StringUtils.StringHexToByteArray(_transactionHash); AionTxInfo info = this.ac.getAionHub().getBlockchain().getTransactionInfo(transactionHash); if (info == null) { @@ -2333,8 +2377,8 @@ public RpcMsg ops_getTransactionReceiptByTransactionAndBlockHash(Object _params) return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid parameters"); } - byte[] transactionHash = TypeConverter.StringHexToByteArray(_transactionHash); - byte[] blockHash = TypeConverter.StringHexToByteArray(_blockHash); + byte[] transactionHash = StringUtils.StringHexToByteArray(_transactionHash); + byte[] blockHash = StringUtils.StringHexToByteArray(_blockHash); // cast will cause issues after the PoW refactor goes in AionBlockchainImpl chain = (AionBlockchainImpl) this.ac.getAionHub().getBlockchain(); @@ -2366,7 +2410,7 @@ public RpcMsg ops_getTransactionReceiptListByBlockHash(Object _params) { return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid parameters"); } - byte[] blockHash = TypeConverter.StringHexToByteArray(_blockHash); + byte[] blockHash = StringUtils.StringHexToByteArray(_blockHash); if (blockHash.length != 32) { return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid parameters"); @@ -2378,7 +2422,10 @@ public RpcMsg ops_getTransactionReceiptListByBlockHash(Object _params) { b = blockCache.get(new ByteArrayWrapper(blockHash)); } catch (Exception e) { // Catch errors if send an incorrect tx hash - return new RpcMsg(null, RpcError.INVALID_REQUEST, "Invalid Request" + e.getMessage()); + return new RpcMsg( + null, + RpcError.INVALID_REQUEST, + "Invalid Request " + e + " " + e.getMessage() != null ? e.getMessage() : ""); } // cast will cause issues after the PoW refactor goes in @@ -2503,7 +2550,7 @@ public RpcMsg stratum_validateaddress(Object _params) { JSONObject obj = new JSONObject(); - obj.put("isvalid", Utils.isValidAddress(_address)); + obj.put("isvalid", StringUtils.isValidAddress(_address)); obj.put("address", _address + ""); obj.put("ismine", Keystore.exist(_address)); return new RpcMsg(obj); @@ -2747,14 +2794,14 @@ MinerStatsView update() { /* if (hashQueue.peekFirst() != null) { - System.out.println("[" + 0 + "]: " + TypeConverter.toJsonHex(hashQueue.peekFirst()) + " - " + blocks.get(hashQueue.peekFirst()).getNumber()); + System.out.println("[" + 0 + "]: " + StringUtils.toJsonHex(hashQueue.peekFirst()) + " - " + blocks.get(hashQueue.peekFirst()).getNumber()); System.out.println("----------------------------------------------------------"); System.out.println("isParentHashMatch? " + FastByteComparisons.equal(hashQueue.peekFirst(), blk.getParentHash())); System.out.println("blk.getNumber() " + blk.getNumber()); } System.out.println("blkNum: " + blk.getNumber() + - " parentHash: " + TypeConverter.toJsonHex(blk.getParentHash()) + - " blkHash: " + TypeConverter.toJsonHex(blk.getHash())); + " parentHash: " + StringUtils.toJsonHex(blk.getParentHash()) + + " blkHash: " + StringUtils.toJsonHex(blk.getHash())); */ while (!Arrays.equals(hashQueue.peekFirst(), blk.getParentHash()) @@ -2766,8 +2813,8 @@ MinerStatsView update() { itr++; /* System.out.println("blkNum: " + blk.getNumber() + - " parentHash: " + TypeConverter.toJsonHex(blk.getParentHash()) + - " blkHash: " + TypeConverter.toJsonHex(blk.getHash())); + " parentHash: " + StringUtils.toJsonHex(blk.getParentHash()) + + " blkHash: " + StringUtils.toJsonHex(blk.getHash())); */ } @@ -2791,10 +2838,10 @@ MinerStatsView update() { } /* - System.out.println("[" + 0 + "]: " + TypeConverter.toJsonHex(hashQueue.peekFirst()) + " - " + blocks.get(hashQueue.peekFirst()).getNumber()); + System.out.println("[" + 0 + "]: " + StringUtils.toJsonHex(hashQueue.peekFirst()) + " - " + blocks.get(hashQueue.peekFirst()).getNumber()); System.out.println("----------------------------------------------------------"); for (int i = hashQueue.size() - 1; i >= 0; i--) { - System.out.println("[" + i + "]: " + TypeConverter.toJsonHex(hashQueue.get(i)) + " - " + blocks.get(hashQueue.get(i)).getNumber()); + System.out.println("[" + i + "]: " + StringUtils.toJsonHex(hashQueue.get(i)) + " - " + blocks.get(hashQueue.get(i)).getNumber()); } */ this.response = buildResponse(); @@ -2832,7 +2879,7 @@ public RpcMsg stratum_getMinerStats(Object _params) { // potential bug introduced by .getSnapshotTo() // comment out until resolved - private IRepository getRepoByJsonBlockId(String _bnOrId) { + private Repository getRepoByJsonBlockId(String _bnOrId) { Long bn = parseBnOrId(_bnOrId); if (bn == null) { @@ -2876,7 +2923,7 @@ private Long parseBnOrId(String _bnOrId) { Long ret; if (_bnOrId.startsWith("0x")) { - ret = TypeConverter.StringHexToBigInteger(_bnOrId).longValue(); + ret = StringUtils.StringHexToBigInteger(_bnOrId).longValue(); } else { ret = Long.parseLong(_bnOrId); } diff --git a/modApiServer/src/org/aion/api/server/types/ArgFltr.java b/modApiServer/src/org/aion/api/server/types/ArgFltr.java index 5c3b2ddf90..85e674516a 100644 --- a/modApiServer/src/org/aion/api/server/types/ArgFltr.java +++ b/modApiServer/src/org/aion/api/server/types/ArgFltr.java @@ -2,8 +2,8 @@ import java.util.ArrayList; import java.util.List; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; +import org.aion.types.Address; +import org.aion.util.bytes.ByteUtil; import org.json.JSONArray; import org.json.JSONObject; @@ -39,10 +39,10 @@ public static ArgFltr fromJSON(final JSONObject json) { if (addressList == null) { // let the address constructor do the validation on the string // it will throw if user passes invalid address - address.add((new AionAddress(json.optString("address", null))).toBytes()); + address.add((new Address(json.optString("address", null))).toBytes()); } else { for (int i = 0; i < addressList.length(); i++) { - address.add((new AionAddress(addressList.optString(i, null))).toBytes()); + address.add((new Address(addressList.optString(i, null))).toBytes()); } } } diff --git a/modApiServer/src/org/aion/api/server/types/ArgTxCall.java b/modApiServer/src/org/aion/api/server/types/ArgTxCall.java index d50d8f8374..e3812a23d5 100644 --- a/modApiServer/src/org/aion/api/server/types/ArgTxCall.java +++ b/modApiServer/src/org/aion/api/server/types/ArgTxCall.java @@ -4,13 +4,13 @@ import static org.aion.mcf.vm.Constants.NRG_TRANSACTION_DEFAULT; import java.math.BigInteger; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.TypeConverter; -import org.aion.base.vm.VirtualMachineSpecs; + +import org.aion.types.Address; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; -import org.aion.vm.api.interfaces.Address; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.string.StringUtils; +import org.aion.mcf.tx.TransactionTypes; import org.json.JSONObject; import org.slf4j.Logger; @@ -39,15 +39,7 @@ public ArgTxCall( final BigInteger _value, final long _nrg, final long _nrgPrice) { - this( - _from, - _to, - _data, - _nonce, - _value, - _nrg, - _nrgPrice, - VirtualMachineSpecs.FVM_DEFAULT_TX_TYPE); + this(_from, _to, _data, _nonce, _value, _nrg, _nrgPrice, TransactionTypes.DEFAULT); } public ArgTxCall( @@ -71,9 +63,13 @@ public ArgTxCall( public static ArgTxCall fromJSON(final JSONObject _jsonObj, long defaultNrgPrice) { try { - Address from = - AionAddress.wrap(ByteUtil.hexStringToBytes(_jsonObj.optString("from", ""))); - Address to = AionAddress.wrap(ByteUtil.hexStringToBytes(_jsonObj.optString("to", ""))); + + String fromStr = _jsonObj.optString("from", ""); + Address from = fromStr.equals("") ? null : Address.wrap(ByteUtil.hexStringToBytes(fromStr)); + + String toStr = _jsonObj.optString("to", ""); + Address to = toStr.equals("") ? null : Address.wrap(ByteUtil.hexStringToBytes(toStr)); + byte[] data = ByteUtil.hexStringToBytes(_jsonObj.optString("data", "")); byte type = ByteUtil.hexStringToBytes(_jsonObj.optString("type", "0x1"))[0]; @@ -81,29 +77,29 @@ public static ArgTxCall fromJSON(final JSONObject _jsonObj, long defaultNrgPrice String valueStr = _jsonObj.optString("value", "0x0"); BigInteger nonce = nonceStr.contains("0x") - ? TypeConverter.StringHexToBigInteger(nonceStr) - : TypeConverter.StringNumberAsBigInt(nonceStr); + ? StringUtils.StringHexToBigInteger(nonceStr) + : StringUtils.StringNumberAsBigInt(nonceStr); BigInteger value = valueStr.contains("0x") - ? TypeConverter.StringHexToBigInteger(valueStr) - : TypeConverter.StringNumberAsBigInt(valueStr); + ? StringUtils.StringHexToBigInteger(valueStr) + : StringUtils.StringNumberAsBigInt(valueStr); String nrgStr = _jsonObj.optString("gas", null); String nrgPriceStr = _jsonObj.optString("gasPrice", null); - long nrg = to.isEmptyAddress() ? NRG_CREATE_CONTRACT_DEFAULT : NRG_TRANSACTION_DEFAULT; + long nrg = to == null ? NRG_CREATE_CONTRACT_DEFAULT : NRG_TRANSACTION_DEFAULT; if (nrgStr != null) nrg = nrgStr.contains("0x") - ? TypeConverter.StringHexToBigInteger(nrgStr).longValue() - : TypeConverter.StringNumberAsBigInt(nrgStr).longValue(); + ? StringUtils.StringHexToBigInteger(nrgStr).longValue() + : StringUtils.StringNumberAsBigInt(nrgStr).longValue(); long nrgPrice = defaultNrgPrice; if (nrgPriceStr != null) nrgPrice = nrgPriceStr.contains("0x") - ? TypeConverter.StringHexToBigInteger(nrgPriceStr).longValue() - : TypeConverter.StringNumberAsBigInt(nrgPriceStr).longValue(); + ? StringUtils.StringHexToBigInteger(nrgPriceStr).longValue() + : StringUtils.StringNumberAsBigInt(nrgPriceStr).longValue(); return new ArgTxCall(from, to, data, nonce, value, nrg, nrgPrice, type); } catch (Exception e) { diff --git a/modApiServer/src/org/aion/api/server/types/Blk.java b/modApiServer/src/org/aion/api/server/types/Blk.java index e40fdeb634..fc76816337 100644 --- a/modApiServer/src/org/aion/api/server/types/Blk.java +++ b/modApiServer/src/org/aion/api/server/types/Blk.java @@ -1,9 +1,12 @@ package org.aion.api.server.types; +import static org.aion.util.bytes.ByteUtil.EMPTY_BYTE_ARRAY; + import java.math.BigInteger; import java.util.List; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.TypeConverter; + +import org.aion.util.bytes.ByteUtil; +import org.aion.util.string.StringUtils; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.types.AionTransaction; import org.json.JSONArray; @@ -23,29 +26,29 @@ public static Object AionBlockToJson( JSONObject obj = new JSONObject(); obj.put("number", block.getNumber()); - obj.put("hash", TypeConverter.toJsonHex(block.getHash())); - obj.put("parentHash", TypeConverter.toJsonHex(block.getParentHash())); - obj.put("logsBloom", TypeConverter.toJsonHex(block.getLogBloom())); - obj.put("transactionsRoot", TypeConverter.toJsonHex(block.getTxTrieRoot())); - obj.put("stateRoot", TypeConverter.toJsonHex(block.getStateRoot())); + obj.put("hash", StringUtils.toJsonHex(block.getHash())); + obj.put("parentHash", StringUtils.toJsonHex(block.getParentHash())); + obj.put("logsBloom", StringUtils.toJsonHex(block.getLogBloom())); + obj.put("transactionsRoot", StringUtils.toJsonHex(block.getTxTrieRoot())); + obj.put("stateRoot", StringUtils.toJsonHex(block.getStateRoot())); obj.put( "receiptsRoot", - TypeConverter.toJsonHex( + StringUtils.toJsonHex( block.getReceiptsRoot() == null ? new byte[0] : block.getReceiptsRoot())); - obj.put("difficulty", TypeConverter.toJsonHex(block.getDifficulty())); - obj.put("totalDifficulty", TypeConverter.toJsonHex(totalDifficulty)); + obj.put("difficulty", StringUtils.toJsonHex(block.getDifficulty())); + obj.put("totalDifficulty", StringUtils.toJsonHex(totalDifficulty)); // TODO: this is coinbase, miner, or minerAddress? - obj.put("miner", TypeConverter.toJsonHex(block.getCoinbase().toString())); - obj.put("timestamp", TypeConverter.toJsonHex(block.getTimestamp())); - obj.put("nonce", TypeConverter.toJsonHex(block.getNonce())); - obj.put("solution", TypeConverter.toJsonHex(block.getHeader().getSolution())); - obj.put("gasUsed", TypeConverter.toJsonHex(block.getHeader().getEnergyConsumed())); - obj.put("gasLimit", TypeConverter.toJsonHex(block.getHeader().getEnergyLimit())); - obj.put("nrgUsed", TypeConverter.toJsonHex(block.getHeader().getEnergyConsumed())); - obj.put("nrgLimit", TypeConverter.toJsonHex(block.getHeader().getEnergyLimit())); + obj.put("miner", StringUtils.toJsonHex(block.getCoinbase().toString())); + obj.put("timestamp", StringUtils.toJsonHex(block.getTimestamp())); + obj.put("nonce", StringUtils.toJsonHex(block.getNonce())); + obj.put("solution", StringUtils.toJsonHex(block.getHeader().getSolution())); + obj.put("gasUsed", StringUtils.toJsonHex(block.getHeader().getEnergyConsumed())); + obj.put("gasLimit", StringUtils.toJsonHex(block.getHeader().getEnergyLimit())); + obj.put("nrgUsed", StringUtils.toJsonHex(block.getHeader().getEnergyConsumed())); + obj.put("nrgLimit", StringUtils.toJsonHex(block.getHeader().getEnergyLimit())); // - obj.put("extraData", TypeConverter.toJsonHex(block.getExtraData())); + obj.put("extraData", StringUtils.toJsonHex(block.getExtraData())); obj.put("size", new NumericalValue(block.size()).toHexString()); JSONArray jsonTxs = new JSONArray(); @@ -57,24 +60,29 @@ public static Object AionBlockToJson( jsonTx.put( "contractAddress", (tx.getContractAddress() != null) - ? TypeConverter.toJsonHex(tx.getContractAddress().toString()) + ? StringUtils.toJsonHex(tx.getContractAddress().toString()) : null); - jsonTx.put("hash", TypeConverter.toJsonHex(tx.getTransactionHash())); + jsonTx.put("hash", StringUtils.toJsonHex(tx.getTransactionHash())); jsonTx.put("transactionIndex", i); - jsonTx.put("value", TypeConverter.toJsonHex(tx.getValue())); + jsonTx.put("value", StringUtils.toJsonHex(tx.getValue())); jsonTx.put("nrg", tx.getEnergyLimit()); - jsonTx.put("nrgPrice", TypeConverter.toJsonHex(tx.getEnergyPrice())); + jsonTx.put("nrgPrice", StringUtils.toJsonHex(tx.getEnergyPrice())); jsonTx.put("gas", tx.getEnergyLimit()); - jsonTx.put("gasPrice", TypeConverter.toJsonHex(tx.getEnergyPrice())); + jsonTx.put("gasPrice", StringUtils.toJsonHex(tx.getEnergyPrice())); jsonTx.put("nonce", ByteUtil.byteArrayToLong(tx.getNonce())); - jsonTx.put("from", TypeConverter.toJsonHex(tx.getSenderAddress().toString())); - jsonTx.put("to", TypeConverter.toJsonHex(tx.getDestinationAddress().toString())); + jsonTx.put("from", StringUtils.toJsonHex(tx.getSenderAddress().toString())); + jsonTx.put( + "to", + StringUtils.toJsonHex( + tx.getDestinationAddress() == null + ? EMPTY_BYTE_ARRAY + : tx.getDestinationAddress().toBytes())); jsonTx.put("timestamp", block.getTimestamp()); - jsonTx.put("input", TypeConverter.toJsonHex(tx.getData())); + jsonTx.put("input", StringUtils.toJsonHex(tx.getData())); jsonTx.put("blockNumber", block.getNumber()); jsonTxs.put(jsonTx); } else { - jsonTxs.put(TypeConverter.toJsonHex(tx.getTransactionHash())); + jsonTxs.put(StringUtils.toJsonHex(tx.getTransactionHash())); } } obj.put("transactions", jsonTxs); @@ -87,28 +95,28 @@ public static JSONObject AionBlockOnlyToJson(AionBlock block, BigInteger totalDi JSONObject obj = new JSONObject(); obj.put("number", block.getNumber()); - obj.put("hash", TypeConverter.toJsonHex(block.getHash())); - obj.put("parentHash", TypeConverter.toJsonHex(block.getParentHash())); - obj.put("logsBloom", TypeConverter.toJsonHex(block.getLogBloom())); - obj.put("transactionsRoot", TypeConverter.toJsonHex(block.getTxTrieRoot())); - obj.put("stateRoot", TypeConverter.toJsonHex(block.getStateRoot())); + obj.put("hash", StringUtils.toJsonHex(block.getHash())); + obj.put("parentHash", StringUtils.toJsonHex(block.getParentHash())); + obj.put("logsBloom", StringUtils.toJsonHex(block.getLogBloom())); + obj.put("transactionsRoot", StringUtils.toJsonHex(block.getTxTrieRoot())); + obj.put("stateRoot", StringUtils.toJsonHex(block.getStateRoot())); obj.put( "receiptsRoot", - TypeConverter.toJsonHex( + StringUtils.toJsonHex( block.getReceiptsRoot() == null ? new byte[0] : block.getReceiptsRoot())); - obj.put("difficulty", TypeConverter.toJsonHex(block.getDifficulty())); - obj.put("totalDifficulty", TypeConverter.toJsonHex(totalDifficulty)); + obj.put("difficulty", StringUtils.toJsonHex(block.getDifficulty())); + obj.put("totalDifficulty", StringUtils.toJsonHex(totalDifficulty)); - obj.put("miner", TypeConverter.toJsonHex(block.getCoinbase().toString())); - obj.put("timestamp", TypeConverter.toJsonHex(block.getTimestamp())); - obj.put("nonce", TypeConverter.toJsonHex(block.getNonce())); - obj.put("solution", TypeConverter.toJsonHex(block.getHeader().getSolution())); - obj.put("gasUsed", TypeConverter.toJsonHex(block.getHeader().getEnergyConsumed())); - obj.put("gasLimit", TypeConverter.toJsonHex(block.getHeader().getEnergyLimit())); - obj.put("nrgUsed", TypeConverter.toJsonHex(block.getHeader().getEnergyConsumed())); - obj.put("nrgLimit", TypeConverter.toJsonHex(block.getHeader().getEnergyLimit())); + obj.put("miner", StringUtils.toJsonHex(block.getCoinbase().toString())); + obj.put("timestamp", StringUtils.toJsonHex(block.getTimestamp())); + obj.put("nonce", StringUtils.toJsonHex(block.getNonce())); + obj.put("solution", StringUtils.toJsonHex(block.getHeader().getSolution())); + obj.put("gasUsed", StringUtils.toJsonHex(block.getHeader().getEnergyConsumed())); + obj.put("gasLimit", StringUtils.toJsonHex(block.getHeader().getEnergyLimit())); + obj.put("nrgUsed", StringUtils.toJsonHex(block.getHeader().getEnergyConsumed())); + obj.put("nrgLimit", StringUtils.toJsonHex(block.getHeader().getEnergyLimit())); - obj.put("extraData", TypeConverter.toJsonHex(block.getExtraData())); + obj.put("extraData", StringUtils.toJsonHex(block.getExtraData())); obj.put("size", block.size()); obj.put("numTransactions", block.getTransactionsList().size()); diff --git a/modApiServer/src/org/aion/api/server/types/EvtBlk.java b/modApiServer/src/org/aion/api/server/types/EvtBlk.java index 74ec3577ae..9accb99671 100644 --- a/modApiServer/src/org/aion/api/server/types/EvtBlk.java +++ b/modApiServer/src/org/aion/api/server/types/EvtBlk.java @@ -2,15 +2,15 @@ import static org.aion.api.server.types.Fltr.Type; -import org.aion.base.type.IBlock; -import org.aion.base.util.TypeConverter; +import org.aion.interfaces.block.Block; +import org.aion.util.string.StringUtils; @SuppressWarnings("rawtypes") public class EvtBlk extends Evt { - public final IBlock b; + public final Block b; - public EvtBlk(IBlock b) { + public EvtBlk(Block b) { this.b = b; } @@ -21,6 +21,6 @@ public Type getType() { @Override public String toJSON() { - return TypeConverter.toJsonHex(b.getHash()); + return StringUtils.toJsonHex(b.getHash()); } } diff --git a/modApiServer/src/org/aion/api/server/types/EvtTx.java b/modApiServer/src/org/aion/api/server/types/EvtTx.java index 902b18947c..e63b9225e8 100644 --- a/modApiServer/src/org/aion/api/server/types/EvtTx.java +++ b/modApiServer/src/org/aion/api/server/types/EvtTx.java @@ -1,14 +1,14 @@ package org.aion.api.server.types; import org.aion.api.server.types.Fltr.Type; -import org.aion.base.type.ITransaction; -import org.aion.base.util.TypeConverter; +import org.aion.interfaces.tx.Transaction; +import org.aion.util.string.StringUtils; public class EvtTx extends Evt { - private final ITransaction tx; + private final Transaction tx; - public EvtTx(ITransaction tx) { + public EvtTx(Transaction tx) { this.tx = tx; } @@ -19,6 +19,6 @@ public Type getType() { @Override public String toJSON() { - return TypeConverter.toJsonHex(tx.getTransactionHash()); + return StringUtils.toJsonHex(tx.getTransactionHash()); } } diff --git a/modApiServer/src/org/aion/api/server/types/Fltr.java b/modApiServer/src/org/aion/api/server/types/Fltr.java index a97eff6e9e..cd821a7035 100644 --- a/modApiServer/src/org/aion/api/server/types/Fltr.java +++ b/modApiServer/src/org/aion/api/server/types/Fltr.java @@ -2,8 +2,8 @@ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.atomic.AtomicLong; -import org.aion.base.type.IBlockSummary; -import org.aion.base.type.ITransaction; +import org.aion.interfaces.block.BlockSummary; +import org.aion.interfaces.tx.Transaction; public abstract class Fltr { @@ -70,11 +70,11 @@ public synchronized void add(Evt evt) { if (events.size() < EVTS_MAX) events.add(evt); } - public boolean onBlock(IBlockSummary b) { + public boolean onBlock(BlockSummary b) { return false; } - public boolean onTransaction(ITransaction tx) { + public boolean onTransaction(Transaction tx) { return false; } } diff --git a/modApiServer/src/org/aion/api/server/types/FltrBlk.java b/modApiServer/src/org/aion/api/server/types/FltrBlk.java index 0dd2ba82de..27d27098ba 100644 --- a/modApiServer/src/org/aion/api/server/types/FltrBlk.java +++ b/modApiServer/src/org/aion/api/server/types/FltrBlk.java @@ -1,6 +1,6 @@ package org.aion.api.server.types; -import org.aion.base.type.IBlockSummary; +import org.aion.interfaces.block.BlockSummary; public class FltrBlk extends Fltr { @@ -9,7 +9,7 @@ public FltrBlk() { } @Override - public boolean onBlock(IBlockSummary b) { + public boolean onBlock(BlockSummary b) { add(new EvtBlk(b.getBlock())); return true; } diff --git a/modApiServer/src/org/aion/api/server/types/FltrCt.java b/modApiServer/src/org/aion/api/server/types/FltrCt.java index e3be169faf..ff22afed51 100644 --- a/modApiServer/src/org/aion/api/server/types/FltrCt.java +++ b/modApiServer/src/org/aion/api/server/types/FltrCt.java @@ -2,8 +2,7 @@ import java.util.Arrays; import java.util.List; -import org.aion.base.type.AionAddress; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; /** @author chris */ // NOTE: only used by java api diff --git a/modApiServer/src/org/aion/api/server/types/FltrLg.java b/modApiServer/src/org/aion/api/server/types/FltrLg.java index 2c598cb7bd..ca6437c16e 100644 --- a/modApiServer/src/org/aion/api/server/types/FltrLg.java +++ b/modApiServer/src/org/aion/api/server/types/FltrLg.java @@ -3,11 +3,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.aion.base.type.IBlock; -import org.aion.base.type.IBlockSummary; -import org.aion.base.type.ITransaction; +import org.aion.interfaces.block.Block; +import org.aion.interfaces.block.BlockSummary; +import org.aion.interfaces.tx.Transaction; import org.aion.mcf.vm.types.Bloom; -import org.aion.mcf.vm.types.Log; import org.aion.vm.api.interfaces.IExecutionLog; import org.aion.zero.impl.core.BloomFilter; import org.aion.zero.impl.core.IAionBlockchain; @@ -45,19 +44,21 @@ public void setTopics(List topics) { // ------------------------------------------------------------------------------- @Override - public boolean onBlock(IBlockSummary bs) { + public boolean onBlock(BlockSummary bs) { List receipts = ((AionBlockSummary) bs).getReceipts(); - IBlock blk = bs.getBlock(); + Block blk = bs.getBlock(); if (matchBloom(new Bloom(((IAionBlock) blk).getLogBloom()))) { int txIndex = 0; for (AionTxReceipt receipt : receipts) { - ITransaction tx = receipt.getTransaction(); - if (matchesContractAddress(tx.getDestinationAddress().toBytes())) { + Transaction tx = receipt.getTransaction(); + if (tx.getDestinationAddress() != null + && matchesContractAddress(tx.getDestinationAddress().toBytes())) { if (matchBloom(receipt.getBloomFilter())) { int logIndex = 0; for (IExecutionLog logInfo : receipt.getLogInfoList()) { - if (matchBloom(logInfo.getBloomFilterForLog()) && matchesExactly(logInfo)) { + if (matchBloom(logInfo.getBloomFilterForLog()) + && matchesExactly(logInfo)) { add( new EvtLg( new TxRecptLg( @@ -85,8 +86,9 @@ public boolean onBlock(IBlockSummary bs) { public boolean onBlock(IAionBlock blk, IAionBlockchain chain) { if (matchBloom(new Bloom(blk.getLogBloom()))) { int txIndex = 0; - for (ITransaction txn : blk.getTransactionsList()) { - if (matchesContractAddress(txn.getDestinationAddress().toBytes())) { + for (Transaction txn : blk.getTransactionsList()) { + if (txn.getDestinationAddress() != null + && matchesContractAddress(txn.getDestinationAddress().toBytes())) { // now that we know that our filter might match with some logs in this // transaction, go ahead // and retrieve the txReceipt from the chain @@ -95,7 +97,8 @@ public boolean onBlock(IAionBlock blk, IAionBlockchain chain) { if (matchBloom(receipt.getBloomFilter())) { int logIndex = 0; for (IExecutionLog logInfo : receipt.getLogInfoList()) { - if (matchBloom(logInfo.getBloomFilterForLog()) && matchesExactly(logInfo)) { + if (matchBloom(logInfo.getBloomFilterForLog()) + && matchesExactly(logInfo)) { add( new EvtLg( new TxRecptLg( diff --git a/modApiServer/src/org/aion/api/server/types/FltrTx.java b/modApiServer/src/org/aion/api/server/types/FltrTx.java index 9c191ad687..7dc99da63b 100644 --- a/modApiServer/src/org/aion/api/server/types/FltrTx.java +++ b/modApiServer/src/org/aion/api/server/types/FltrTx.java @@ -1,6 +1,6 @@ package org.aion.api.server.types; -import org.aion.base.type.ITransaction; +import org.aion.interfaces.tx.Transaction; public class FltrTx extends Fltr { @@ -9,7 +9,7 @@ public FltrTx() { } @Override - public boolean onTransaction(ITransaction tx) { + public boolean onTransaction(Transaction tx) { add(new EvtTx(tx)); return true; } diff --git a/modApiServer/src/org/aion/api/server/types/NumericalValue.java b/modApiServer/src/org/aion/api/server/types/NumericalValue.java index 54e2f91bcb..ee3e344dc5 100644 --- a/modApiServer/src/org/aion/api/server/types/NumericalValue.java +++ b/modApiServer/src/org/aion/api/server/types/NumericalValue.java @@ -2,7 +2,7 @@ import java.math.BigInteger; import java.util.regex.Pattern; -import org.aion.base.util.ByteUtil; +import org.aion.util.bytes.ByteUtil; /** Base type for a numerical value derived from some JSON string, or vice versa */ public class NumericalValue { diff --git a/modApiServer/src/org/aion/api/server/types/Tx.java b/modApiServer/src/org/aion/api/server/types/Tx.java index 2540728fdb..3c1d8160ba 100644 --- a/modApiServer/src/org/aion/api/server/types/Tx.java +++ b/modApiServer/src/org/aion/api/server/types/Tx.java @@ -1,7 +1,9 @@ package org.aion.api.server.types; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.TypeConverter; +import static org.aion.util.bytes.ByteUtil.EMPTY_BYTE_ARRAY; + +import org.aion.util.bytes.ByteUtil; +import org.aion.util.string.StringUtils; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.impl.types.AionTxInfo; import org.aion.zero.types.AionTransaction; @@ -35,22 +37,27 @@ public static JSONObject AionTransactionToJSON(AionTransaction tx, AionBlock b, json.put( "contractAddress", (tx.getContractAddress() != null) - ? TypeConverter.toJsonHex(tx.getContractAddress().toString()) + ? StringUtils.toJsonHex(tx.getContractAddress().toString()) : null); - json.put("hash", TypeConverter.toJsonHex(tx.getTransactionHash())); + json.put("hash", StringUtils.toJsonHex(tx.getTransactionHash())); json.put("transactionIndex", index); - json.put("value", TypeConverter.toJsonHex(tx.getValue())); + json.put("value", StringUtils.toJsonHex(tx.getValue())); json.put("nrg", tx.getEnergyLimit()); - json.put("nrgPrice", TypeConverter.toJsonHex(tx.getEnergyPrice())); + json.put("nrgPrice", StringUtils.toJsonHex(tx.getEnergyPrice())); json.put("gas", tx.getEnergyLimit()); - json.put("gasPrice", TypeConverter.toJsonHex(tx.getEnergyPrice())); + json.put("gasPrice", StringUtils.toJsonHex(tx.getEnergyPrice())); json.put("nonce", ByteUtil.byteArrayToLong(tx.getNonce())); - json.put("from", TypeConverter.toJsonHex(tx.getSenderAddress().toString())); - json.put("to", TypeConverter.toJsonHex(tx.getDestinationAddress().toString())); + json.put("from", StringUtils.toJsonHex(tx.getSenderAddress().toString())); + json.put( + "to", + StringUtils.toJsonHex( + tx.getDestinationAddress() == null + ? EMPTY_BYTE_ARRAY + : tx.getDestinationAddress().toBytes())); json.put("timestamp", b.getTimestamp()); - json.put("input", TypeConverter.toJsonHex(tx.getData())); - json.put("blockNumber", TypeConverter.toJsonHex(b.getNumber())); - json.put("blockHash", TypeConverter.toJsonHex(b.getHash())); + json.put("input", StringUtils.toJsonHex(tx.getData())); + json.put("blockNumber", StringUtils.toJsonHex(b.getNumber())); + json.put("blockHash", StringUtils.toJsonHex(b.getHash())); return json; } diff --git a/modApiServer/src/org/aion/api/server/types/TxPendingStatus.java b/modApiServer/src/org/aion/api/server/types/TxPendingStatus.java index 7747c777f9..4f8939e036 100644 --- a/modApiServer/src/org/aion/api/server/types/TxPendingStatus.java +++ b/modApiServer/src/org/aion/api/server/types/TxPendingStatus.java @@ -1,6 +1,6 @@ package org.aion.api.server.types; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; import org.aion.mcf.evt.IListenerBase; public class TxPendingStatus { diff --git a/modApiServer/src/org/aion/api/server/types/TxRecpt.java b/modApiServer/src/org/aion/api/server/types/TxRecpt.java index 688efe2a5b..5ea5bb1516 100644 --- a/modApiServer/src/org/aion/api/server/types/TxRecpt.java +++ b/modApiServer/src/org/aion/api/server/types/TxRecpt.java @@ -1,17 +1,15 @@ package org.aion.api.server.types; -import static org.aion.base.util.TypeConverter.toJsonHex; +import static org.aion.util.string.StringUtils.toJsonHex; -import org.aion.base.type.AionAddress; -import org.aion.base.type.IBlock; -import org.aion.base.type.IBlockHeader; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.TypeConverter; +import org.aion.interfaces.block.Block; +import org.aion.interfaces.block.BlockHeader; +import org.aion.types.Address; import org.aion.mcf.core.AbstractTxInfo; import org.aion.mcf.types.AbstractTransaction; import org.aion.mcf.types.AbstractTxReceipt; -import org.aion.mcf.vm.types.Log; -import org.aion.vm.api.interfaces.Address; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.string.StringUtils; import org.aion.vm.api.interfaces.IExecutionLog; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.types.AionTransaction; @@ -72,10 +70,10 @@ public final class TxRecpt { public < TX extends AbstractTransaction, - BH extends IBlockHeader, + BH extends BlockHeader, TXR extends AbstractTxReceipt> TxRecpt( - IBlock block, + Block block, AbstractTxInfo txInfo, long cumulativeNrgUsed, boolean isMainchain) { @@ -120,7 +118,7 @@ public final class TxRecpt { this.to = this.toAddr == null ? null : toJsonHex(this.toAddr.toBytes()); this.txTimeStamp = ByteUtil.byteArrayToLong(receipt.getTransaction().getTimeStamp()); - this.txValue = TypeConverter.toJsonHex(txInfo.getReceipt().getTransaction().getValue()); + this.txValue = StringUtils.toJsonHex(txInfo.getReceipt().getTransaction().getValue()); this.txNonce = ByteUtil.byteArrayToLong(txInfo.getReceipt().getTransaction().getNonce()); byte[] _txData = txInfo.getReceipt().getTransaction().getData(); this.txData = _txData == null ? "" : toJsonHex(_txData); diff --git a/modApiServer/src/org/aion/api/server/types/TxRecptLg.java b/modApiServer/src/org/aion/api/server/types/TxRecptLg.java index aa27d92ae2..7c08f379d5 100644 --- a/modApiServer/src/org/aion/api/server/types/TxRecptLg.java +++ b/modApiServer/src/org/aion/api/server/types/TxRecptLg.java @@ -1,9 +1,8 @@ package org.aion.api.server.types; -import org.aion.base.type.IBlock; -import org.aion.base.type.ITransaction; -import org.aion.base.util.TypeConverter; -import org.aion.mcf.vm.types.Log; +import org.aion.interfaces.block.Block; +import org.aion.interfaces.tx.Transaction; +import org.aion.util.string.StringUtils; import org.aion.vm.api.interfaces.IExecutionLog; public class TxRecptLg { @@ -27,21 +26,21 @@ public class TxRecptLg { // true when the log was removed, due to a chain reorganization. false if its a valid log. public boolean removed; - public TxRecptLg( - IExecutionLog logInfo, IBlock b, Integer txIndex, TX tx, int logIdx, boolean isMainchain) { - this.logIndex = TypeConverter.toJsonHex(logIdx); - this.blockNumber = b == null ? null : TypeConverter.toJsonHex(b.getNumber()); - this.blockHash = b == null ? null : TypeConverter.toJsonHex(b.getHash()); + public TxRecptLg( + IExecutionLog logInfo, Block b, Integer txIndex, TX tx, int logIdx, boolean isMainchain) { + this.logIndex = StringUtils.toJsonHex(logIdx); + this.blockNumber = b == null ? null : StringUtils.toJsonHex(b.getNumber()); + this.blockHash = b == null ? null : StringUtils.toJsonHex(b.getHash()); this.transactionIndex = - (b == null || txIndex == null) ? null : TypeConverter.toJsonHex(txIndex); - this.transactionHash = TypeConverter.toJsonHex(tx.getTransactionHash()); - this.address = TypeConverter.toJsonHex(logInfo.getSourceAddress().toString()); - this.data = TypeConverter.toJsonHex(logInfo.getData()); + (b == null || txIndex == null) ? null : StringUtils.toJsonHex(txIndex); + this.transactionHash = StringUtils.toJsonHex(tx.getTransactionHash()); + this.address = StringUtils.toJsonHex(logInfo.getSourceAddress().toString()); + this.data = StringUtils.toJsonHex(logInfo.getData()); this.removed = !isMainchain; this.topics = new String[logInfo.getTopics().size()]; for (int i = 0, m = this.topics.length; i < m; i++) { - this.topics[i] = TypeConverter.toJsonHex(logInfo.getTopics().get(i)); + this.topics[i] = StringUtils.toJsonHex(logInfo.getTopics().get(i)); } } } diff --git a/modApiServer/src/org/aion/api/server/zmq/HdlrZmq.java b/modApiServer/src/org/aion/api/server/zmq/HdlrZmq.java index 27824e3177..a8ef01b4b3 100644 --- a/modApiServer/src/org/aion/api/server/zmq/HdlrZmq.java +++ b/modApiServer/src/org/aion/api/server/zmq/HdlrZmq.java @@ -9,8 +9,7 @@ import org.aion.api.server.pb.TxWaitingMappingUpdate; import org.aion.api.server.types.Fltr; import org.aion.api.server.types.TxPendingStatus; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.NativeLoader; +import org.aion.types.ByteArrayWrapper; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.slf4j.Logger; diff --git a/modApiServer/src/org/aion/api/server/zmq/ProtocolProcessor.java b/modApiServer/src/org/aion/api/server/zmq/ProtocolProcessor.java index 89fb52200a..af60e7e90d 100644 --- a/modApiServer/src/org/aion/api/server/zmq/ProtocolProcessor.java +++ b/modApiServer/src/org/aion/api/server/zmq/ProtocolProcessor.java @@ -22,11 +22,11 @@ import org.aion.api.server.types.EvtContract; import org.aion.api.server.types.Fltr; import org.aion.api.server.types.TxPendingStatus; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.Hex; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.aion.mcf.config.CfgApiZmq; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.conversions.Hex; import org.slf4j.Logger; import org.zeromq.ZMQ; import org.zeromq.ZMQ.Context; @@ -155,7 +155,7 @@ public void run() { } private void loadCurveKeyPair() { - List files = org.aion.base.io.File.getFiles(PATH); + List files = org.aion.util.file.File.getFiles(PATH); String nextLoad = ""; for (File f : files) { if (f.getName().contains("zmqCurvePubkey")) { diff --git a/modApiServer/test/org/aion/api/server/ApiAionTest.java b/modApiServer/test/org/aion/api/server/ApiAionTest.java index b4b3cd0737..7be303ae48 100644 --- a/modApiServer/test/org/aion/api/server/ApiAionTest.java +++ b/modApiServer/test/org/aion/api/server/ApiAionTest.java @@ -2,6 +2,7 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -16,9 +17,9 @@ import java.util.Map; import org.aion.api.server.types.ArgTxCall; import org.aion.api.server.types.SyncInfo; -import org.aion.base.type.AionAddress; -import org.aion.base.type.ITransaction; -import org.aion.base.type.ITxReceipt; +import org.aion.interfaces.tx.Transaction; +import org.aion.interfaces.tx.TxReceipt; +import org.aion.types.Address; import org.aion.crypto.ed25519.ECKeyEd25519; import org.aion.evtmgr.impl.evt.EventBlock; import org.aion.evtmgr.impl.evt.EventDummy; @@ -26,7 +27,8 @@ import org.aion.mcf.account.AccountManager; import org.aion.mcf.account.Keystore; import org.aion.mcf.blockchain.TxResponse; -import org.aion.vm.api.interfaces.Address; + +import org.aion.vm.VirtualMachineProvider; import org.aion.zero.impl.blockchain.AionImpl; import org.aion.zero.impl.config.CfgAion; import org.aion.zero.impl.db.AionBlockStore; @@ -54,12 +56,12 @@ protected void onBlock(AionBlockSummary cbs) { } @Override - protected void pendingTxReceived(ITransaction _tx) { + protected void pendingTxReceived(Transaction _tx) { pendingRcvdFlag = true; } @Override - protected void pendingTxUpdate(ITxReceipt _txRcpt, EventTx.STATE _state) { + protected void pendingTxUpdate(TxReceipt _txRcpt, EventTx.STATE _state) { pendingUpdateFlag = true; } @@ -77,7 +79,7 @@ private ApiAionImpl(AionImpl impl) { private void addEvents() { EventTx pendingRcvd = new EventTx(EventTx.CALLBACK.PENDINGTXRECEIVED0); AionTransaction tx = new AionTransaction(null); - List l1 = new ArrayList(); + List l1 = new ArrayList(); l1.add(tx); l1.add(tx); l1.add(tx); @@ -128,10 +130,13 @@ public void setup() { api = new ApiAionImpl(impl); repo = AionRepositoryImpl.inst(); testStartTime = System.currentTimeMillis(); + VirtualMachineProvider.initializeAllVirtualMachines(); } @After public void tearDown() { + VirtualMachineProvider.shutdownAllVirtualMachines(); + // get a list of all the files in keystore directory File folder = new File(KEYSTORE_PATH); @@ -206,21 +211,58 @@ public void testGetBlock() { CfgAion.inst().getGenesis().getDifficultyBI()); } + /** + * Tests that getSyncInfo returns the correct information when the local best block number is + * greater than {@link ApiAion#SYNC_TOLERANCE} blocks below the network best block. + * + *

    {@link ApiAion#SYNC_TOLERANCE} is the number of blocks that the local must be within + * (compared to the network best) in order for syncing to be considered complete. + */ + @Test + public void testGetSyncInfoWhenLocalIsOutsideSyncToleranceAmount() { + long localBestBlockNumber = 0; + long networkBestBlockNumber = localBestBlockNumber + ApiAion.SYNC_TOLERANCE + 1; + + SyncInfo syncInfo = api.getSyncInfo(localBestBlockNumber, networkBestBlockNumber); + assertFalse(syncInfo.done); + assertEquals(localBestBlockNumber, syncInfo.chainBestBlkNumber); + assertEquals(networkBestBlockNumber, syncInfo.networkBestBlkNumber); + } + + /** + * Tests that getSyncInfo returns the correct information when the local best block number is + * {@link ApiAion#SYNC_TOLERANCE} blocks below the network best block. + * + *

    {@link ApiAion#SYNC_TOLERANCE} is the number of blocks that the local must be within + * (compared to the network best) in order for syncing to be considered complete. + */ + @Test + public void testGetSyncInfoWhenLocalIsAtSyncToleranceAmount() { + long localBestBlockNumber = 0; + long networkBestBlockNumber = localBestBlockNumber + ApiAion.SYNC_TOLERANCE; + + SyncInfo syncInfo = api.getSyncInfo(localBestBlockNumber, networkBestBlockNumber); + assertTrue(syncInfo.done); + assertEquals(localBestBlockNumber, syncInfo.chainBestBlkNumber); + assertEquals(networkBestBlockNumber, syncInfo.networkBestBlkNumber); + } + + /** + * Tests that getSyncInfo returns the correct information when the local best block number is + * less than {@link ApiAion#SYNC_TOLERANCE} blocks below the network best block. + * + *

    {@link ApiAion#SYNC_TOLERANCE} is the number of blocks that the local must be within + * (compared to the network best) in order for syncing to be considered complete. + */ @Test - public void testGetSync() { - SyncInfo sync = api.getSync(); - assertNotNull(sync); - assertEquals(sync.done, impl.isSyncComplete()); - if (impl.getInitialStartingBlockNumber().isPresent()) - assertEquals( - (long) impl.getInitialStartingBlockNumber().get(), sync.chainStartingBlkNumber); - else assertEquals(0L, sync.chainStartingBlkNumber); - if (impl.getNetworkBestBlockNumber().isPresent()) - assertEquals((long) impl.getNetworkBestBlockNumber().get(), sync.networkBestBlkNumber); - else assertEquals(0L, sync.networkBestBlkNumber); - if (impl.getLocalBestBlockNumber().isPresent()) - assertEquals((long) impl.getLocalBestBlockNumber().get(), sync.chainBestBlkNumber); - else assertEquals(0L, sync.chainBestBlkNumber); + public void testGetSyncInfoWhenLocalIsWithinSyncToleranceAmount() { + long localBestBlockNumber = 0; + long networkBestBlockNumber = localBestBlockNumber + ApiAion.SYNC_TOLERANCE - 1; + + SyncInfo syncInfo = api.getSyncInfo(localBestBlockNumber, networkBestBlockNumber); + assertTrue(syncInfo.done); + assertEquals(localBestBlockNumber, syncInfo.chainBestBlkNumber); + assertEquals(networkBestBlockNumber, syncInfo.networkBestBlkNumber); } @Test @@ -230,9 +272,9 @@ public void testGetTransactions() { byte[] msg = "test message".getBytes(); AionTransaction tx = new AionTransaction( - repo.getNonce(AionAddress.ZERO_ADDRESS()).toByteArray(), - AionAddress.ZERO_ADDRESS(), - AionAddress.ZERO_ADDRESS(), + repo.getNonce(Address.ZERO_ADDRESS()).toByteArray(), + Address.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), BigInteger.ONE.toByteArray(), msg, 100000, @@ -261,7 +303,7 @@ public void testGetTransactions() { 1, api.getTransactionCount( blk.getTransactionsList().get(0).getSenderAddress(), blk.getNumber())); - assertEquals(0, api.getTransactionCount(AionAddress.EMPTY_ADDRESS(), blk.getNumber())); + assertEquals(0, api.getTransactionCount(null, blk.getNumber())); assertEquals(tx, api.getTransactionByHash(tx.getTransactionHash())); } @@ -270,14 +312,14 @@ public void testGetTransactions() { public void testDoCall() { byte[] msg = "test message".getBytes(); - Address addr = new AionAddress(Keystore.create("testPwd")); + Address addr = new Address(Keystore.create("testPwd")); AccountManager.inst().unlockAccount(addr, "testPwd", 50000); AionTransaction tx = new AionTransaction( - repo.getNonce(AionAddress.ZERO_ADDRESS()).toByteArray(), + repo.getNonce(Address.ZERO_ADDRESS()).toByteArray(), addr, - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), BigInteger.ONE.toByteArray(), msg, 100000, @@ -287,7 +329,7 @@ public void testDoCall() { ArgTxCall txcall = new ArgTxCall( addr, - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), msg, repo.getNonce(addr), BigInteger.ONE, @@ -295,22 +337,21 @@ public void testDoCall() { 100000); assertNotNull(api.doCall(txcall)); - tearDown(); } @Test public void testEstimates() { byte[] msg = "test message".getBytes(); - Address addr = new AionAddress(Keystore.create("testPwd")); + Address addr = new Address(Keystore.create("testPwd")); AccountManager.inst().unlockAccount(addr, "testPwd", 50000); AionTransaction tx = new AionTransaction( - repo.getNonce(AionAddress.ZERO_ADDRESS()).toByteArray(), + repo.getNonce(Address.ZERO_ADDRESS()).toByteArray(), addr, - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), BigInteger.ONE.toByteArray(), msg, 100000, @@ -320,7 +361,7 @@ public void testEstimates() { ArgTxCall txcall = new ArgTxCall( addr, - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), msg, repo.getNonce(addr), BigInteger.ONE, @@ -328,7 +369,6 @@ public void testEstimates() { 100000); assertEquals(impl.estimateTxNrg(tx, api.getBestBlock()), api.estimateNrg(txcall)); - tearDown(); } @Test @@ -346,7 +386,7 @@ public void testCreateContract() { txcall = new ArgTxCall( null, - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), msg, BigInteger.ONE, BigInteger.ONE, @@ -357,8 +397,8 @@ public void testCreateContract() { txcall = new ArgTxCall( - AionAddress.EMPTY_ADDRESS(), - AionAddress.ZERO_ADDRESS(), + null, + Address.ZERO_ADDRESS(), msg, BigInteger.ONE, BigInteger.ONE, @@ -369,12 +409,12 @@ public void testCreateContract() { // locked account should throw INVALID_ACCOUNT - Address addr = new AionAddress(Keystore.create("testPwd")); + Address addr = new Address(Keystore.create("testPwd")); txcall = new ArgTxCall( addr, - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), msg, repo.getNonce(addr), BigInteger.ONE, @@ -387,17 +427,14 @@ public void testCreateContract() { @Test public void testAccountGetters() { assertEquals( - repo.getBalance(AionAddress.ZERO_ADDRESS()), - api.getBalance(AionAddress.ZERO_ADDRESS())); + repo.getBalance(Address.ZERO_ADDRESS()), api.getBalance(Address.ZERO_ADDRESS())); + assertEquals(repo.getNonce(Address.ZERO_ADDRESS()), api.getNonce(Address.ZERO_ADDRESS())); assertEquals( - repo.getNonce(AionAddress.ZERO_ADDRESS()), - api.getNonce(AionAddress.ZERO_ADDRESS())); + repo.getBalance(Address.ZERO_ADDRESS()), + api.getBalance(Address.ZERO_ADDRESS().toString())); assertEquals( - repo.getBalance(AionAddress.ZERO_ADDRESS()), - api.getBalance(AionAddress.ZERO_ADDRESS().toString())); - assertEquals( - repo.getNonce(AionAddress.ZERO_ADDRESS()), - api.getNonce(AionAddress.ZERO_ADDRESS().toString())); + repo.getNonce(Address.ZERO_ADDRESS()), + api.getNonce(Address.ZERO_ADDRESS().toString())); } @Test @@ -416,7 +453,7 @@ public void testSendTransaction() { txcall = new ArgTxCall( null, - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), msg, BigInteger.ONE, BigInteger.ONE, @@ -427,8 +464,8 @@ public void testSendTransaction() { txcall = new ArgTxCall( - AionAddress.EMPTY_ADDRESS(), - AionAddress.ZERO_ADDRESS(), + null, + Address.ZERO_ADDRESS(), msg, BigInteger.ONE, BigInteger.ONE, @@ -439,12 +476,12 @@ public void testSendTransaction() { // locked account should throw INVALID_ACCOUNT - Address addr = new AionAddress(Keystore.create("testPwd")); + Address addr = new Address(Keystore.create("testPwd")); txcall = new ArgTxCall( addr, - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), msg, repo.getNonce(addr), BigInteger.ONE, @@ -462,8 +499,7 @@ public void testSimpleGetters() { api.initNrgOracle(impl); assertNotNull(api.getCoinbase()); - assertEquals( - repo.getCode(AionAddress.ZERO_ADDRESS()), api.getCode(AionAddress.ZERO_ADDRESS())); + assertEquals(repo.getCode(Address.ZERO_ADDRESS()), api.getCode(Address.ZERO_ADDRESS())); assertEquals(impl.getBlockMiner().isMining(), api.isMining()); assertArrayEquals(CfgAion.inst().getNodes(), api.getBootNodes()); assertEquals(impl.getAionHub().getP2pMgr().getActiveNodes().size(), api.peerCount()); diff --git a/modApiServer/test/org/aion/api/server/ApiTest.java b/modApiServer/test/org/aion/api/server/ApiTest.java index b84cdeac9b..83d9476aa5 100644 --- a/modApiServer/test/org/aion/api/server/ApiTest.java +++ b/modApiServer/test/org/aion/api/server/ApiTest.java @@ -12,7 +12,7 @@ import java.math.BigInteger; import java.util.Map; import org.aion.api.server.types.CompiledContr; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.mcf.account.AccountManager; import org.aion.mcf.account.Keystore; import org.aion.mcf.types.AbstractBlock; @@ -110,9 +110,9 @@ public void tearDown() { @Test public void testLockAndUnlock() { - assertFalse(api.unlockAccount(AionAddress.ZERO_ADDRESS(), "testPassword", 0)); - assertFalse(api.unlockAccount(AionAddress.ZERO_ADDRESS().toString(), "testPassword", 0)); - assertFalse(api.lockAccount(AionAddress.ZERO_ADDRESS(), "testPassword")); + assertFalse(api.unlockAccount(Address.ZERO_ADDRESS(), "testPassword", 0)); + assertFalse(api.unlockAccount(Address.ZERO_ADDRESS().toString(), "testPassword", 0)); + assertFalse(api.lockAccount(Address.ZERO_ADDRESS(), "testPassword")); addr = Keystore.create("testPwd"); assertTrue(api.unlockAccount(addr, "testPwd", 50000)); @@ -121,10 +121,10 @@ public void testLockAndUnlock() { @Test public void testAccountRetrieval() { - assertNull(api.getAccountKey(AionAddress.ZERO_ADDRESS().toString())); + assertNull(api.getAccountKey(Address.ZERO_ADDRESS().toString())); addr = Keystore.create("testPwd"); - assertEquals(AccountManager.inst().getKey(AionAddress.wrap(addr)), api.getAccountKey(addr)); + assertEquals(AccountManager.inst().getKey(Address.wrap(addr)), api.getAccountKey(addr)); assertTrue(api.getAccounts().contains(addr)); tearDown(); diff --git a/modApiServer/test/org/aion/api/server/ApiUtilTest.java b/modApiServer/test/org/aion/api/server/ApiUtilTest.java index 459816e77c..042f2c0005 100644 --- a/modApiServer/test/org/aion/api/server/ApiUtilTest.java +++ b/modApiServer/test/org/aion/api/server/ApiUtilTest.java @@ -5,7 +5,7 @@ import static org.junit.Assert.assertNull; import java.util.Arrays; -import org.aion.base.util.ByteUtil; +import org.aion.util.bytes.ByteUtil; import org.apache.commons.lang3.RandomUtils; import org.junit.Test; diff --git a/modApiServer/test/org/aion/api/server/TxRecptLgTest.java b/modApiServer/test/org/aion/api/server/TxRecptLgTest.java index 481c5b1bda..4372745821 100644 --- a/modApiServer/test/org/aion/api/server/TxRecptLgTest.java +++ b/modApiServer/test/org/aion/api/server/TxRecptLgTest.java @@ -8,13 +8,14 @@ import java.math.BigInteger; import java.util.List; import org.aion.api.server.types.TxRecptLg; -import org.aion.base.util.ByteUtil; import org.aion.crypto.ECKey; import org.aion.crypto.HashUtil; import org.aion.mcf.core.ImportResult; +import org.aion.mcf.tx.TransactionTypes; import org.aion.solidity.CompilationResult; import org.aion.solidity.Compiler; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; +import org.aion.util.bytes.ByteUtil; import org.aion.vm.api.interfaces.IExecutionLog; import org.aion.zero.impl.BlockContext; import org.aion.zero.impl.StandaloneBlockchain; @@ -69,7 +70,8 @@ public void TestTxRecptLg() throws InterruptedException, IOException { new byte[0], ByteUtil.hexStringToBytes(contractA), 1_000_000L, - 1L); + 1L, + TransactionTypes.FVM_CREATE_CODE); tx1.sign(deployerAccount); nonce = nonce.add(BigInteger.ONE); @@ -80,7 +82,8 @@ public void TestTxRecptLg() throws InterruptedException, IOException { new byte[0], ByteUtil.hexStringToBytes(contractB), 1_000_000L, - 1L); + 1L, + TransactionTypes.FVM_CREATE_CODE); tx2.sign(deployerAccount); BlockContext context = diff --git a/modApiServer/test/org/aion/api/server/pb/ApiAion0Test.java b/modApiServer/test/org/aion/api/server/pb/ApiAion0Test.java index 02cc4c0ca3..cd0c888918 100644 --- a/modApiServer/test/org/aion/api/server/pb/ApiAion0Test.java +++ b/modApiServer/test/org/aion/api/server/pb/ApiAion0Test.java @@ -15,14 +15,15 @@ import java.util.Arrays; import java.util.Collections; import org.aion.api.server.ApiUtil; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; -import org.aion.base.util.TypeConverter; +import org.aion.types.Address; import org.aion.crypto.ed25519.ECKeyEd25519; import org.aion.equihash.EquihashMiner; import org.aion.mcf.account.AccountManager; import org.aion.mcf.account.Keystore; -import org.aion.vm.api.interfaces.Address; + +import org.aion.util.bytes.ByteUtil; +import org.aion.util.string.StringUtils; +import org.aion.vm.VirtualMachineProvider; import org.aion.zero.impl.Version; import org.aion.zero.impl.blockchain.AionImpl; import org.aion.zero.impl.config.CfgAion; @@ -113,6 +114,7 @@ public void setup() { CfgAion.inst().getDb().setPath(DATABASE_PATH); api = new ApiAion0(AionImpl.inst()); testStartTime = System.currentTimeMillis(); + VirtualMachineProvider.initializeAllVirtualMachines(); } @After @@ -120,6 +122,8 @@ public void tearDown() { api.shutDown(); rsp = null; + VirtualMachineProvider.shutdownAllVirtualMachines(); + // get a list of all the files in keystore directory File folder = new File(KEYSTORE_PATH); try { @@ -181,7 +185,7 @@ public void testProcessMinerAddress() throws Exception { Message.rsp_minerAddress ma = Message.rsp_minerAddress.parseFrom(stripHeader(rsp)); assertEquals( - ByteString.copyFrom(TypeConverter.StringHexToByteArray(api.getCoinbase())), + ByteString.copyFrom(StringUtils.StringHexToByteArray(api.getCoinbase())), ma.getMinerAddr()); rsp = sendRequest(Message.Servs.s_hb_VALUE, Message.Funcs.f_minerAddress_VALUE); @@ -191,7 +195,7 @@ public void testProcessMinerAddress() throws Exception { @Test public void testProcessAccountsValue() throws Exception { - Address addr = new AionAddress(Keystore.create("testPwd")); + Address addr = new Address(Keystore.create("testPwd")); rsp = sendRequest(Message.Servs.s_wallet_VALUE, Message.Funcs.f_accounts_VALUE); @@ -202,7 +206,7 @@ public void testProcessAccountsValue() throws Exception { assertEquals( ByteString.copyFrom( - TypeConverter.StringHexToByteArray((String) api.getAccounts().get(0))), + StringUtils.StringHexToByteArray((String) api.getAccounts().get(0))), accts.getAccout(0)); rsp = sendRequest(Message.Servs.s_hb_VALUE, Message.Funcs.f_accounts_VALUE); @@ -226,7 +230,7 @@ public void testProcessBlockNumber() throws Exception { @Test public void testProcessUnlockAccount() { - Address addr = new AionAddress(Keystore.create("testPwd")); + Address addr = new Address(Keystore.create("testPwd")); AccountManager.inst().unlockAccount(addr, "testPwd", 50000); Message.req_unlockAccount reqBody = @@ -256,7 +260,7 @@ public void testProcessUnlockAccount() { @Test public void testProcessGetBalance() throws Exception { - Address addr = new AionAddress(Keystore.create("testPwd")); + Address addr = new Address(Keystore.create("testPwd")); AccountManager.inst().unlockAccount(addr, "testPwd", 50000); @@ -288,7 +292,7 @@ public void testProcessGetBalance() throws Exception { @Test public void testProcessGetNonce() throws Exception { - Address addr = new AionAddress(Keystore.create("testPwd")); + Address addr = new Address(Keystore.create("testPwd")); AccountManager.inst().unlockAccount(addr, "testPwd", 50000); @@ -397,7 +401,7 @@ public void testProcessCompileFail() { @Test public void testProcessGetCode() throws Exception { - Address addr = new AionAddress(Keystore.create("testPwd")); + Address addr = new Address(Keystore.create("testPwd")); AccountManager.inst().unlockAccount(addr, "testPwd", 50000); @@ -433,9 +437,9 @@ public void testProcessGetTR() throws Exception { AionTransaction tx = new AionTransaction( - repo.getNonce(AionAddress.ZERO_ADDRESS()).toByteArray(), - AionAddress.ZERO_ADDRESS(), - AionAddress.ZERO_ADDRESS(), + repo.getNonce(Address.ZERO_ADDRESS()).toByteArray(), + Address.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), BigInteger.ONE.toByteArray(), msg, 100000, @@ -465,7 +469,7 @@ public void testProcessGetTR() throws Exception { Message.rsp_getTransactionReceipt rslt = Message.rsp_getTransactionReceipt.parseFrom(stripHeader(rsp)); - assertEquals(ByteString.copyFrom(AionAddress.ZERO_ADDRESS().toBytes()), rslt.getTo()); + assertEquals(ByteString.copyFrom(Address.ZERO_ADDRESS().toBytes()), rslt.getTo()); rsp = sendRequest(Message.Servs.s_hb_VALUE, Message.Funcs.f_getTransactionReceipt_VALUE); @@ -474,7 +478,7 @@ public void testProcessGetTR() throws Exception { @Test public void testProcessCall() throws Exception { - Address addr = new AionAddress(Keystore.create("testPwd")); + Address addr = new Address(Keystore.create("testPwd")); AccountManager.inst().unlockAccount(addr, "testPwd", 50000); @@ -484,7 +488,7 @@ public void testProcessCall() throws Exception { .setData(ByteString.copyFrom(msg)) .setFrom(ByteString.copyFrom(addr.toBytes())) .setValue(ByteString.copyFrom("1234".getBytes())) - .setTo(ByteString.copyFrom(AionAddress.ZERO_ADDRESS().toBytes())) + .setTo(ByteString.copyFrom(Address.ZERO_ADDRESS().toBytes())) .build(); rsp = @@ -563,9 +567,9 @@ public void testProcessGetTxByBlockHashAndIndex() throws Exception { AionTransaction tx = new AionTransaction( - repo.getNonce(AionAddress.ZERO_ADDRESS()).toByteArray(), - AionAddress.ZERO_ADDRESS(), - AionAddress.ZERO_ADDRESS(), + repo.getNonce(Address.ZERO_ADDRESS()).toByteArray(), + Address.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), BigInteger.ONE.toByteArray(), msg, 100000, @@ -617,9 +621,9 @@ public void testProcessGetTxByBlockNumberAndIndex() throws Exception { AionTransaction tx = new AionTransaction( - repo.getNonce(AionAddress.ZERO_ADDRESS()).toByteArray(), - AionAddress.ZERO_ADDRESS(), - AionAddress.ZERO_ADDRESS(), + repo.getNonce(Address.ZERO_ADDRESS()).toByteArray(), + Address.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), BigInteger.ONE.toByteArray(), msg, 100000, @@ -671,9 +675,9 @@ public void testProcessGetBlockTxCountByNumber() throws Exception { AionTransaction tx = new AionTransaction( - repo.getNonce(AionAddress.ZERO_ADDRESS()).toByteArray(), - AionAddress.ZERO_ADDRESS(), - AionAddress.ZERO_ADDRESS(), + repo.getNonce(Address.ZERO_ADDRESS()).toByteArray(), + Address.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), BigInteger.ONE.toByteArray(), msg, 100000, @@ -723,9 +727,9 @@ public void testProcessGetBlockTxCountByHash() throws Exception { AionTransaction tx = new AionTransaction( - repo.getNonce(AionAddress.ZERO_ADDRESS()).toByteArray(), - AionAddress.ZERO_ADDRESS(), - AionAddress.ZERO_ADDRESS(), + repo.getNonce(Address.ZERO_ADDRESS()).toByteArray(), + Address.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), BigInteger.ONE.toByteArray(), msg, 100000, @@ -775,9 +779,9 @@ public void testProcessGetTxByHash() throws Exception { AionTransaction tx = new AionTransaction( - repo.getNonce(AionAddress.ZERO_ADDRESS()).toByteArray(), - AionAddress.ZERO_ADDRESS(), - AionAddress.ZERO_ADDRESS(), + repo.getNonce(Address.ZERO_ADDRESS()).toByteArray(), + Address.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), BigInteger.ONE.toByteArray(), msg, 100000, @@ -818,8 +822,6 @@ public void testProcessGetTxByHash() throws Exception { @Test @Ignore public void testProcessGetTxCount() throws Exception { - setup(); - AionImpl impl = AionImpl.inst(); AionRepositoryImpl repo = AionRepositoryImpl.inst(); @@ -827,9 +829,9 @@ public void testProcessGetTxCount() throws Exception { AionTransaction tx = new AionTransaction( - repo.getNonce(AionAddress.ZERO_ADDRESS()).toByteArray(), - AionAddress.ZERO_ADDRESS(), - AionAddress.ZERO_ADDRESS(), + repo.getNonce(Address.ZERO_ADDRESS()).toByteArray(), + Address.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), BigInteger.ONE.toByteArray(), msg, 100000, @@ -917,43 +919,6 @@ public void testProcessGetSolcVersion() throws Exception { assertEquals(Message.Retcode.r_fail_service_call_VALUE, rsp[1]); } - @Test - public void testProcessIsSyncing() throws Exception { - rsp = sendRequest(Message.Servs.s_net_VALUE, Message.Funcs.f_isSyncing_VALUE); - - assertEquals(Message.Retcode.r_success_VALUE, rsp[1]); - - Message.rsp_isSyncing rslt = Message.rsp_isSyncing.parseFrom(stripHeader(rsp)); - assertNotEquals(AionImpl.inst().isSyncComplete(), rslt.getSyncing()); - - rsp = sendRequest(Message.Servs.s_hb_VALUE, Message.Funcs.f_isSyncing_VALUE); - - assertEquals(Message.Retcode.r_fail_service_call_VALUE, rsp[1]); - } - - @Test - public void testProcessSyncInfo() throws Exception { - setup(); - AionImpl impl = AionImpl.inst(); - - rsp = sendRequest(Message.Servs.s_net_VALUE, Message.Funcs.f_syncInfo_VALUE); - - assertEquals(Message.Retcode.r_success_VALUE, rsp[1]); - - Message.rsp_syncInfo rslt = Message.rsp_syncInfo.parseFrom(stripHeader(rsp)); - assertNotEquals(impl.isSyncComplete(), rslt.getSyncing()); - assertEquals( - (long) impl.getLocalBestBlockNumber().orElse(0L), (long) rslt.getChainBestBlock()); - assertEquals( - (long) impl.getNetworkBestBlockNumber().orElse(0L), - (long) rslt.getNetworkBestBlock()); - assertEquals(24, rslt.getMaxImportBlocks()); - - rsp = sendRequest(Message.Servs.s_hb_VALUE, Message.Funcs.f_syncInfo_VALUE); - - assertEquals(Message.Retcode.r_fail_service_call_VALUE, rsp[1]); - } - @Test public void testProcessAccountCreateAndLock() throws Exception { Message.req_accountCreate reqBody = @@ -978,13 +943,13 @@ public void testProcessAccountCreateAndLock() throws Exception { ByteString addr = rslt.getAddress(0); assertTrue( api.unlockAccount( - AionAddress.wrap(rslt.getAddress(0).toByteArray()), "passwd0", 500)); + Address.wrap(rslt.getAddress(0).toByteArray()), "passwd0", 500)); assertTrue( api.unlockAccount( - AionAddress.wrap(rslt.getAddress(1).toByteArray()), "passwd1", 500)); + Address.wrap(rslt.getAddress(1).toByteArray()), "passwd1", 500)); assertTrue( api.unlockAccount( - AionAddress.wrap(rslt.getAddress(2).toByteArray()), "passwd2", 500)); + Address.wrap(rslt.getAddress(2).toByteArray()), "passwd2", 500)); rsp = sendRequest(Message.Servs.s_hb_VALUE, Message.Funcs.f_accountCreate_VALUE); @@ -1043,8 +1008,8 @@ public void testProcessEstimateNrg() throws Exception { Message.req_estimateNrg reqBody = Message.req_estimateNrg .newBuilder() - .setFrom(ByteString.copyFrom(AionAddress.ZERO_ADDRESS().toBytes())) - .setTo(ByteString.copyFrom(AionAddress.ZERO_ADDRESS().toBytes())) + .setFrom(ByteString.copyFrom(Address.ZERO_ADDRESS().toBytes())) + .setTo(ByteString.copyFrom(Address.ZERO_ADDRESS().toBytes())) .setNrg(1000) .setNrgPrice(5000) .setData(ByteString.copyFrom(msg)) @@ -1064,10 +1029,10 @@ public void testProcessEstimateNrg() throws Exception { AionTransaction tx = new AionTransaction( AionRepositoryImpl.inst() - .getNonce(AionAddress.ZERO_ADDRESS()) + .getNonce(Address.ZERO_ADDRESS()) .toByteArray(), - AionAddress.ZERO_ADDRESS(), - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), val, msg, 1000, @@ -1083,10 +1048,10 @@ public void testProcessEstimateNrg() throws Exception { @Test public void testProcessExportAccounts() throws Exception { - Address addr1 = new AionAddress(Keystore.create("testPwd1")); + Address addr1 = new Address(Keystore.create("testPwd1")); AccountManager.inst().unlockAccount(addr1, "testPwd1", 50000); - Address addr2 = new AionAddress(Keystore.create("testPwd2")); + Address addr2 = new Address(Keystore.create("testPwd2")); AccountManager.inst().unlockAccount(addr2, "testPwd12", 50000); Message.t_Key tkey1 = @@ -1163,10 +1128,10 @@ public void testProcessImportAccounts() throws Exception { @Test public void testProcessEventRegister() throws Exception { - Address addr1 = new AionAddress(Keystore.create("testPwd1")); + Address addr1 = new Address(Keystore.create("testPwd1")); AccountManager.inst().unlockAccount(addr1, "testPwd1", 50000); - Address addr2 = new AionAddress(Keystore.create("testPwd2")); + Address addr2 = new Address(Keystore.create("testPwd2")); AccountManager.inst().unlockAccount(addr2, "testPwd12", 50000); Message.t_FilterCt fil1 = @@ -1368,14 +1333,14 @@ public void testProcessBlocksLatest() throws Exception { @Test public void testProcessAccountDetails() throws Exception { - Address addr = new AionAddress(Keystore.create("testPwd")); + Address addr = new Address(Keystore.create("testPwd")); AccountManager.inst().unlockAccount(addr, "testPwd", 50000); Message.req_getAccountDetailsByAddressList reqBody = Message.req_getAccountDetailsByAddressList .newBuilder() .addAddresses(ByteString.copyFrom(addr.toBytes())) - .addAddresses(ByteString.copyFrom(AionAddress.ZERO_ADDRESS().toBytes())) + .addAddresses(ByteString.copyFrom(Address.ZERO_ADDRESS().toBytes())) .build(); rsp = diff --git a/modApiServer/test/org/aion/api/server/rpc/ApiWeb3AionTest.java b/modApiServer/test/org/aion/api/server/rpc/ApiWeb3AionTest.java index fbd3832847..605ba5db03 100644 --- a/modApiServer/test/org/aion/api/server/rpc/ApiWeb3AionTest.java +++ b/modApiServer/test/org/aion/api/server/rpc/ApiWeb3AionTest.java @@ -1,14 +1,14 @@ package org.aion.api.server.rpc; -import static org.aion.base.util.TypeConverter.StringHexToBigInteger; +import static org.aion.util.string.StringUtils.StringHexToBigInteger; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.mcf.account.AccountManager; import org.aion.mcf.account.Keystore; -import org.aion.vm.api.interfaces.Address; + import org.aion.zero.impl.blockchain.AionImpl; import org.aion.zero.impl.blockchain.AionPendingStateImpl; import org.json.JSONArray; @@ -29,11 +29,11 @@ public void setup() { @Test public void testEthSignTransaction() { - Address addr = new AionAddress(Keystore.create("testPwd")); + Address addr = new Address(Keystore.create("testPwd")); AccountManager.inst().unlockAccount(addr, "testPwd", 50000); - Address toAddr = new AionAddress(Keystore.create("testPwd")); + Address toAddr = new Address(Keystore.create("testPwd")); JSONObject tx = new JSONObject(); tx.put("from", "0x" + addr.toString()); @@ -78,11 +78,11 @@ public void testEthSignTransaction() { @Test public void testEthSignTransactionAddressParamIsNull() { - Address addr = new AionAddress(Keystore.create("testPwd")); + Address addr = new Address(Keystore.create("testPwd")); AccountManager.inst().unlockAccount(addr, "testPwd", 50000); - Address toAddr = new AionAddress(Keystore.create("testPwd")); + Address toAddr = new Address(Keystore.create("testPwd")); JSONObject tx = new JSONObject(); tx.put("from", addr.toString()); @@ -106,9 +106,9 @@ public void testEthSignTransactionAddressParamIsNull() { @Test public void testEthSignTransactionAccountNotUnlocked() { - Address addr = new AionAddress(Keystore.create("testPwd")); + Address addr = new Address(Keystore.create("testPwd")); - Address toAddr = new AionAddress(Keystore.create("testPwd")); + Address toAddr = new Address(Keystore.create("testPwd")); JSONObject tx = new JSONObject(); tx.put("from", addr.toString()); @@ -132,9 +132,9 @@ public void testEthSignTransactionAccountNotUnlocked() { @Test public void testEthSendTransactionAccountNotUnlocked() { - Address addr = new AionAddress(Keystore.create("testPwd")); + Address addr = new Address(Keystore.create("testPwd")); - Address toAddr = new AionAddress(Keystore.create("testPwd")); + Address toAddr = new Address(Keystore.create("testPwd")); JSONObject tx = new JSONObject(); tx.put("from", addr.toString()); @@ -159,28 +159,28 @@ public void testEthSendTransactionAccountNotUnlocked() { @Test public void testEthGetTransactionCountPending() { JSONObject req = new JSONObject(); - req.put("address", AionAddress.ZERO_ADDRESS().toString()); + req.put("address", Address.ZERO_ADDRESS().toString()); req.put("block", "pending"); RpcMsg rsp = web3Api.eth_getTransactionCount(req); assertNull(rsp.getError()); assertEquals( - impl.getPendingState().getNonce(AionAddress.ZERO_ADDRESS()), + impl.getPendingState().getNonce(Address.ZERO_ADDRESS()), StringHexToBigInteger(rsp.getResult().toString())); } @Test public void testEthGetBalancePending() { JSONObject req = new JSONObject(); - req.put("address", AionAddress.ZERO_ADDRESS().toString()); + req.put("address", Address.ZERO_ADDRESS().toString()); req.put("block", "pending"); RpcMsg rsp = web3Api.eth_getBalance(req); assertNull(rsp.getError()); assertEquals( - impl.getPendingState().getBalance(AionAddress.ZERO_ADDRESS()), + impl.getPendingState().getBalance(Address.ZERO_ADDRESS()), StringHexToBigInteger(rsp.getResult().toString())); } diff --git a/modApiServer/test/org/aion/api/server/types/ArgTxCallTest.java b/modApiServer/test/org/aion/api/server/types/ArgTxCallTest.java index bf10b425ae..e7ce1e8447 100644 --- a/modApiServer/test/org/aion/api/server/types/ArgTxCallTest.java +++ b/modApiServer/test/org/aion/api/server/types/ArgTxCallTest.java @@ -1,11 +1,12 @@ package org.aion.api.server.types; import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertNull; import static org.aion.mcf.vm.Constants.NRG_TRANSACTION_DEFAULT; import static org.aion.mcf.vm.Constants.NRG_CREATE_CONTRACT_DEFAULT; import java.math.BigInteger; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.json.JSONObject; import org.junit.Test; @@ -18,8 +19,8 @@ public void testFromJsonContractCreateDefaults() { JSONObject tx = new JSONObject(); ArgTxCall txCall = ArgTxCall.fromJSON(tx, nrgPrice); - assertEquals(AionAddress.EMPTY_ADDRESS(), txCall.getFrom()); - assertEquals(AionAddress.EMPTY_ADDRESS(), txCall.getTo()); + assertNull(txCall.getFrom()); + assertNull(txCall.getTo()); assertEquals(0, txCall.getData().length); assertEquals(BigInteger.ZERO, txCall.getNonce()); assertEquals(BigInteger.ZERO, txCall.getValue()); @@ -38,8 +39,8 @@ public void testFromJsonTxDefaults() { tx.put("to", toAddr); ArgTxCall txCall = ArgTxCall.fromJSON(tx, nrgPrice); - assertEquals(AionAddress.EMPTY_ADDRESS(), txCall.getFrom()); - assertEquals(new AionAddress(toAddr), txCall.getTo()); + assertNull(txCall.getFrom()); + assertEquals(new Address(toAddr), txCall.getTo()); assertEquals(0, txCall.getData().length); assertEquals(BigInteger.ZERO, txCall.getNonce()); assertEquals(BigInteger.ZERO, txCall.getValue()); diff --git a/modBoot/build.gradle b/modBoot/build.gradle index c702eb23ca..e7129a655f 100644 --- a/modBoot/build.gradle +++ b/modBoot/build.gradle @@ -1,18 +1,18 @@ ext.moduleName = 'aion.boot' dependencies { - compile project(':modAionBase') - compile project(':modCrypto') + compile project(':aion_vm_api') + compile 'network.aion:util4j:0.4.0' + compile 'network.aion:log4j:0.4.0' + compile 'network.aion:crypto4j:0.4.0' + compile project(':modApiServer') compile project(':modAionImpl') - compile project(':modLogger') compile project(':modEvtMgr') compile project(':modP2p') compile project(':modMcf') compile project(':modTxPoolImpl') compile project(':3rdParty.libnzmq') - compile 'com.madgag.spongycastle:prov:1.58.0.0' - compile 'com.madgag.spongycastle:core:1.58.0.0' compile 'org.slf4j:slf4j-api:1.7.25' testCompile 'junit:junit:4.12' diff --git a/modBoot/src/module-info.java b/modBoot/src/module-info.java index d197e37923..b98965e90e 100644 --- a/modBoot/src/module-info.java +++ b/modBoot/src/module-info.java @@ -14,8 +14,8 @@ uses org.aion.evtmgr.EventMgrModule; uses org.aion.log.AionLoggerFactory; - requires aion.base; requires aion.vm; + requires aion.util; exports org.aion; } diff --git a/modBoot/src/org/aion/Aion.java b/modBoot/src/org/aion/Aion.java index da4b3bd892..3ded234ce4 100644 --- a/modBoot/src/org/aion/Aion.java +++ b/modBoot/src/org/aion/Aion.java @@ -196,11 +196,7 @@ public static void main(String args[]) { } // show enabled VMs - String vmStr = "using FVM"; - if (cfg.getVm().isAvmEnabled()) { - vmStr += " & AVM"; - } - logo = appendLogo(logo, vmStr); + logo = appendLogo(logo, "using FVM & AVM"); genLog.info(path); genLog.info(logo); @@ -414,7 +410,7 @@ private static void checkZmqKeyPair() throws IOException { } private static boolean existZmqSecKeyFile(final Path path) { - List files = org.aion.base.io.File.getFiles(path); + List files = org.aion.util.file.File.getFiles(path); for (File file : files) { if (file.getName().contains("zmqCurveSeckey")) { diff --git a/modCrypto/build.gradle b/modCrypto/build.gradle index db167c0a1b..578e5ff20b 100644 --- a/modCrypto/build.gradle +++ b/modCrypto/build.gradle @@ -1,23 +1,140 @@ ext.moduleName = 'aion.crypto' +// set the publish to true when the code ready to push the lib to the maven repo +def publish = false; + +apply plugin: 'maven' +apply plugin: 'signing' + +group = "network.aion" +archivesBaseName = "crypto4j" + +def getCommitHash = { -> + def hashStdOut = new ByteArrayOutputStream() + exec { + commandLine "sh", "-c", "git log --pretty=format:%h | head -1" + standardOutput = hashStdOut + } + + return hashStdOut.toString().trim() +} + dependencies { - compile project(':modUtil') - compile project(':modRlp') + compile 'network.aion:util4j:0.4.0' + compile 'network.aion:rlp4j:0.4.0' + compile 'com.madgag.spongycastle:prov:1.58.0.0' compile 'com.madgag.spongycastle:core:1.58.0.0' compile 'org.slf4j:slf4j-api:1.7.25' - compile 'com.google.guava:guava:25.1-jre' testCompile 'com.google.truth:truth:0.42' testCompile 'org.hamcrest:hamcrest-core:1.3' testCompile "org.mockito:mockito-core:2.23.0" } +tasks.withType(JavaCompile) { + doFirst { + println "Args for for $name are $options.allCompilerArgs" + } +} + +sourceSets { + + if (publish) { + version = "0.4.0" + } else { + jar.baseName = 'crypto4j-' + getCommitHash() + } + + main { + java.srcDirs = ['src/main/java'] + } + test { + java.srcDirs = ['src/test/java'] + } +} + + task compileNative(type: Exec) { - workingDir 'src_native' + workingDir 'src/main/c' commandLine 'make' } +signing { + sign configurations.archives +} +signArchives.enabled = publish + +task sourcesJar(type: Jar) { + classifier = 'sources' + from sourceSets.main.allSource +} +sourcesJar.enabled = publish + + +javadoc { + inputs.property("moduleName", moduleName) + doFirst { + options.addStringOption('-module-path', classpath.asPath) + options.tags = [ "implNote" ] + } +} + + +task javadocJar(type: Jar) { + classifier = 'javadoc' + from javadoc +} +javadocJar.enabled = publish + + +artifacts { + archives sourcesJar, javadocJar +} + +uploadArchives { + repositories { + mavenDeployer { + + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } + + repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { + authentication(userName: ossrhUsername, password: ossrhPassword) + } + + pom.project { + name 'crypto4j' + packaging 'jar' + // optionally artifactId can be defined here + description 'a crypto module for the aion java kernel.' + url 'https://github.com/aionnetwork/aion/tree/master-pre-merge/modCrypto' + + scm { + connection 'scm:git:https://github.com/aionnetwork/aion.git' + developerConnection 'git:https://github.com/aionnetwork/aion.git' + url 'https://github.com/aionnetwork/aion/tree/master' + } + + licenses { + license { + name 'MIT' + url 'https://opensource.org/licenses/MIT' + } + } + + developers { + developer { + id 'aion foundation dev' + name 'aion foundation dev' + email 'toengineering@aion.network' + } + } + } + } + } +} +uploadArchives.enabled = publish + build.dependsOn compileNative test.dependsOn copyNativeLibsForModuleTests clean.dependsOn deleteNativeLibs diff --git a/modCrypto/src_native/Makefile b/modCrypto/src/main/c/Makefile similarity index 94% rename from modCrypto/src_native/Makefile rename to modCrypto/src/main/c/Makefile index dbb94e7a78..5ed9aa0470 100644 --- a/modCrypto/src_native/Makefile +++ b/modCrypto/src/main/c/Makefile @@ -1,4 +1,4 @@ -AION_HOME=../.. +AION_HOME=../../../.. JAVA_HOME=/usr/lib/jvm/jdk-11.0.1 diff --git a/modCrypto/src_native/blake2-config.h b/modCrypto/src/main/c/blake2-config.h similarity index 100% rename from modCrypto/src_native/blake2-config.h rename to modCrypto/src/main/c/blake2-config.h diff --git a/modCrypto/src_native/blake2-impl.h b/modCrypto/src/main/c/blake2-impl.h similarity index 100% rename from modCrypto/src_native/blake2-impl.h rename to modCrypto/src/main/c/blake2-impl.h diff --git a/modCrypto/src_native/blake2.h b/modCrypto/src/main/c/blake2.h similarity index 100% rename from modCrypto/src_native/blake2.h rename to modCrypto/src/main/c/blake2.h diff --git a/modCrypto/src_native/blake2b-load-sse2.h b/modCrypto/src/main/c/blake2b-load-sse2.h similarity index 100% rename from modCrypto/src_native/blake2b-load-sse2.h rename to modCrypto/src/main/c/blake2b-load-sse2.h diff --git a/modCrypto/src_native/blake2b-load-sse41.h b/modCrypto/src/main/c/blake2b-load-sse41.h similarity index 100% rename from modCrypto/src_native/blake2b-load-sse41.h rename to modCrypto/src/main/c/blake2b-load-sse41.h diff --git a/modCrypto/src_native/blake2b-round.h b/modCrypto/src/main/c/blake2b-round.h similarity index 100% rename from modCrypto/src_native/blake2b-round.h rename to modCrypto/src/main/c/blake2b-round.h diff --git a/modCrypto/src_native/blake2b.c b/modCrypto/src/main/c/blake2b.c similarity index 100% rename from modCrypto/src_native/blake2b.c rename to modCrypto/src/main/c/blake2b.c diff --git a/modCrypto/src_native/org_aion_crypto_hash_Blake2bNative.c b/modCrypto/src/main/c/org_aion_crypto_hash_Blake2bNative.c similarity index 100% rename from modCrypto/src_native/org_aion_crypto_hash_Blake2bNative.c rename to modCrypto/src/main/c/org_aion_crypto_hash_Blake2bNative.c diff --git a/modCrypto/src_native/org_aion_crypto_hash_Blake2bNative.h b/modCrypto/src/main/c/org_aion_crypto_hash_Blake2bNative.h similarity index 100% rename from modCrypto/src_native/org_aion_crypto_hash_Blake2bNative.h rename to modCrypto/src/main/c/org_aion_crypto_hash_Blake2bNative.h diff --git a/modCrypto/src/module-info.java b/modCrypto/src/main/java/module-info.java similarity index 100% rename from modCrypto/src/module-info.java rename to modCrypto/src/main/java/module-info.java diff --git a/modCrypto/src/org/aion/crypto/AddressSpecs.java b/modCrypto/src/main/java/org/aion/crypto/AddressSpecs.java similarity index 98% rename from modCrypto/src/org/aion/crypto/AddressSpecs.java rename to modCrypto/src/main/java/org/aion/crypto/AddressSpecs.java index fba0d1122d..e4c8776d44 100644 --- a/modCrypto/src/org/aion/crypto/AddressSpecs.java +++ b/modCrypto/src/main/java/org/aion/crypto/AddressSpecs.java @@ -47,7 +47,6 @@ public static Optional checksummedAddress(String address) { b.get(i) ? Character.toUpperCase(caddr[i]) : Character.toLowerCase(caddr[i]); - continue; } } return Optional.of(String.valueOf(caddr)); diff --git a/modCrypto/src/org/aion/crypto/ECKey.java b/modCrypto/src/main/java/org/aion/crypto/ECKey.java similarity index 100% rename from modCrypto/src/org/aion/crypto/ECKey.java rename to modCrypto/src/main/java/org/aion/crypto/ECKey.java diff --git a/modCrypto/src/org/aion/crypto/ECKeyFac.java b/modCrypto/src/main/java/org/aion/crypto/ECKeyFac.java similarity index 100% rename from modCrypto/src/org/aion/crypto/ECKeyFac.java rename to modCrypto/src/main/java/org/aion/crypto/ECKeyFac.java diff --git a/modCrypto/src/org/aion/crypto/HashUtil.java b/modCrypto/src/main/java/org/aion/crypto/HashUtil.java similarity index 99% rename from modCrypto/src/org/aion/crypto/HashUtil.java rename to modCrypto/src/main/java/org/aion/crypto/HashUtil.java index 0f6467e228..114cfd5d43 100644 --- a/modCrypto/src/org/aion/crypto/HashUtil.java +++ b/modCrypto/src/main/java/org/aion/crypto/HashUtil.java @@ -12,7 +12,7 @@ import org.aion.crypto.hash.Blake2b; import org.aion.crypto.hash.Blake2bNative; import org.aion.rlp.RLP; -import org.aion.util.NativeLoader; +import org.aion.util.file.NativeLoader; import org.spongycastle.crypto.Digest; import org.spongycastle.crypto.digests.KeccakDigest; import org.spongycastle.crypto.digests.RIPEMD160Digest; diff --git a/modCrypto/src/org/aion/crypto/ISignature.java b/modCrypto/src/main/java/org/aion/crypto/ISignature.java similarity index 100% rename from modCrypto/src/org/aion/crypto/ISignature.java rename to modCrypto/src/main/java/org/aion/crypto/ISignature.java diff --git a/modCrypto/src/org/aion/crypto/SignatureFac.java b/modCrypto/src/main/java/org/aion/crypto/SignatureFac.java similarity index 100% rename from modCrypto/src/org/aion/crypto/SignatureFac.java rename to modCrypto/src/main/java/org/aion/crypto/SignatureFac.java diff --git a/modCrypto/src/org/aion/crypto/ecdsa/ECDSASignature.java b/modCrypto/src/main/java/org/aion/crypto/ecdsa/ECDSASignature.java similarity index 94% rename from modCrypto/src/org/aion/crypto/ecdsa/ECDSASignature.java rename to modCrypto/src/main/java/org/aion/crypto/ecdsa/ECDSASignature.java index 5dac267b31..cf1c30315c 100644 --- a/modCrypto/src/org/aion/crypto/ecdsa/ECDSASignature.java +++ b/modCrypto/src/main/java/org/aion/crypto/ecdsa/ECDSASignature.java @@ -61,7 +61,7 @@ public byte[] getPubkey(byte[] msg) { * @param r * @param s */ - public ECDSASignature(BigInteger r, BigInteger s) { + ECDSASignature(BigInteger r, BigInteger s) { this.r = r; this.s = s; } @@ -136,9 +136,7 @@ public static boolean isLessThan(BigInteger valueA, BigInteger valueB) { } public static ECDSASignature decodeFromDER(byte[] bytes) { - ASN1InputStream decoder = null; - try { - decoder = new ASN1InputStream(bytes); + try (ASN1InputStream decoder = new ASN1InputStream(bytes)) { DLSequence seq = (DLSequence) decoder.readObject(); if (seq == null) { throw new RuntimeException("Reached past end of ASN.1 stream."); @@ -157,13 +155,6 @@ public static ECDSASignature decodeFromDER(byte[] bytes) { return new ECDSASignature(r.getPositiveValue(), s.getPositiveValue()); } catch (IOException e) { throw new RuntimeException(e); - } finally { - if (decoder != null) { - try { - decoder.close(); - } catch (IOException x) { - } - } } } @@ -177,7 +168,7 @@ public static ECDSASignature decodeFromDER(byte[] bytes) { * * @return - */ - public ECDSASignature toCanonicalised() { + ECDSASignature toCanonicalised() { if (s.compareTo(HALF_CURVE_ORDER) > 0) { // The order of the curve is the number of valid points that exist // on that curve. If S is in the upper diff --git a/modCrypto/src/org/aion/crypto/ecdsa/ECKeySecp256k1.java b/modCrypto/src/main/java/org/aion/crypto/ecdsa/ECKeySecp256k1.java similarity index 98% rename from modCrypto/src/org/aion/crypto/ecdsa/ECKeySecp256k1.java rename to modCrypto/src/main/java/org/aion/crypto/ecdsa/ECKeySecp256k1.java index 8c53ebc6dd..9129189659 100644 --- a/modCrypto/src/org/aion/crypto/ecdsa/ECKeySecp256k1.java +++ b/modCrypto/src/main/java/org/aion/crypto/ecdsa/ECKeySecp256k1.java @@ -72,7 +72,7 @@ */ public class ECKeySecp256k1 implements ECKey, Serializable { - private static final Logger logger = LoggerFactory.getLogger(ECKeySecp256k1.class); + private static final Logger logger = LoggerFactory.getLogger("CRYPTO"); public static final BigInteger ETH_SECP256K1N = new BigInteger("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16); @@ -85,7 +85,8 @@ public class ECKeySecp256k1 implements ECKey, Serializable { /** * Equal to CURVE.getN().shiftRight(1), used for canonicalising the S value of a signature. * ECDSA signatures are mutable in the sense that for a given (R, S) pair, then both (R, S) and - * (R, N - S mod N) are valid signatures. Canonical signatures are those where 1 <= S <= N/2 + * (R, N - S mod N) are valid signatures. Canonical signatures are those where 1 less equal then + * S less equal then N/2 * *

    See * https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#Low_S_values_in_signatures @@ -114,7 +115,7 @@ public class ECKeySecp256k1 implements ECKey, Serializable { // TODO: Redesign this class to use consistent internals and more efficient // serialization. private final PrivateKey privKey; - protected final ECPoint pub; + private final ECPoint pub; // the Java Cryptographic Architecture provider to use for Signature // this is set along with the PrivateKey privKey and must be compatible @@ -385,7 +386,7 @@ public boolean hasPrivKey() { /** * Returns public key bytes from the given private key. To convert a byte array into a - * BigInteger, use new BigInteger(1, bytes); + * BigInteger, use new BigInteger(1, bytes); * * @param privKey - * @param compressed - @@ -810,7 +811,7 @@ public boolean verify(byte[] data, ECDSASignature signature, byte[] pub) { } } - /** @TODO: yao Verify from Base64 encoded signature Switch to DER encoding in future */ + /** TODO: yao Verify from Base64 encoded signature Switch to DER encoding in future */ public boolean verify(byte[] messageHash, String signatureBase64) throws SignatureException { byte[] signatureEncoded; try { @@ -888,18 +889,13 @@ public boolean isPubKeyCanonical() { public boolean isPubKeyCanonical(byte[] pubkey) { if (pubkey[0] == 0x04) { // Uncompressed pubkey - if (pubkey.length != 65) { - return false; - } + return pubkey.length == 65; } else if (pubkey[0] == 0x02 || pubkey[0] == 0x03) { // Compressed pubkey - if (pubkey.length != 33) { - return false; - } + return pubkey.length == 33; } else { return false; } - return true; } /** diff --git a/modCrypto/src/org/aion/crypto/ed25519/Curve25519.java b/modCrypto/src/main/java/org/aion/crypto/ed25519/Curve25519.java similarity index 96% rename from modCrypto/src/org/aion/crypto/ed25519/Curve25519.java rename to modCrypto/src/main/java/org/aion/crypto/ed25519/Curve25519.java index cc2f137e74..4081bbe917 100644 --- a/modCrypto/src/org/aion/crypto/ed25519/Curve25519.java +++ b/modCrypto/src/main/java/org/aion/crypto/ed25519/Curve25519.java @@ -140,7 +140,7 @@ public static final boolean sign(byte[] v, byte[] h, byte[] x, byte[] s) { * h [in] signature hash * P [in] public key */ - public static final void verify(byte[] Y, byte[] v, byte[] h, byte[] P) { + public static void verify(byte[] Y, byte[] v, byte[] h, byte[] P) { /* Y = v abs(P) + h G */ byte[] d = new byte[32]; long10[] p = new long10[] {new long10(), new long10()}, diff --git a/modCrypto/src/org/aion/crypto/ed25519/ECKeyEd25519.java b/modCrypto/src/main/java/org/aion/crypto/ed25519/ECKeyEd25519.java similarity index 98% rename from modCrypto/src/org/aion/crypto/ed25519/ECKeyEd25519.java rename to modCrypto/src/main/java/org/aion/crypto/ed25519/ECKeyEd25519.java index 9de63422f5..e6040a6135 100644 --- a/modCrypto/src/org/aion/crypto/ed25519/ECKeyEd25519.java +++ b/modCrypto/src/main/java/org/aion/crypto/ed25519/ECKeyEd25519.java @@ -4,8 +4,8 @@ import org.aion.crypto.AddressSpecs; import org.aion.crypto.ECKey; import org.aion.crypto.ISignature; -import org.aion.util.NativeLoader; import org.aion.util.bytes.ByteUtil; +import org.aion.util.file.NativeLoader; import org.libsodium.jni.NaCl; import org.libsodium.jni.Sodium; import org.spongycastle.util.encoders.Hex; diff --git a/modCrypto/src/org/aion/crypto/ed25519/Ed25519Signature.java b/modCrypto/src/main/java/org/aion/crypto/ed25519/Ed25519Signature.java similarity index 100% rename from modCrypto/src/org/aion/crypto/ed25519/Ed25519Signature.java rename to modCrypto/src/main/java/org/aion/crypto/ed25519/Ed25519Signature.java diff --git a/modCrypto/src/org/aion/crypto/hash/Blake2b.java b/modCrypto/src/main/java/org/aion/crypto/hash/Blake2b.java similarity index 99% rename from modCrypto/src/org/aion/crypto/hash/Blake2b.java rename to modCrypto/src/main/java/org/aion/crypto/hash/Blake2b.java index 24ef5c02c1..e77d95a540 100644 --- a/modCrypto/src/org/aion/crypto/hash/Blake2b.java +++ b/modCrypto/src/main/java/org/aion/crypto/hash/Blake2b.java @@ -63,7 +63,7 @@ interface Spec { /** max tree inner length value */ int MAX_TREE_INNER_LEN = 0xFF; - /** initialization values map ref-Spec IV[i] -> slice iv[i*8:i*8+7] */ + /** initialization values map ref-Spec IV[i] to slice iv[i*8:i*8+7] */ long[] IV = { 0x6a09e667f3bcc908L, 0xbb67ae8584caa73bL, diff --git a/modCrypto/src/org/aion/crypto/hash/Blake2bNative.java b/modCrypto/src/main/java/org/aion/crypto/hash/Blake2bNative.java similarity index 100% rename from modCrypto/src/org/aion/crypto/hash/Blake2bNative.java rename to modCrypto/src/main/java/org/aion/crypto/hash/Blake2bNative.java diff --git a/modCrypto/src/org/aion/crypto/jce/ECAlgorithmParameters.java b/modCrypto/src/main/java/org/aion/crypto/jce/ECAlgorithmParameters.java similarity index 100% rename from modCrypto/src/org/aion/crypto/jce/ECAlgorithmParameters.java rename to modCrypto/src/main/java/org/aion/crypto/jce/ECAlgorithmParameters.java diff --git a/modCrypto/src/org/aion/crypto/jce/ECKeyAgreement.java b/modCrypto/src/main/java/org/aion/crypto/jce/ECKeyAgreement.java similarity index 100% rename from modCrypto/src/org/aion/crypto/jce/ECKeyAgreement.java rename to modCrypto/src/main/java/org/aion/crypto/jce/ECKeyAgreement.java diff --git a/modCrypto/src/org/aion/crypto/jce/ECKeyFactory.java b/modCrypto/src/main/java/org/aion/crypto/jce/ECKeyFactory.java similarity index 100% rename from modCrypto/src/org/aion/crypto/jce/ECKeyFactory.java rename to modCrypto/src/main/java/org/aion/crypto/jce/ECKeyFactory.java diff --git a/modCrypto/src/org/aion/crypto/jce/ECKeyPairGenerator.java b/modCrypto/src/main/java/org/aion/crypto/jce/ECKeyPairGenerator.java similarity index 100% rename from modCrypto/src/org/aion/crypto/jce/ECKeyPairGenerator.java rename to modCrypto/src/main/java/org/aion/crypto/jce/ECKeyPairGenerator.java diff --git a/modCrypto/src/org/aion/crypto/jce/ECSignatureFactory.java b/modCrypto/src/main/java/org/aion/crypto/jce/ECSignatureFactory.java similarity index 100% rename from modCrypto/src/org/aion/crypto/jce/ECSignatureFactory.java rename to modCrypto/src/main/java/org/aion/crypto/jce/ECSignatureFactory.java diff --git a/modCrypto/src/org/aion/crypto/jce/SpongyCastleProvider.java b/modCrypto/src/main/java/org/aion/crypto/jce/SpongyCastleProvider.java similarity index 100% rename from modCrypto/src/org/aion/crypto/jce/SpongyCastleProvider.java rename to modCrypto/src/main/java/org/aion/crypto/jce/SpongyCastleProvider.java diff --git a/modCrypto/src/org/libsodium/jni/NaCl.java b/modCrypto/src/main/java/org/libsodium/jni/NaCl.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/NaCl.java rename to modCrypto/src/main/java/org/libsodium/jni/NaCl.java diff --git a/modCrypto/src/org/libsodium/jni/Sodium.java b/modCrypto/src/main/java/org/libsodium/jni/Sodium.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/Sodium.java rename to modCrypto/src/main/java/org/libsodium/jni/Sodium.java diff --git a/modCrypto/src/org/libsodium/jni/SodiumConstants.java b/modCrypto/src/main/java/org/libsodium/jni/SodiumConstants.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/SodiumConstants.java rename to modCrypto/src/main/java/org/libsodium/jni/SodiumConstants.java diff --git a/modCrypto/src/org/libsodium/jni/SodiumJNI.java b/modCrypto/src/main/java/org/libsodium/jni/SodiumJNI.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/SodiumJNI.java rename to modCrypto/src/main/java/org/libsodium/jni/SodiumJNI.java diff --git a/modCrypto/src/org/libsodium/jni/crypto/Box.java b/modCrypto/src/main/java/org/libsodium/jni/crypto/Box.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/crypto/Box.java rename to modCrypto/src/main/java/org/libsodium/jni/crypto/Box.java diff --git a/modCrypto/src/org/libsodium/jni/crypto/Hash.java b/modCrypto/src/main/java/org/libsodium/jni/crypto/Hash.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/crypto/Hash.java rename to modCrypto/src/main/java/org/libsodium/jni/crypto/Hash.java diff --git a/modCrypto/src/org/libsodium/jni/crypto/Point.java b/modCrypto/src/main/java/org/libsodium/jni/crypto/Point.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/crypto/Point.java rename to modCrypto/src/main/java/org/libsodium/jni/crypto/Point.java diff --git a/modCrypto/src/org/libsodium/jni/crypto/Random.java b/modCrypto/src/main/java/org/libsodium/jni/crypto/Random.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/crypto/Random.java rename to modCrypto/src/main/java/org/libsodium/jni/crypto/Random.java diff --git a/modCrypto/src/org/libsodium/jni/crypto/SecretBox.java b/modCrypto/src/main/java/org/libsodium/jni/crypto/SecretBox.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/crypto/SecretBox.java rename to modCrypto/src/main/java/org/libsodium/jni/crypto/SecretBox.java diff --git a/modCrypto/src/org/libsodium/jni/crypto/Util.java b/modCrypto/src/main/java/org/libsodium/jni/crypto/Util.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/crypto/Util.java rename to modCrypto/src/main/java/org/libsodium/jni/crypto/Util.java diff --git a/modCrypto/src/org/libsodium/jni/encoders/Encoder.java b/modCrypto/src/main/java/org/libsodium/jni/encoders/Encoder.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/encoders/Encoder.java rename to modCrypto/src/main/java/org/libsodium/jni/encoders/Encoder.java diff --git a/modCrypto/src/org/libsodium/jni/encoders/Hex.java b/modCrypto/src/main/java/org/libsodium/jni/encoders/Hex.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/encoders/Hex.java rename to modCrypto/src/main/java/org/libsodium/jni/encoders/Hex.java diff --git a/modCrypto/src/org/libsodium/jni/encoders/Raw.java b/modCrypto/src/main/java/org/libsodium/jni/encoders/Raw.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/encoders/Raw.java rename to modCrypto/src/main/java/org/libsodium/jni/encoders/Raw.java diff --git a/modCrypto/src/org/libsodium/jni/keys/KeyPair.java b/modCrypto/src/main/java/org/libsodium/jni/keys/KeyPair.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/keys/KeyPair.java rename to modCrypto/src/main/java/org/libsodium/jni/keys/KeyPair.java diff --git a/modCrypto/src/org/libsodium/jni/keys/PrivateKey.java b/modCrypto/src/main/java/org/libsodium/jni/keys/PrivateKey.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/keys/PrivateKey.java rename to modCrypto/src/main/java/org/libsodium/jni/keys/PrivateKey.java diff --git a/modCrypto/src/org/libsodium/jni/keys/PublicKey.java b/modCrypto/src/main/java/org/libsodium/jni/keys/PublicKey.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/keys/PublicKey.java rename to modCrypto/src/main/java/org/libsodium/jni/keys/PublicKey.java diff --git a/modCrypto/src/org/libsodium/jni/keys/SigningKey.java b/modCrypto/src/main/java/org/libsodium/jni/keys/SigningKey.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/keys/SigningKey.java rename to modCrypto/src/main/java/org/libsodium/jni/keys/SigningKey.java diff --git a/modCrypto/src/org/libsodium/jni/keys/VerifyKey.java b/modCrypto/src/main/java/org/libsodium/jni/keys/VerifyKey.java similarity index 100% rename from modCrypto/src/org/libsodium/jni/keys/VerifyKey.java rename to modCrypto/src/main/java/org/libsodium/jni/keys/VerifyKey.java diff --git a/modCrypto/src/org/aion/crypto/Hash256.java b/modCrypto/src/org/aion/crypto/Hash256.java deleted file mode 100644 index eab2837c35..0000000000 --- a/modCrypto/src/org/aion/crypto/Hash256.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.aion.crypto; - -/** @author jin */ -public interface Hash256 { - - byte[] h256(byte[] in); - - byte[] h256(byte[] in1, byte[] in2); -} diff --git a/modCrypto/test/org/aion/crypto/ChecksumTest.java b/modCrypto/src/test/java/org/aion/crypto/ChecksumTest.java similarity index 100% rename from modCrypto/test/org/aion/crypto/ChecksumTest.java rename to modCrypto/src/test/java/org/aion/crypto/ChecksumTest.java diff --git a/modCrypto/test/org/aion/crypto/ECKeyBench.java b/modCrypto/src/test/java/org/aion/crypto/ECKeyBench.java similarity index 100% rename from modCrypto/test/org/aion/crypto/ECKeyBench.java rename to modCrypto/src/test/java/org/aion/crypto/ECKeyBench.java diff --git a/modCrypto/test/org/aion/crypto/ECKeyTest.java b/modCrypto/src/test/java/org/aion/crypto/ECKeyTest.java similarity index 100% rename from modCrypto/test/org/aion/crypto/ECKeyTest.java rename to modCrypto/src/test/java/org/aion/crypto/ECKeyTest.java diff --git a/modCrypto/test/org/aion/crypto/HashBench.java b/modCrypto/src/test/java/org/aion/crypto/HashBench.java similarity index 100% rename from modCrypto/test/org/aion/crypto/HashBench.java rename to modCrypto/src/test/java/org/aion/crypto/HashBench.java diff --git a/modCrypto/test/org/aion/crypto/HashTest.java b/modCrypto/src/test/java/org/aion/crypto/HashTest.java similarity index 100% rename from modCrypto/test/org/aion/crypto/HashTest.java rename to modCrypto/src/test/java/org/aion/crypto/HashTest.java diff --git a/modCrypto/test/org/aion/crypto/SignatureTest.java b/modCrypto/src/test/java/org/aion/crypto/SignatureTest.java similarity index 100% rename from modCrypto/test/org/aion/crypto/SignatureTest.java rename to modCrypto/src/test/java/org/aion/crypto/SignatureTest.java diff --git a/modCrypto/test/org/aion/crypto/ecdsa/ECDSATest.java b/modCrypto/src/test/java/org/aion/crypto/ecdsa/ECDSATest.java similarity index 100% rename from modCrypto/test/org/aion/crypto/ecdsa/ECDSATest.java rename to modCrypto/src/test/java/org/aion/crypto/ecdsa/ECDSATest.java diff --git a/modCrypto/test/org/aion/crypto/hash/Blake2bTest.java b/modCrypto/src/test/java/org/aion/crypto/hash/Blake2bTest.java similarity index 100% rename from modCrypto/test/org/aion/crypto/hash/Blake2bTest.java rename to modCrypto/src/test/java/org/aion/crypto/hash/Blake2bTest.java diff --git a/modDbImpl/build.gradle b/modDbImpl/build.gradle index 3053406d5b..21ff9f7419 100644 --- a/modDbImpl/build.gradle +++ b/modDbImpl/build.gradle @@ -14,8 +14,10 @@ sourceSets { } dependencies { - compile project(':modAionBase') - compile project(':modLogger') + compile project(':aion_vm_api') + compile 'network.aion:util4j:0.4.0' + compile 'network.aion:log4j:0.4.0' + compile 'com.google.guava:guava:25.1-jre' compile 'org.slf4j:slf4j-api:1.7.25' compile group: 'org.ethereum', name: 'leveldbjni-all', version: '1.18.3' diff --git a/modDbImpl/src/module-info.java b/modDbImpl/src/module-info.java index 4569a0f7ad..62b434d9ba 100644 --- a/modDbImpl/src/module-info.java +++ b/modDbImpl/src/module-info.java @@ -1,12 +1,13 @@ module aion.db.impl { requires slf4j.api; requires aion.log; - requires aion.base; - requires leveldbjni.all; + requires aion.util; + requires aion.vm.api; requires rocksdbjni; requires h2.mvstore; requires com.google.common; requires mongo.java.driver; + requires leveldbjni.all; exports org.aion.db.impl; exports org.aion.db.impl.leveldb; diff --git a/modDbImpl/src/org/aion/db/generic/CacheIteratorWrapper.java b/modDbImpl/src/org/aion/db/generic/CacheIteratorWrapper.java index d95bb3c67c..60d36cf01f 100644 --- a/modDbImpl/src/org/aion/db/generic/CacheIteratorWrapper.java +++ b/modDbImpl/src/org/aion/db/generic/CacheIteratorWrapper.java @@ -4,7 +4,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; /** * A wrapper for the iterator needed by {@link DatabaseWithCache} conforming to the {@link Iterator} diff --git a/modDbImpl/src/org/aion/db/generic/DatabaseWithCache.java b/modDbImpl/src/org/aion/db/generic/DatabaseWithCache.java index 02de10abf7..1659aaf5b9 100644 --- a/modDbImpl/src/org/aion/db/generic/DatabaseWithCache.java +++ b/modDbImpl/src/org/aion/db/generic/DatabaseWithCache.java @@ -10,12 +10,12 @@ import java.util.Iterator; import java.util.Map; import java.util.Optional; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.db.PersistenceMethod; -import org.aion.base.util.ByteArrayWrapper; import org.aion.db.impl.AbstractDB; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.PersistenceMethod; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; +import org.aion.types.ByteArrayWrapper; import org.slf4j.Logger; /** @@ -25,7 +25,7 @@ * @author Alexandra Roatis * @implNote Assumes persistent database. Overwrite method if this is not the case. */ -public class DatabaseWithCache implements IByteArrayKeyValueDatabase { +public class DatabaseWithCache implements ByteArrayKeyValueDatabase { private static final Logger LOG = AionLoggerFactory.getLogger(LogEnum.DB.name()); diff --git a/modDbImpl/src/org/aion/db/generic/LockedDatabase.java b/modDbImpl/src/org/aion/db/generic/LockedDatabase.java index 2d33ff1501..6b1448672b 100644 --- a/modDbImpl/src/org/aion/db/generic/LockedDatabase.java +++ b/modDbImpl/src/org/aion/db/generic/LockedDatabase.java @@ -6,8 +6,8 @@ import java.util.Optional; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.db.PersistenceMethod; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.PersistenceMethod; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.slf4j.Logger; @@ -20,17 +20,17 @@ * * @author Alexandra Roatis */ -public class LockedDatabase implements IByteArrayKeyValueDatabase { +public class LockedDatabase implements ByteArrayKeyValueDatabase { /** Unlocked database. */ - protected final IByteArrayKeyValueDatabase database; + protected final ByteArrayKeyValueDatabase database; /** Read-write lock allowing concurrent reads and single write operations. */ protected final ReadWriteLock lock = new ReentrantReadWriteLock(); protected static final Logger LOG = AionLoggerFactory.getLogger(LogEnum.DB.name()); - public LockedDatabase(IByteArrayKeyValueDatabase _unlockedDatabase) { + public LockedDatabase(ByteArrayKeyValueDatabase _unlockedDatabase) { this.database = _unlockedDatabase; } diff --git a/modDbImpl/src/org/aion/db/generic/SpecialLockedDatabase.java b/modDbImpl/src/org/aion/db/generic/SpecialLockedDatabase.java index 942d5701ff..4b6b514701 100644 --- a/modDbImpl/src/org/aion/db/generic/SpecialLockedDatabase.java +++ b/modDbImpl/src/org/aion/db/generic/SpecialLockedDatabase.java @@ -2,7 +2,7 @@ import java.util.Collection; import java.util.Map; -import org.aion.base.db.IByteArrayKeyValueDatabase; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; /** * Implements locking functionality for a database that is mostly thread-safe except for open and @@ -10,9 +10,9 @@ * * @author Alexandra Roatis */ -public class SpecialLockedDatabase extends LockedDatabase implements IByteArrayKeyValueDatabase { +public class SpecialLockedDatabase extends LockedDatabase implements ByteArrayKeyValueDatabase { - public SpecialLockedDatabase(IByteArrayKeyValueDatabase _unlockedDatabase) { + public SpecialLockedDatabase(ByteArrayKeyValueDatabase _unlockedDatabase) { super(_unlockedDatabase); } diff --git a/modDbImpl/src/org/aion/db/generic/TimedDatabase.java b/modDbImpl/src/org/aion/db/generic/TimedDatabase.java index c47db63659..fee344e29d 100644 --- a/modDbImpl/src/org/aion/db/generic/TimedDatabase.java +++ b/modDbImpl/src/org/aion/db/generic/TimedDatabase.java @@ -4,11 +4,11 @@ import java.util.Iterator; import java.util.Map; import java.util.Optional; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.db.PersistenceMethod; -import org.aion.base.util.Hex; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.PersistenceMethod; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; +import org.aion.util.conversions.Hex; import org.slf4j.Logger; /** @@ -16,14 +16,14 @@ * * @author Alexandra Roatis */ -public class TimedDatabase implements IByteArrayKeyValueDatabase { +public class TimedDatabase implements ByteArrayKeyValueDatabase { /** Unlocked database. */ - protected final IByteArrayKeyValueDatabase database; + protected final ByteArrayKeyValueDatabase database; protected static final Logger LOG = AionLoggerFactory.getLogger(LogEnum.DB.name()); - public TimedDatabase(IByteArrayKeyValueDatabase _database) { + public TimedDatabase(ByteArrayKeyValueDatabase _database) { this.database = _database; } diff --git a/modDbImpl/src/org/aion/db/impl/AbstractDB.java b/modDbImpl/src/org/aion/db/impl/AbstractDB.java index 447f53f11c..813f387548 100644 --- a/modDbImpl/src/org/aion/db/impl/AbstractDB.java +++ b/modDbImpl/src/org/aion/db/impl/AbstractDB.java @@ -8,11 +8,11 @@ import java.util.Objects; import java.util.Optional; import java.util.stream.Stream; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.db.PersistenceMethod; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.PersistenceMethod; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; +import org.aion.types.ByteArrayWrapper; import org.slf4j.Logger; /** @@ -21,7 +21,7 @@ * @author Alexandra Roatis * @implNote Assumes persistent database. Overwrite method if this is not the case. */ -public abstract class AbstractDB implements IByteArrayKeyValueDatabase { +public abstract class AbstractDB implements ByteArrayKeyValueDatabase { protected static final Logger LOG = AionLoggerFactory.getLogger(LogEnum.DB.name()); diff --git a/modDbImpl/src/org/aion/db/impl/DBVendor.java b/modDbImpl/src/org/aion/db/impl/DBVendor.java index 37209f6da7..0bc45bb16b 100644 --- a/modDbImpl/src/org/aion/db/impl/DBVendor.java +++ b/modDbImpl/src/org/aion/db/impl/DBVendor.java @@ -3,8 +3,8 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import org.aion.base.db.PersistenceMethod; import org.aion.db.impl.rocksdb.RocksDBWrapper; +import org.aion.interfaces.db.PersistenceMethod; // @ThreadSafe public enum DBVendor { diff --git a/modDbImpl/src/org/aion/db/impl/DatabaseFactory.java b/modDbImpl/src/org/aion/db/impl/DatabaseFactory.java index ad3363e5ba..367f38d7d4 100644 --- a/modDbImpl/src/org/aion/db/impl/DatabaseFactory.java +++ b/modDbImpl/src/org/aion/db/impl/DatabaseFactory.java @@ -1,7 +1,6 @@ package org.aion.db.impl; import java.util.Properties; -import org.aion.base.db.IByteArrayKeyValueDatabase; import org.aion.db.generic.DatabaseWithCache; import org.aion.db.generic.LockedDatabase; import org.aion.db.generic.SpecialLockedDatabase; @@ -14,12 +13,13 @@ import org.aion.db.impl.mongodb.MongoDB; import org.aion.db.impl.rocksdb.RocksDBConstants; import org.aion.db.impl.rocksdb.RocksDBWrapper; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.slf4j.Logger; /** - * Returns an instance of {@link IByteArrayKeyValueDatabase} based on the given properties. + * Returns an instance of {@link ByteArrayKeyValueDatabase} based on the given properties. * * @author Alexandra Roatis */ @@ -54,14 +54,14 @@ public static class Props { public static final String READ_BUFFER_SIZE = "read_buffer_size"; } - public static IByteArrayKeyValueDatabase connect(Properties info) { + public static ByteArrayKeyValueDatabase connect(Properties info) { return connect(info, false); } - public static IByteArrayKeyValueDatabase connect(Properties info, boolean debug) { + public static ByteArrayKeyValueDatabase connect(Properties info, boolean debug) { DBVendor dbType = DBVendor.fromString(info.getProperty(Props.DB_TYPE)); - IByteArrayKeyValueDatabase db; + ByteArrayKeyValueDatabase db; if (dbType == DBVendor.UNKNOWN) { // the driver, if correct should check path and name @@ -96,7 +96,7 @@ public static IByteArrayKeyValueDatabase connect(Properties info, boolean debug) * * @return A database implementation with read-write locks. */ - private static IByteArrayKeyValueDatabase connectWithLocks(Properties info) { + private static ByteArrayKeyValueDatabase connectWithLocks(Properties info) { boolean enableHeapCache = getBoolean(info, Props.ENABLE_HEAP_CACHE); if (enableHeapCache) { return new LockedDatabase(connectWithCache(info)); @@ -111,7 +111,7 @@ private static IByteArrayKeyValueDatabase connectWithLocks(Properties info) { } /** @return A database implementation with a caching layer. */ - private static IByteArrayKeyValueDatabase connectWithCache(Properties info) { + private static ByteArrayKeyValueDatabase connectWithCache(Properties info) { boolean enableAutoCommit = getBoolean(info, Props.ENABLE_AUTO_COMMIT); return new DatabaseWithCache( connectBasic(info), @@ -208,7 +208,7 @@ private static AbstractDB connectBasic(Properties info) { * @return A database implementation based on a driver implementing the {@link IDriver} * interface. */ - public static IByteArrayKeyValueDatabase connect(String driverName, Properties info) { + public static ByteArrayKeyValueDatabase connect(String driverName, Properties info) { try { // see if the given name is a valid driver IDriver driver = @@ -226,7 +226,7 @@ public static IByteArrayKeyValueDatabase connect(String driverName, Properties i } /** @return A mock database. */ - public static IByteArrayKeyValueDatabase connect(String _dbName) { + public static ByteArrayKeyValueDatabase connect(String _dbName) { return new MockDB(_dbName); } diff --git a/modDbImpl/src/org/aion/db/impl/IDriver.java b/modDbImpl/src/org/aion/db/impl/IDriver.java index aa9affd809..ad9d3d3268 100644 --- a/modDbImpl/src/org/aion/db/impl/IDriver.java +++ b/modDbImpl/src/org/aion/db/impl/IDriver.java @@ -1,6 +1,6 @@ package org.aion.db.impl; -import org.aion.base.db.IByteArrayKeyValueDatabase; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; public interface IDriver { @@ -10,7 +10,7 @@ public interface IDriver { * @param info the parameters for this database, all represented in String. * @return HashMapDB, or null. */ - IByteArrayKeyValueDatabase connect(java.util.Properties info); + ByteArrayKeyValueDatabase connect(java.util.Properties info); /** * Retrieves the driver's major version number. Initially this should be 1. diff --git a/modDbImpl/src/org/aion/db/impl/h2/H2MVMap.java b/modDbImpl/src/org/aion/db/impl/h2/H2MVMap.java index ee8f92699f..9611699da0 100644 --- a/modDbImpl/src/org/aion/db/impl/h2/H2MVMap.java +++ b/modDbImpl/src/org/aion/db/impl/h2/H2MVMap.java @@ -5,7 +5,7 @@ import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; import org.aion.db.impl.AbstractDB; import org.h2.mvstore.FileStore; import org.h2.mvstore.MVMap; diff --git a/modDbImpl/src/org/aion/db/impl/leveldb/LevelDB.java b/modDbImpl/src/org/aion/db/impl/leveldb/LevelDB.java index f1ed18cc24..ad26279b55 100644 --- a/modDbImpl/src/org/aion/db/impl/leveldb/LevelDB.java +++ b/modDbImpl/src/org/aion/db/impl/leveldb/LevelDB.java @@ -6,7 +6,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.Map; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; import org.aion.db.impl.AbstractDB; import org.fusesource.leveldbjni.JniDBFactory; import org.iq80.leveldb.CompressionType; diff --git a/modDbImpl/src/org/aion/db/impl/mockdb/MockDB.java b/modDbImpl/src/org/aion/db/impl/mockdb/MockDB.java index 8af7ad47e3..bfe7de3fb8 100644 --- a/modDbImpl/src/org/aion/db/impl/mockdb/MockDB.java +++ b/modDbImpl/src/org/aion/db/impl/mockdb/MockDB.java @@ -6,8 +6,8 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; -import org.aion.base.db.PersistenceMethod; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.db.PersistenceMethod; +import org.aion.types.ByteArrayWrapper; import org.aion.db.impl.AbstractDB; public class MockDB extends AbstractDB { diff --git a/modDbImpl/src/org/aion/db/impl/mockdb/MockDBDriver.java b/modDbImpl/src/org/aion/db/impl/mockdb/MockDBDriver.java index f30ee35321..b195eb943d 100644 --- a/modDbImpl/src/org/aion/db/impl/mockdb/MockDBDriver.java +++ b/modDbImpl/src/org/aion/db/impl/mockdb/MockDBDriver.java @@ -3,8 +3,8 @@ import static org.aion.db.impl.DatabaseFactory.Props; import java.util.Properties; -import org.aion.base.db.IByteArrayKeyValueDatabase; import org.aion.db.impl.IDriver; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.slf4j.Logger; @@ -25,7 +25,7 @@ public class MockDBDriver implements IDriver { /** @inheritDoc */ @Override - public IByteArrayKeyValueDatabase connect(Properties info) { + public ByteArrayKeyValueDatabase connect(Properties info) { String dbType = info.getProperty(Props.DB_TYPE); String dbName = info.getProperty(Props.DB_NAME); diff --git a/modDbImpl/src/org/aion/db/impl/mockdb/PersistentMockDB.java b/modDbImpl/src/org/aion/db/impl/mockdb/PersistentMockDB.java index b4d3df8dd3..dac067ae89 100644 --- a/modDbImpl/src/org/aion/db/impl/mockdb/PersistentMockDB.java +++ b/modDbImpl/src/org/aion/db/impl/mockdb/PersistentMockDB.java @@ -10,8 +10,8 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; -import org.aion.base.db.PersistenceMethod; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.db.PersistenceMethod; +import org.aion.types.ByteArrayWrapper; /** * Provides the same behavior as {@link MockDB} with the addition that data is read from a file on diff --git a/modDbImpl/src/org/aion/db/impl/mongodb/MongoDB.java b/modDbImpl/src/org/aion/db/impl/mongodb/MongoDB.java index bdf70b8f31..5e7dba4f64 100644 --- a/modDbImpl/src/org/aion/db/impl/mongodb/MongoDB.java +++ b/modDbImpl/src/org/aion/db/impl/mongodb/MongoDB.java @@ -27,8 +27,9 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import org.aion.base.db.PersistenceMethod; -import org.aion.base.util.ByteArrayWrapper; + +import org.aion.interfaces.db.PersistenceMethod; +import org.aion.types.ByteArrayWrapper; import org.aion.db.impl.AbstractDB; import org.bson.BsonBinary; import org.bson.BsonDocument; diff --git a/modDbImpl/src/org/aion/db/impl/rocksdb/RocksDBWrapper.java b/modDbImpl/src/org/aion/db/impl/rocksdb/RocksDBWrapper.java index c0eec3c27e..522bccf948 100644 --- a/modDbImpl/src/org/aion/db/impl/rocksdb/RocksDBWrapper.java +++ b/modDbImpl/src/org/aion/db/impl/rocksdb/RocksDBWrapper.java @@ -6,7 +6,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.Map; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; import org.aion.db.impl.AbstractDB; import org.rocksdb.BlockBasedTableConfig; import org.rocksdb.CompressionType; diff --git a/modDbImpl/test/org/aion/db/impl/AccessWithExceptionTest.java b/modDbImpl/test/org/aion/db/impl/AccessWithExceptionTest.java index f5e25e5096..6abb028ff2 100644 --- a/modDbImpl/test/org/aion/db/impl/AccessWithExceptionTest.java +++ b/modDbImpl/test/org/aion/db/impl/AccessWithExceptionTest.java @@ -11,8 +11,8 @@ import java.util.Properties; import junitparams.JUnitParamsRunner; import junitparams.Parameters; -import org.aion.base.db.IByteArrayKeyValueDatabase; import org.aion.db.utils.FileUtils; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; import org.aion.log.AionLoggerFactory; import org.junit.AfterClass; import org.junit.Before; @@ -58,7 +58,7 @@ private static Object databaseInstanceDefinitions() { public void testIsEmptyWithClosedDatabase(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.isOpen()).isFalse(); if (VERBOSE) { @@ -74,7 +74,7 @@ public void testIsEmptyWithClosedDatabase(Properties dbDef) { public void testKeysWithClosedDatabase(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.isOpen()).isFalse(); if (VERBOSE) { @@ -90,7 +90,7 @@ public void testKeysWithClosedDatabase(Properties dbDef) { public void testGetWithClosedDatabase(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.isOpen()).isFalse(); if (VERBOSE) { @@ -106,7 +106,7 @@ public void testGetWithClosedDatabase(Properties dbDef) { public void testPutWithClosedDatabase(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.isOpen()).isFalse(); if (VERBOSE) { @@ -122,7 +122,7 @@ public void testPutWithClosedDatabase(Properties dbDef) { public void testDeleteWithClosedDatabase(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.isOpen()).isFalse(); if (VERBOSE) { @@ -138,7 +138,7 @@ public void testDeleteWithClosedDatabase(Properties dbDef) { public void testPutToBatchWithClosedDatabase(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.isOpen()).isFalse(); if (VERBOSE) { @@ -154,7 +154,7 @@ public void testPutToBatchWithClosedDatabase(Properties dbDef) { public void testDeleteInBatchWithClosedDatabase(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.isOpen()).isFalse(); if (VERBOSE) { @@ -170,7 +170,7 @@ public void testDeleteInBatchWithClosedDatabase(Properties dbDef) { public void testPutBatchWithClosedDatabase(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.isOpen()).isFalse(); Map map = new HashMap<>(); @@ -191,7 +191,7 @@ public void testPutBatchWithClosedDatabase(Properties dbDef) { public void testDeleteBatchWithClosedDatabase(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.isOpen()).isFalse(); List list = new ArrayList<>(); @@ -212,7 +212,7 @@ public void testDeleteBatchWithClosedDatabase(Properties dbDef) { public void testCommitWithClosedDatabase(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.isOpen()).isFalse(); if (VERBOSE) { @@ -229,7 +229,7 @@ public void testCommitWithClosedDatabase(Properties dbDef) { public void testSizeWithClosedDatabase(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.isOpen()).isFalse(); if (VERBOSE) { @@ -245,7 +245,7 @@ public void testSizeWithClosedDatabase(Properties dbDef) { public void testGetWithNullKey(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.open()).isTrue(); if (VERBOSE) { @@ -261,7 +261,7 @@ public void testGetWithNullKey(Properties dbDef) { public void testPutWithNullKey(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.open()).isTrue(); if (VERBOSE) { @@ -277,7 +277,7 @@ public void testPutWithNullKey(Properties dbDef) { public void testPutWithNullValue(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.open()).isTrue(); if (VERBOSE) { @@ -293,7 +293,7 @@ public void testPutWithNullValue(Properties dbDef) { public void testPutToBatchWithNullKey(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.open()).isTrue(); if (VERBOSE) { @@ -309,7 +309,7 @@ public void testPutToBatchWithNullKey(Properties dbDef) { public void testPutToBatchWithNullValue(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.open()).isTrue(); if (VERBOSE) { @@ -325,7 +325,7 @@ public void testPutToBatchWithNullValue(Properties dbDef) { public void testDeleteWithNullKey(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.open()).isTrue(); if (VERBOSE) { @@ -341,7 +341,7 @@ public void testDeleteWithNullKey(Properties dbDef) { public void testDeleteInBatchWithNullKey(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.open()).isTrue(); if (VERBOSE) { @@ -357,7 +357,7 @@ public void testDeleteInBatchWithNullKey(Properties dbDef) { public void testPutBatchWithNullKey(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.open()).isTrue(); Map map = new HashMap<>(); @@ -378,7 +378,7 @@ public void testPutBatchWithNullKey(Properties dbDef) { public void testPutBatchWithNullValue(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.open()).isTrue(); Map map = new HashMap<>(); @@ -399,7 +399,7 @@ public void testPutBatchWithNullValue(Properties dbDef) { public void testDeleteBatchWithNullKey(Properties dbDef) { // create database dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + DatabaseTestUtils.getNext()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.open()).isTrue(); List list = new ArrayList<>(); diff --git a/modDbImpl/test/org/aion/db/impl/ConcurrencyTest.java b/modDbImpl/test/org/aion/db/impl/ConcurrencyTest.java index 9cab4bcfdf..66f01738cf 100644 --- a/modDbImpl/test/org/aion/db/impl/ConcurrencyTest.java +++ b/modDbImpl/test/org/aion/db/impl/ConcurrencyTest.java @@ -14,8 +14,8 @@ import java.util.Properties; import junitparams.JUnitParamsRunner; import junitparams.Parameters; -import org.aion.base.db.IByteArrayKeyValueDatabase; import org.aion.db.utils.FileUtils; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; import org.aion.log.AionLoggerFactory; import org.junit.AfterClass; import org.junit.Before; @@ -76,7 +76,7 @@ private static int count(Iterator keys) { return size; } - private void addThread4IsEmpty(List threads, IByteArrayKeyValueDatabase db) { + private void addThread4IsEmpty(List threads, ByteArrayKeyValueDatabase db) { threads.add( () -> { boolean check = db.isEmpty(); @@ -89,7 +89,7 @@ private void addThread4IsEmpty(List threads, IByteArrayKeyValueDatabas }); } - private void addThread4Keys(List threads, IByteArrayKeyValueDatabase db) { + private void addThread4Keys(List threads, ByteArrayKeyValueDatabase db) { threads.add( () -> { Iterator keys = db.keys(); @@ -100,7 +100,7 @@ private void addThread4Keys(List threads, IByteArrayKeyValueDatabase d }); } - private void addThread4Get(List threads, IByteArrayKeyValueDatabase db, String key) { + private void addThread4Get(List threads, ByteArrayKeyValueDatabase db, String key) { threads.add( () -> { boolean hasValue = db.get(key.getBytes()).isPresent(); @@ -115,7 +115,7 @@ private void addThread4Get(List threads, IByteArrayKeyValueDatabase db }); } - private void addThread4Put(List threads, IByteArrayKeyValueDatabase db, String key) { + private void addThread4Put(List threads, ByteArrayKeyValueDatabase db, String key) { threads.add( () -> { db.put(key.getBytes(), DatabaseTestUtils.randomBytes(32)); @@ -127,7 +127,7 @@ private void addThread4Put(List threads, IByteArrayKeyValueDatabase db } private void addThread4Delete( - List threads, IByteArrayKeyValueDatabase db, String key) { + List threads, ByteArrayKeyValueDatabase db, String key) { threads.add( () -> { db.delete(key.getBytes()); @@ -139,7 +139,7 @@ private void addThread4Delete( } private void addThread4PutBatch( - List threads, IByteArrayKeyValueDatabase db, String key) { + List threads, ByteArrayKeyValueDatabase db, String key) { threads.add( () -> { Map map = new HashMap<>(); @@ -162,7 +162,7 @@ private void addThread4PutBatch( } private void addThread4DeleteBatch( - List threads, IByteArrayKeyValueDatabase db, String key) { + List threads, ByteArrayKeyValueDatabase db, String key) { threads.add( () -> { List list = new ArrayList<>(); @@ -184,7 +184,7 @@ private void addThread4DeleteBatch( }); } - private void addThread4Open(List threads, IByteArrayKeyValueDatabase db) { + private void addThread4Open(List threads, ByteArrayKeyValueDatabase db) { threads.add( () -> { db.open(); @@ -194,7 +194,7 @@ private void addThread4Open(List threads, IByteArrayKeyValueDatabase d }); } - private void addThread4Close(List threads, IByteArrayKeyValueDatabase db) { + private void addThread4Close(List threads, ByteArrayKeyValueDatabase db) { threads.add( () -> { db.close(); @@ -204,7 +204,7 @@ private void addThread4Close(List threads, IByteArrayKeyValueDatabase }); } - private void addThread4Size(List threads, IByteArrayKeyValueDatabase db) { + private void addThread4Size(List threads, ByteArrayKeyValueDatabase db) { threads.add( () -> { long size = db.approximateSize(); @@ -221,7 +221,7 @@ public void testConcurrentAccessOnOpenDatabase(Properties dbDef) throws Interrup dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + getNext()); dbDef.setProperty(ENABLE_LOCKING, "true"); // open database - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.open()).isTrue(); // create distinct threads with @@ -276,7 +276,7 @@ public void testConcurrentAccessOnOpenDatabase(Properties dbDef) throws Interrup public void testConcurrentPut(Properties dbDef) throws InterruptedException { dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + getNext()); dbDef.setProperty(ENABLE_LOCKING, "true"); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.open()).isTrue(); // create distinct threads with @@ -302,7 +302,7 @@ public void testConcurrentPut(Properties dbDef) throws InterruptedException { public void testConcurrentPutBatch(Properties dbDef) throws InterruptedException { dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + getNext()); dbDef.setProperty(ENABLE_LOCKING, "true"); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.open()).isTrue(); // create distinct threads with @@ -329,7 +329,7 @@ public void testConcurrentUpdate(Properties dbDef) throws InterruptedException { dbDef.setProperty(DB_NAME, DatabaseTestUtils.dbName + getNext()); dbDef.setProperty(ENABLE_LOCKING, "true"); // open database - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(dbDef); assertThat(db.open()).isTrue(); // create distinct threads with diff --git a/modDbImpl/test/org/aion/db/impl/DatabaseFactoryTest.java b/modDbImpl/test/org/aion/db/impl/DatabaseFactoryTest.java index 3148b54778..69dcc8bf48 100644 --- a/modDbImpl/test/org/aion/db/impl/DatabaseFactoryTest.java +++ b/modDbImpl/test/org/aion/db/impl/DatabaseFactoryTest.java @@ -6,7 +6,6 @@ import java.io.File; import java.util.Properties; -import org.aion.base.db.IByteArrayKeyValueDatabase; import org.aion.db.generic.DatabaseWithCache; import org.aion.db.generic.LockedDatabase; import org.aion.db.generic.SpecialLockedDatabase; @@ -18,6 +17,7 @@ import org.aion.db.impl.mockdb.PersistentMockDB; import org.aion.db.impl.rocksdb.RocksDBConstants; import org.aion.db.impl.rocksdb.RocksDBWrapper; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; import org.junit.Test; public class DatabaseFactoryTest { @@ -36,7 +36,7 @@ public void testReturnBasicDatabase() { // MOCKDB props.setProperty(Props.DB_TYPE, DBVendor.MOCKDB.toValue()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); assertThat(db).isNotNull(); assertThat(db.getClass().getSimpleName()).isEqualTo(MockDB.class.getSimpleName()); @@ -91,7 +91,7 @@ public void testReturnLockedDatabase() { // MOCKDB props.setProperty(Props.DB_TYPE, DBVendor.MOCKDB.toValue()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); assertThat(db).isNotNull(); assertThat(db.getClass().getSimpleName()).isEqualTo(LockedDatabase.class.getSimpleName()); assertThat(db.toString()).contains(MockDB.class.getSimpleName()); @@ -154,7 +154,7 @@ public void testReturnDatabaseWithCacheParameterSet1() { // MOCKDB props.setProperty(Props.DB_TYPE, DBVendor.MOCKDB.toValue()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); assertThat(db).isNotNull(); assertThat(db.getClass().getSimpleName()) .isEqualTo(DatabaseWithCache.class.getSimpleName()); @@ -223,7 +223,7 @@ public void testReturnDatabaseWithCacheParameterSet2() { // MOCKDB props.setProperty(Props.DB_TYPE, DBVendor.MOCKDB.toValue()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); assertThat(db).isNotNull(); assertThat(db.getClass().getSimpleName()) .isEqualTo(DatabaseWithCache.class.getSimpleName()); @@ -283,7 +283,7 @@ public void testDriverRandomClassReturnNull() { // random class that is not an IDriver props.setProperty(Props.DB_TYPE, MockDB.class.getName()); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); // System.out.println(db); assertNull(db); } @@ -296,7 +296,7 @@ public void testDriverRandomStringReturnNull() { // random string props.setProperty(Props.DB_TYPE, "not a class"); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); // System.out.println(db); assertNull(db); } diff --git a/modDbImpl/test/org/aion/db/impl/DriverBaseTest.java b/modDbImpl/test/org/aion/db/impl/DriverBaseTest.java index a71eff7d54..d98e8d105a 100644 --- a/modDbImpl/test/org/aion/db/impl/DriverBaseTest.java +++ b/modDbImpl/test/org/aion/db/impl/DriverBaseTest.java @@ -13,8 +13,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.db.PersistenceMethod; import org.aion.db.generic.DatabaseWithCache; import org.aion.db.generic.LockedDatabase; import org.aion.db.impl.h2.H2MVMap; @@ -22,6 +20,8 @@ import org.aion.db.impl.mockdb.MockDB; import org.aion.db.impl.mockdb.PersistentMockDB; import org.aion.db.utils.FileUtils; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.PersistenceMethod; import org.aion.log.AionLoggerFactory; import org.junit.After; import org.junit.AfterClass; @@ -314,9 +314,9 @@ public static Iterable data() throws NoSuchMethodException, SecurityEx }); } - private IByteArrayKeyValueDatabase db; + private ByteArrayKeyValueDatabase db; - private final Constructor constructor; + private final Constructor constructor; private final Object[] args; private final String dbName; @@ -333,7 +333,7 @@ public static Iterable data() throws NoSuchMethodException, SecurityEx public DriverBaseTest( String testName, boolean[] props, - Constructor constructor, + Constructor constructor, Object[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { @@ -457,7 +457,7 @@ public void testOpenSecondInstance() if (db.getPersistenceMethod() == PersistenceMethod.FILE_BASED && !(db instanceof PersistentMockDB)) { // another connection to same DB should fail on open for all persistent KVDBs - IByteArrayKeyValueDatabase otherDatabase = this.constructor.newInstance(this.args); + ByteArrayKeyValueDatabase otherDatabase = this.constructor.newInstance(this.args); assertThat(otherDatabase.open()).isFalse(); // ensuring that new connection did not somehow close old one diff --git a/modDbImpl/test/org/aion/db/impl/DriverBenchmarkTest.java b/modDbImpl/test/org/aion/db/impl/DriverBenchmarkTest.java index 1e1dc3790d..9933f9fa0e 100644 --- a/modDbImpl/test/org/aion/db/impl/DriverBenchmarkTest.java +++ b/modDbImpl/test/org/aion/db/impl/DriverBenchmarkTest.java @@ -20,8 +20,6 @@ import java.util.Map; import java.util.Random; import java.util.concurrent.TimeUnit; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.db.PersistenceMethod; import org.aion.db.impl.h2.H2MVMap; import org.aion.db.impl.leveldb.LevelDB; import org.aion.db.impl.rocksdb.RocksDBConstants; @@ -32,6 +30,8 @@ import org.aion.db.utils.slices.Slice; import org.aion.db.utils.slices.SliceOutput; import org.aion.db.utils.slices.Slices; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.PersistenceMethod; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; @@ -82,14 +82,14 @@ public static Iterable data() { }); } - public IByteArrayKeyValueDatabase db; + public ByteArrayKeyValueDatabase db; public String testName; private final RandomGenerator generator; private final Random random; // Every test invocation instantiates a new IByteArrayKeyValueDB - public DriverBenchmarkTest(String testName, IByteArrayKeyValueDatabase db) { + public DriverBenchmarkTest(String testName, ByteArrayKeyValueDatabase db) { this.db = db; this.testName = testName; diff --git a/modDbImpl/test/org/aion/db/impl/h2/H2MVMapDriverTest.java b/modDbImpl/test/org/aion/db/impl/h2/H2MVMapDriverTest.java index e22236ef51..27e02e95fd 100644 --- a/modDbImpl/test/org/aion/db/impl/h2/H2MVMapDriverTest.java +++ b/modDbImpl/test/org/aion/db/impl/h2/H2MVMapDriverTest.java @@ -6,9 +6,9 @@ import java.io.File; import java.util.Properties; -import org.aion.base.db.IByteArrayKeyValueDatabase; import org.aion.db.impl.DBVendor; import org.aion.db.impl.DatabaseFactory; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; import org.junit.Test; public class H2MVMapDriverTest { @@ -28,7 +28,7 @@ public void testDriverReturnDatabase() { props.setProperty(Props.DB_NAME, dbName); props.setProperty(Props.DB_PATH, dbPath); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); assertNotNull(db); } @@ -41,7 +41,7 @@ public void testDriverReturnNull() { props.setProperty(Props.DB_NAME, dbName); props.setProperty(Props.DB_PATH, dbPath); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); assertNull(db); } diff --git a/modDbImpl/test/org/aion/db/impl/leveldb/LevelDBDriverTest.java b/modDbImpl/test/org/aion/db/impl/leveldb/LevelDBDriverTest.java index 4f42a12ec1..3c162c9910 100644 --- a/modDbImpl/test/org/aion/db/impl/leveldb/LevelDBDriverTest.java +++ b/modDbImpl/test/org/aion/db/impl/leveldb/LevelDBDriverTest.java @@ -6,9 +6,9 @@ import java.io.File; import java.util.Properties; -import org.aion.base.db.IByteArrayKeyValueDatabase; import org.aion.db.impl.DBVendor; import org.aion.db.impl.DatabaseFactory; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; import org.junit.Test; public class LevelDBDriverTest { @@ -33,7 +33,7 @@ public void testDriverReturnDatabase() { Props.WRITE_BUFFER_SIZE, String.valueOf(LevelDBConstants.WRITE_BUFFER_SIZE)); props.setProperty(Props.DB_CACHE_SIZE, String.valueOf(LevelDBConstants.CACHE_SIZE)); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); assertNotNull(db); } @@ -46,7 +46,7 @@ public void testDriverReturnNull() { props.setProperty(Props.DB_NAME, dbName); props.setProperty(Props.DB_PATH, dbPath); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); assertNull(db); } diff --git a/modDbImpl/test/org/aion/db/impl/mockdb/MockDBDriverTest.java b/modDbImpl/test/org/aion/db/impl/mockdb/MockDBDriverTest.java index 2919dd9a88..9ef0a2d034 100644 --- a/modDbImpl/test/org/aion/db/impl/mockdb/MockDBDriverTest.java +++ b/modDbImpl/test/org/aion/db/impl/mockdb/MockDBDriverTest.java @@ -7,15 +7,15 @@ import static org.junit.Assert.assertNull; import java.util.Properties; -import org.aion.base.db.IByteArrayKeyValueDatabase; import org.aion.db.impl.DBVendor; import org.aion.db.impl.DatabaseFactory; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; import org.junit.Before; import org.junit.Test; public class MockDBDriverTest { - private static IByteArrayKeyValueDatabase db; + private static ByteArrayKeyValueDatabase db; private static DBVendor vendor; private static MockDBDriver driver; private static Properties props; diff --git a/modDbImpl/test/org/aion/db/impl/rocksdb/RocksDBDriverTest.java b/modDbImpl/test/org/aion/db/impl/rocksdb/RocksDBDriverTest.java index d045056f21..c6adc02abc 100644 --- a/modDbImpl/test/org/aion/db/impl/rocksdb/RocksDBDriverTest.java +++ b/modDbImpl/test/org/aion/db/impl/rocksdb/RocksDBDriverTest.java @@ -6,9 +6,9 @@ import java.io.File; import java.util.Properties; -import org.aion.base.db.IByteArrayKeyValueDatabase; import org.aion.db.impl.DBVendor; import org.aion.db.impl.DatabaseFactory; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; import org.junit.Test; public class RocksDBDriverTest { @@ -32,7 +32,7 @@ public void testDriverReturnDatabase() { props.setProperty( Props.WRITE_BUFFER_SIZE, String.valueOf(RocksDBConstants.WRITE_BUFFER_SIZE)); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); assertNotNull(db); } @@ -45,7 +45,7 @@ public void testDriverReturnNull() { props.setProperty(Props.DB_NAME, dbName); props.setProperty(Props.DB_PATH, dbPath); - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(props); assertNull(db); } diff --git a/modEvtMgr/build.gradle b/modEvtMgr/build.gradle index 0ecf1ec692..0694b4fe30 100644 --- a/modEvtMgr/build.gradle +++ b/modEvtMgr/build.gradle @@ -1,8 +1,9 @@ ext.moduleName = 'org.aion.evtmgr' dependencies { + testCompile 'network.aion:log4j:0.4.0' + testCompile project(':modEvtMgrImpl') - testCompile project(':modLogger') testCompile 'junit:junit:4.12' testCompile 'org.hamcrest:hamcrest-all:1.3' testCompile group: 'org.apache.commons', name: 'commons-collections4', version: '4.0' diff --git a/modEvtMgrImpl/build.gradle b/modEvtMgrImpl/build.gradle index 8928b8f182..ed0a1a5b90 100644 --- a/modEvtMgrImpl/build.gradle +++ b/modEvtMgrImpl/build.gradle @@ -1,8 +1,9 @@ ext.moduleName = 'aion.evtmgr.impl' dependencies { + compile 'network.aion:log4j:0.4.0' + compile project(':modEvtMgr') - compile project(':modLogger') compile 'com.google.guava:guava:25.1-jre' testCompile 'junit:junit:4.12' diff --git a/modLogger/build.gradle b/modLogger/build.gradle index cabb586fda..2a4c0a9187 100644 --- a/modLogger/build.gradle +++ b/modLogger/build.gradle @@ -1,7 +1,115 @@ ext.moduleName = 'aion.log' +// set the publish to true when the code ready to push the lib to the maven repo +def publish = false; + +apply plugin: 'maven' +apply plugin: 'signing' + +group = "network.aion" +archivesBaseName = "log4j" + +def getCommitHash = { -> + def hashStdOut = new ByteArrayOutputStream() + exec { + commandLine "sh", "-c", "git log --pretty=format:%h | head -1" + standardOutput = hashStdOut + } + + return hashStdOut.toString().trim() +} + dependencies { compile 'org.slf4j:slf4j-api:1.7.25' compile 'ch.qos.logback:logback-core:1.2.3' compile 'ch.qos.logback:logback-classic:1.2.3' } + +sourceSets { + + if (publish) { + version = "0.4.0" + } else { + jar.baseName = 'crypto4j-' + getCommitHash() + } + + main { + java.srcDirs = ['src/main/java'] + } + test { + java.srcDirs = ['src/test/java'] + } +} + +signing { + sign configurations.archives +} +signArchives.enabled = publish + + +task sourcesJar(type: Jar) { + classifier = 'sources' + from sourceSets.main.allSource +} +sourcesJar.enabled = publish + +javadoc { + inputs.property("moduleName", moduleName) + doFirst { + options.addStringOption('-module-path', classpath.asPath) + options.tags = [ "implNote" ] + } +} + +task javadocJar(type: Jar) { + classifier = 'javadoc' + from javadoc +} +javadocJar.enabled = publish + +artifacts { + archives sourcesJar, javadocJar +} + +uploadArchives { + repositories { + mavenDeployer { + + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } + + repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { + authentication(userName: ossrhUsername, password: ossrhPassword) + } + + pom.project { + name 'log4j' + packaging 'jar' + // optionally artifactId can be defined here + description 'a log module for the aion java kernel.' + url 'https://github.com/aionnetwork/aion/tree/master-pre-merge/modLogger' + + scm { + connection 'scm:git:https://github.com/aionnetwork/aion.git' + developerConnection 'git:https://github.com/aionnetwork/aion.git' + url 'https://github.com/aionnetwork/aion/tree/master' + } + + licenses { + license { + name 'MIT' + url 'https://opensource.org/licenses/MIT' + } + } + + developers { + developer { + id 'aion foundation dev' + name 'aion foundation dev' + email 'toengineering@aion.network' + } + } + } + } + } +} +uploadArchives.enabled = publish diff --git a/modLogger/src/module-info.java b/modLogger/src/main/java/module-info.java similarity index 100% rename from modLogger/src/module-info.java rename to modLogger/src/main/java/module-info.java diff --git a/modLogger/src/org/aion/log/AionLoggerFactory.java b/modLogger/src/main/java/org/aion/log/AionLoggerFactory.java similarity index 97% rename from modLogger/src/org/aion/log/AionLoggerFactory.java rename to modLogger/src/main/java/org/aion/log/AionLoggerFactory.java index 553d27be7d..4469550a9b 100644 --- a/modLogger/src/org/aion/log/AionLoggerFactory.java +++ b/modLogger/src/main/java/org/aion/log/AionLoggerFactory.java @@ -72,9 +72,7 @@ private static Map constructModuleLoglevelMap( Map moduleToLevelMap = new HashMap<>(); if (_moduleToLevelMap != null) { _moduleToLevelMap.forEach( - (module, level) -> { - moduleToLevelMap.put(module.toUpperCase(), level); - }); + (module, level) -> moduleToLevelMap.put(module.toUpperCase(), level)); } Map modules = new HashMap<>(); @@ -128,7 +126,7 @@ private static List> constructAppenders( RollingFileAppender fileSync = new RollingFileAppender<>(); - SizeBasedTriggeringPolicy tp = new SizeBasedTriggeringPolicy(); + SizeBasedTriggeringPolicy tp = new SizeBasedTriggeringPolicy<>(); tp.setContext(context); tp.start(); diff --git a/modLogger/src/org/aion/log/LogEnum.java b/modLogger/src/main/java/org/aion/log/LogEnum.java similarity index 100% rename from modLogger/src/org/aion/log/LogEnum.java rename to modLogger/src/main/java/org/aion/log/LogEnum.java diff --git a/modLogger/src/org/aion/log/LogLevel.java b/modLogger/src/main/java/org/aion/log/LogLevel.java similarity index 100% rename from modLogger/src/org/aion/log/LogLevel.java rename to modLogger/src/main/java/org/aion/log/LogLevel.java diff --git a/modLogger/src/org/aion/log/LogUtil.java b/modLogger/src/main/java/org/aion/log/LogUtil.java similarity index 77% rename from modLogger/src/org/aion/log/LogUtil.java rename to modLogger/src/main/java/org/aion/log/LogUtil.java index ec343631c3..46efe7c2e0 100644 --- a/modLogger/src/org/aion/log/LogUtil.java +++ b/modLogger/src/main/java/org/aion/log/LogUtil.java @@ -12,9 +12,9 @@ public class LogUtil { * 'http://stackoverflow.com/questions/9655181/how-to-convert-a-byte-array-to-a-hex-string-in-java'>stackoverflow * discussion and our benchmark for performance gains */ - protected static final char[] hexArray = "0123456789abcfef".toCharArray(); + private static final char[] hexArray = "0123456789abcdef".toCharArray(); - protected static String toHex(byte[] bytes) { + private static String toHex(byte[] bytes) { char[] hexChars = new char[bytes.length * 2]; for (int j = 0; j < bytes.length; j++) { int v = bytes[j] & 0xFF; @@ -24,16 +24,17 @@ protected static String toHex(byte[] bytes) { return new String(hexChars); } + + private static final String nullString = ""; + /** * Guarantees a return of at max, first 8 characters, even if data is ill formatted (null, * shorter, longer) etc. * - * @param data - * @return + * @param data byte array + * @return first 8 chars of the input HexString */ - protected static final String nullString = ""; - - protected static String toHexF8Internal(byte[] data) { + private static String toHexF8Internal(byte[] data) { if (data == null || data.length == 0) { return nullString; } @@ -49,10 +50,10 @@ protected static String toHexF8Internal(byte[] data) { * Guarantees a return of at max, last 8 characters, even if data is ill formatted (null, * shorter, longer) etc. * - * @param data - * @return + * @param data byte array + * @return last 8 chars of the input HexString */ - public static String toHexL8Internal(byte[] data) { + private static String toHexL8Internal(byte[] data) { if (data == null || data.length == 0) { return nullString; } @@ -68,8 +69,8 @@ public static String toHexL8Internal(byte[] data) { * Guarantees a return of at max, first 8 characters, even if data is ill formatted (null, * shorter, longer) etc. * - * @param data - * @return + * @param data byte array + * @return first 8 chars of the input HexString */ public static String toHexF8(byte[] data) { int len = 0; @@ -82,8 +83,8 @@ public static String toHexF8(byte[] data) { * Guarantees a return of at max, last 8 characters, even if data is ill formatted (null, * shorter, longer) etc. * - * @param data - * @return + * @param data byte array + * @return last 8 chars of the input HexString */ public static String toHexL8(byte[] data) { int len = 0; diff --git a/modMcf/build.gradle b/modMcf/build.gradle index a28a43d476..0eb1a6498b 100644 --- a/modMcf/build.gradle +++ b/modMcf/build.gradle @@ -4,16 +4,16 @@ test.dependsOn copyNativeLibsForModuleTests clean.dependsOn deleteNativeLibs dependencies { - compile project(':modUtil') - compile project(':modAionBase') - compile project(':modLogger') + compile project(':aion_vm_api') + compile 'network.aion:util4j:0.4.0' + compile 'network.aion:log4j:0.4.0' + compile 'network.aion:rlp4j:0.4.0' + compile 'network.aion:crypto4j:0.4.0' + compile project(':modP2p') - compile project(':modCrypto') - compile project(':modRlp') compile project(':modDbImpl') compile 'com.madgag.spongycastle:prov:1.58.0.0' compile 'com.madgag.spongycastle:core:1.58.0.0' - compile project(':aion_vm_api') compile files('../lib/libnsc.jar') compile 'org.slf4j:slf4j-api:1.7.25' compile 'com.google.guava:guava:25.1-jre' @@ -28,6 +28,8 @@ dependencies { testCompile group: 'commons-codec', name: 'commons-codec', version: '1.10' testCompile "org.mockito:mockito-core:2.23.0" testCompile 'pl.pragmatists:JUnitParams:1.1.1' + testCompile 'network.aion:crypto4j:0.4.0' + } // Skip unit tests when doing build task; unit tests are all mixed up with diff --git a/modMcf/src/module-info.java b/modMcf/src/module-info.java index 17ea2c75ca..8dcef75ee6 100644 --- a/modMcf/src/module-info.java +++ b/modMcf/src/module-info.java @@ -1,7 +1,6 @@ module aion.mcf { requires aion.util; requires aion.crypto; - requires aion.base; requires aion.log; requires java.xml; requires aion.rlp; @@ -9,7 +8,6 @@ requires slf4j.api; requires aion.p2p; requires com.google.common; - // requires libnsc; requires commons.collections4; requires aion.vm.api; requires core; diff --git a/modMcf/src/org/aion/mcf/account/AccountManager.java b/modMcf/src/org/aion/mcf/account/AccountManager.java index ab22648bee..4467b621ae 100644 --- a/modMcf/src/org/aion/mcf/account/AccountManager.java +++ b/modMcf/src/org/aion/mcf/account/AccountManager.java @@ -9,7 +9,7 @@ import org.aion.crypto.ECKey; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; import org.slf4j.Logger; /** Account Manger Class */ diff --git a/modMcf/src/org/aion/mcf/account/Keystore.java b/modMcf/src/org/aion/mcf/account/Keystore.java index 107971ea65..693a12f34a 100644 --- a/modMcf/src/org/aion/mcf/account/Keystore.java +++ b/modMcf/src/org/aion/mcf/account/Keystore.java @@ -22,16 +22,16 @@ import java.util.TimeZone; import java.util.regex.Pattern; import java.util.stream.Collectors; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.TypeConverter; + +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.aion.util.bytes.ByteUtil; import org.aion.util.conversions.Hex; -import org.aion.vm.api.interfaces.Address; +import org.aion.util.string.StringUtils; import org.slf4j.Logger; /** key store class. */ @@ -89,7 +89,7 @@ public static String create(String password, ECKey key) { FileOutputStream fos = new FileOutputStream(path); fos.write(content); fos.close(); - return TypeConverter.toJsonHex(address); + return StringUtils.toJsonHex(address); } catch (IOException e) { LOG.error("fail to create keystore"); return ADDR_PREFIX; @@ -118,7 +118,7 @@ public static Map backupAccount(Map throw new NullPointerException(); } - List files = org.aion.base.io.File.getFiles(PATH); + List files = org.aion.util.file.File.getFiles(PATH); if (files == null) { if (LOG.isWarnEnabled()) { LOG.warn("No key file been stored in the kernel."); @@ -146,7 +146,7 @@ public static Map backupAccount(Map String[] frags = file.getName().split("--"); if (frags.length == 3) { if (frags[2].startsWith(AION_PREFIX)) { - Address addr = AionAddress.wrap(frags[2]); + Address addr = Address.wrap(frags[2]); byte[] content = Files.readAllBytes(file.toPath()); String pw = account.get(addr); @@ -171,7 +171,7 @@ public static Map backupAccount(Map } public static String[] list() { - return addAddrs(org.aion.base.io.File.getFiles(PATH)).toArray(new String[0]); + return addAddrs(org.aion.util.file.File.getFiles(PATH)).toArray(new String[0]); } private static List addAddrs(List files) { @@ -181,7 +181,7 @@ private static List addAddrs(List files) { String[] frags = file.getName().split("--"); if (frags.length == 3) { if (frags[2].startsWith(AION_PREFIX)) { - addresses.add(TypeConverter.toJsonHex(frags[2])); + addresses.add(StringUtils.toJsonHex(frags[2])); } else { if (LOG.isDebugEnabled()) { LOG.debug("Wrong address format: {}", frags[2]); @@ -198,7 +198,7 @@ private static List addAddrs(List files) { * @return address represent by String as a List */ public static List accountsSorted() { - List files = org.aion.base.io.File.getFiles(PATH); + List files = org.aion.util.file.File.getFiles(PATH); files.sort(COMPARE); return addAddrs(files); } @@ -210,7 +210,7 @@ public static ECKey getKey(String _address, String _password) { ECKey key = null; if (_address.startsWith(AION_PREFIX)) { - List files = org.aion.base.io.File.getFiles(PATH); + List files = org.aion.util.file.File.getFiles(PATH); for (File file : files) { if (HEX_64.matcher(_address).find() && file.getName().contains(_address)) { try { @@ -240,7 +240,7 @@ public static boolean exist(String _address) { boolean flag = false; if (_address.startsWith(AION_PREFIX)) { - List files = org.aion.base.io.File.getFiles(PATH); + List files = org.aion.util.file.File.getFiles(PATH); for (File file : files) { if (HEX_64.matcher(_address).find() && file.getName().contains(_address)) { flag = true; @@ -296,7 +296,7 @@ public static Set importAccount(Map importKey) { * Test method. Don't use it for the code dev. */ static File getAccountFile(String address, String password) { - List files = org.aion.base.io.File.getFiles(PATH); + List files = org.aion.util.file.File.getFiles(PATH); if (files == null) { if (LOG.isWarnEnabled()) { LOG.warn("No key file been stored in the kernel."); diff --git a/modMcf/src/org/aion/mcf/blockchain/AbstractPendingTx.java b/modMcf/src/org/aion/mcf/blockchain/AbstractPendingTx.java index adb7ac8f2b..6557deef7d 100644 --- a/modMcf/src/org/aion/mcf/blockchain/AbstractPendingTx.java +++ b/modMcf/src/org/aion/mcf/blockchain/AbstractPendingTx.java @@ -1,16 +1,16 @@ package org.aion.mcf.blockchain; import java.math.BigInteger; -import org.aion.base.type.ITransaction; +import org.aion.interfaces.tx.Transaction; +import org.aion.types.Address; import org.aion.util.bytes.ByteUtil; -import org.aion.vm.api.interfaces.Address; /** * Abstract Pending Transaction Class. * * @param */ -public abstract class AbstractPendingTx { +public abstract class AbstractPendingTx { protected TX transaction; diff --git a/modMcf/src/org/aion/mcf/blockchain/AbstractSyncQueue.java b/modMcf/src/org/aion/mcf/blockchain/AbstractSyncQueue.java index c480c284db..fadb08bbe8 100644 --- a/modMcf/src/org/aion/mcf/blockchain/AbstractSyncQueue.java +++ b/modMcf/src/org/aion/mcf/blockchain/AbstractSyncQueue.java @@ -1,19 +1,14 @@ package org.aion.mcf.blockchain; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.aion.base.type.IBlock; -import org.aion.base.util.ByteArrayWrapper; +import java.util.*; + +import org.aion.interfaces.block.Block; +import org.aion.types.ByteArrayWrapper; import org.aion.mcf.types.AbstractBlockHeaderWrapper; /** Abstract SyncQueue Class */ public abstract class AbstractSyncQueue< - BLK extends IBlock, BHW extends AbstractBlockHeaderWrapper> + BLK extends Block, BHW extends AbstractBlockHeaderWrapper> implements ISyncQueue { protected static int MAX_CHAIN_LEN = 192; @@ -58,7 +53,7 @@ public boolean isReverse() { } } - public class HeaderElement, BW extends AbstractBlockHeaderWrapper> { + public class HeaderElement, BW extends AbstractBlockHeaderWrapper> { public BW header; public BK block; diff --git a/modMcf/src/org/aion/mcf/blockchain/IChainCfg.java b/modMcf/src/org/aion/mcf/blockchain/IChainCfg.java index 3980ba2c6e..ee2aae4f7f 100644 --- a/modMcf/src/org/aion/mcf/blockchain/IChainCfg.java +++ b/modMcf/src/org/aion/mcf/blockchain/IChainCfg.java @@ -1,14 +1,14 @@ package org.aion.mcf.blockchain; -import org.aion.base.type.IBlock; -import org.aion.base.type.ITransaction; +import org.aion.interfaces.block.Block; +import org.aion.interfaces.tx.Transaction; import org.aion.mcf.core.IDifficultyCalculator; import org.aion.mcf.core.IRewardsCalculator; import org.aion.mcf.valid.BlockHeaderValidator; import org.aion.mcf.valid.ParentBlockHeaderValidator; /** Chain configuration interface. */ -public interface IChainCfg, Tx extends ITransaction> { +public interface IChainCfg, Tx extends Transaction> { boolean acceptTransactionSignature(Tx tx); diff --git a/modMcf/src/org/aion/mcf/blockchain/IGenericChain.java b/modMcf/src/org/aion/mcf/blockchain/IGenericChain.java index 80ab76dd03..59140008ad 100644 --- a/modMcf/src/org/aion/mcf/blockchain/IGenericChain.java +++ b/modMcf/src/org/aion/mcf/blockchain/IGenericChain.java @@ -1,12 +1,12 @@ package org.aion.mcf.blockchain; -import org.aion.base.type.IBlock; +import org.aion.interfaces.block.Block; import org.aion.mcf.core.AbstractTxInfo; import org.aion.mcf.db.IBlockStoreBase; import org.aion.mcf.types.AbstractBlockHeader; /** Generic Chain interface. */ -public interface IGenericChain { +public interface IGenericChain { BLK getBlockByNumber(long number); diff --git a/modMcf/src/org/aion/mcf/blockchain/IPendingState.java b/modMcf/src/org/aion/mcf/blockchain/IPendingState.java index 47bd618c4c..6765de76ca 100644 --- a/modMcf/src/org/aion/mcf/blockchain/IPendingState.java +++ b/modMcf/src/org/aion/mcf/blockchain/IPendingState.java @@ -2,11 +2,11 @@ import java.math.BigInteger; import java.util.List; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.ITransaction; -import org.aion.vm.api.interfaces.Address; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.interfaces.tx.Transaction; +import org.aion.types.Address; -public interface IPendingState { +public interface IPendingState { List addPendingTransactions(List transactions); @@ -14,7 +14,7 @@ public interface IPendingState { boolean isValid(TX tx); - IRepositoryCache getRepository(); + RepositoryCache getRepository(); List getPendingTransactions(); diff --git a/modMcf/src/org/aion/mcf/blockchain/IPendingStateInternal.java b/modMcf/src/org/aion/mcf/blockchain/IPendingStateInternal.java index a6f2706944..b741ea521e 100644 --- a/modMcf/src/org/aion/mcf/blockchain/IPendingStateInternal.java +++ b/modMcf/src/org/aion/mcf/blockchain/IPendingStateInternal.java @@ -1,8 +1,8 @@ package org.aion.mcf.blockchain; import java.util.List; -import org.aion.base.type.IBlock; -import org.aion.base.type.ITransaction; +import org.aion.interfaces.block.Block; +import org.aion.interfaces.tx.Transaction; import org.aion.mcf.types.AbstractTxReceipt; /** @@ -11,7 +11,7 @@ * @param * @param */ -public interface IPendingStateInternal, Tx extends ITransaction> +public interface IPendingStateInternal, Tx extends Transaction> extends IPendingState { // called by onBest diff --git a/modMcf/src/org/aion/mcf/blockchain/IPowChain.java b/modMcf/src/org/aion/mcf/blockchain/IPowChain.java index 1823772308..1e611276df 100644 --- a/modMcf/src/org/aion/mcf/blockchain/IPowChain.java +++ b/modMcf/src/org/aion/mcf/blockchain/IPowChain.java @@ -1,9 +1,9 @@ package org.aion.mcf.blockchain; import java.math.BigInteger; -import org.aion.base.type.Hash256; -import org.aion.base.type.IBlock; +import org.aion.interfaces.block.Block; import org.aion.mcf.types.AbstractBlockHeader; +import org.aion.types.Hash256; /** * proof of work chain interface. @@ -12,7 +12,7 @@ * @param */ @SuppressWarnings("rawtypes") -public interface IPowChain +public interface IPowChain extends IGenericChain { BigInteger getTotalDifficulty(); diff --git a/modMcf/src/org/aion/mcf/blockchain/ISyncQueue.java b/modMcf/src/org/aion/mcf/blockchain/ISyncQueue.java index 10106d73ca..74f3f7ed23 100644 --- a/modMcf/src/org/aion/mcf/blockchain/ISyncQueue.java +++ b/modMcf/src/org/aion/mcf/blockchain/ISyncQueue.java @@ -2,7 +2,7 @@ import java.util.Collection; import java.util.List; -import org.aion.base.type.IBlock; +import org.aion.interfaces.block.Block; import org.aion.mcf.types.AbstractBlockHeaderWrapper; /** @@ -11,7 +11,7 @@ * @param * @param */ -public interface ISyncQueue, BHW extends AbstractBlockHeaderWrapper> { +public interface ISyncQueue, BHW extends AbstractBlockHeaderWrapper> { /** Wanted headers */ interface HeadersRequest { diff --git a/modMcf/src/org/aion/mcf/blockchain/TxExecutorBase.java b/modMcf/src/org/aion/mcf/blockchain/TxExecutorBase.java index bb94cd7375..2b234ad698 100644 --- a/modMcf/src/org/aion/mcf/blockchain/TxExecutorBase.java +++ b/modMcf/src/org/aion/mcf/blockchain/TxExecutorBase.java @@ -1,7 +1,7 @@ package org.aion.mcf.blockchain; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.IBlock; +import org.aion.interfaces.block.Block; +import org.aion.interfaces.db.RepositoryCache; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.aion.mcf.db.IBlockStoreBase; @@ -11,7 +11,7 @@ /** Transaction executor base class. */ public abstract class TxExecutorBase< - BLK extends IBlock, + BLK extends Block, TX extends AbstractTransaction, BS extends IBlockStoreBase, TR extends AbstractTxReceipt> { @@ -20,9 +20,9 @@ public abstract class TxExecutorBase< protected TX tx; - protected IRepositoryCache track; + protected RepositoryCache track; - protected IRepositoryCache cacheTrack; + protected RepositoryCache cacheTrack; protected BS blockStore; diff --git a/modMcf/src/org/aion/mcf/blockchain/valid/IBlockHeaderValidRule.java b/modMcf/src/org/aion/mcf/blockchain/valid/IBlockHeaderValidRule.java index 9e27122fec..a4fc956485 100644 --- a/modMcf/src/org/aion/mcf/blockchain/valid/IBlockHeaderValidRule.java +++ b/modMcf/src/org/aion/mcf/blockchain/valid/IBlockHeaderValidRule.java @@ -1,14 +1,14 @@ package org.aion.mcf.blockchain.valid; import java.util.List; -import org.aion.base.type.IBlockHeader; +import org.aion.interfaces.block.BlockHeader; /** * Block header validation rules. * * @param */ -public interface IBlockHeaderValidRule extends IValidRule { +public interface IBlockHeaderValidRule extends IValidRule { boolean validate(BH header, BH dependency, List errors); } diff --git a/modMcf/src/org/aion/mcf/blockchain/valid/IValidRule.java b/modMcf/src/org/aion/mcf/blockchain/valid/IValidRule.java index 4ab54834a5..9003e7f773 100644 --- a/modMcf/src/org/aion/mcf/blockchain/valid/IValidRule.java +++ b/modMcf/src/org/aion/mcf/blockchain/valid/IValidRule.java @@ -2,7 +2,7 @@ /** Valication rules interface. */ public interface IValidRule { - public static class RuleError { + class RuleError { public final Class errorClass; public final String error; diff --git a/modMcf/src/org/aion/mcf/config/CfgDb.java b/modMcf/src/org/aion/mcf/config/CfgDb.java index dd98feb9b8..4ab4dfd41e 100644 --- a/modMcf/src/org/aion/mcf/config/CfgDb.java +++ b/modMcf/src/org/aion/mcf/config/CfgDb.java @@ -13,8 +13,8 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; -import org.aion.base.util.Utils; import org.aion.db.impl.DBVendor; +import org.aion.util.others.Utils; /** @author chris */ public class CfgDb { @@ -26,6 +26,7 @@ public static class Names { public static final String INDEX = "index"; public static final String PENDING_BLOCK = "pendingBlock"; + public static final String CONTRACT_INDEX = "contractIndex"; public static final String DETAILS = "details"; public static final String STORAGE = "storage"; diff --git a/modMcf/src/org/aion/mcf/config/CfgDbDetails.java b/modMcf/src/org/aion/mcf/config/CfgDbDetails.java index e83a2c98bf..719c4be031 100644 --- a/modMcf/src/org/aion/mcf/config/CfgDbDetails.java +++ b/modMcf/src/org/aion/mcf/config/CfgDbDetails.java @@ -8,8 +8,8 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; -import org.aion.base.util.Utils; import org.aion.db.impl.DBVendor; +import org.aion.util.others.Utils; public class CfgDbDetails { diff --git a/modMcf/src/org/aion/mcf/config/CfgPrune.java b/modMcf/src/org/aion/mcf/config/CfgPrune.java index 2feea01177..98d595d2b6 100644 --- a/modMcf/src/org/aion/mcf/config/CfgPrune.java +++ b/modMcf/src/org/aion/mcf/config/CfgPrune.java @@ -4,14 +4,14 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; -import org.aion.base.db.IPruneConfig; +import org.aion.interfaces.db.PruneConfig; /** * Configuration for data pruning behavior. * * @author Alexandra Roatis */ -public class CfgPrune implements IPruneConfig { +public class CfgPrune implements PruneConfig { private boolean enabled; private boolean archived; diff --git a/modMcf/src/org/aion/mcf/core/FastImportResult.java b/modMcf/src/org/aion/mcf/core/FastImportResult.java new file mode 100644 index 0000000000..29064a28dd --- /dev/null +++ b/modMcf/src/org/aion/mcf/core/FastImportResult.java @@ -0,0 +1,21 @@ +package org.aion.mcf.core; + +/** + * Import results that can be returned when importing blocks using Fast Sync strategy. + * + * @author Alexandra Roatis + */ +public enum FastImportResult { + IMPORTED, + KNOWN, + NO_CHILD, + INVALID_BLOCK; + + public boolean isSuccessful() { + return equals(IMPORTED); + } + + public boolean isKnown() { + return equals(KNOWN); + } +} diff --git a/modMcf/src/org/aion/mcf/core/IBlockchain.java b/modMcf/src/org/aion/mcf/core/IBlockchain.java index 2c0d65b634..c301da5630 100644 --- a/modMcf/src/org/aion/mcf/core/IBlockchain.java +++ b/modMcf/src/org/aion/mcf/core/IBlockchain.java @@ -3,14 +3,14 @@ import java.math.BigInteger; import java.util.List; import java.util.Map; -import org.aion.base.type.IBlock; -import org.aion.base.type.ITransaction; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.block.Block; +import org.aion.interfaces.tx.Transaction; import org.aion.mcf.blockchain.IPowChain; import org.aion.mcf.types.AbstractBlockHeader; import org.aion.mcf.types.AbstractBlockSummary; import org.aion.mcf.types.AbstractTxReceipt; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; /** * Blockchain interface. @@ -23,9 +23,9 @@ */ @SuppressWarnings("rawtypes") public interface IBlockchain< - BLK extends IBlock, + BLK extends Block, BH extends AbstractBlockHeader, - TX extends ITransaction, + TX extends Transaction, TR extends AbstractTxReceipt, INFO extends AbstractTxInfo> extends IPowChain { @@ -124,7 +124,7 @@ void dropImported( // * Returns emptyList() for side chain blocks. // */ // List getListOfHeadersStartFrom( - // BlockIdentifier identifier, int skip, int limit, boolean reverse); + // BlockIdentifierImpl identifier, int skip, int limit, boolean reverse); List getListOfBodiesByHashes(List hashes); } diff --git a/modMcf/src/org/aion/mcf/core/TxTouchedStorage.java b/modMcf/src/org/aion/mcf/core/TxTouchedStorage.java index cd51900621..d9d948f595 100644 --- a/modMcf/src/org/aion/mcf/core/TxTouchedStorage.java +++ b/modMcf/src/org/aion/mcf/core/TxTouchedStorage.java @@ -3,18 +3,18 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; -import org.aion.base.util.Functional; -import org.aion.mcf.vm.types.DataWord; +import org.aion.interfaces.functional.Functional; +import org.aion.mcf.vm.types.DataWordImpl; import org.apache.commons.collections4.MapUtils; import org.apache.commons.collections4.keyvalue.AbstractKeyValue; public class TxTouchedStorage { - public static class Entry extends AbstractKeyValue { + public static class Entry extends AbstractKeyValue { private boolean changed; - public Entry(DataWord key, DataWord value, boolean changed) { + public Entry(DataWordImpl key, DataWordImpl value, boolean changed) { super(key, value); this.changed = changed; } @@ -24,12 +24,12 @@ public Entry() { } @Override - protected DataWord setKey(DataWord key) { + protected DataWordImpl setKey(DataWordImpl key) { return super.setKey(key); } @Override - protected DataWord setValue(DataWord value) { + protected DataWordImpl setValue(DataWordImpl value) { return super.setValue(value); } @@ -42,7 +42,7 @@ public void setChanged(boolean changed) { } } - private Map entries = new HashMap<>(); + private Map entries = new HashMap<>(); public TxTouchedStorage() {} @@ -60,28 +60,28 @@ public Entry add(Entry entry) { return entries.put(entry.getKey(), entry); } - private Entry add(Map.Entry entry, boolean changed) { + private Entry add(Map.Entry entry, boolean changed) { return add(new Entry(entry.getKey(), entry.getValue(), changed)); } - public void addReading(Map entries) { + public void addReading(Map entries) { if (MapUtils.isEmpty(entries)) return; - for (Map.Entry entry : entries.entrySet()) { + for (Map.Entry entry : entries.entrySet()) { if (!this.entries.containsKey(entry.getKey())) add(entry, false); } } - public void addWriting(Map entries) { + public void addWriting(Map entries) { if (MapUtils.isEmpty(entries)) return; - for (Map.Entry entry : entries.entrySet()) { + for (Map.Entry entry : entries.entrySet()) { add(entry, true); } } - private Map keyValues(Functional.Function filter) { - Map result = new HashMap<>(); + private Map keyValues(Functional.Function filter) { + Map result = new HashMap<>(); for (Entry entry : getEntries()) { if (filter == null || filter.apply(entry)) { result.put(entry.getKey(), entry.getValue()); @@ -90,7 +90,7 @@ private Map keyValues(Functional.Function fi return result; } - public Map getChanged() { + public Map getChanged() { return keyValues( new Functional.Function() { @Override @@ -100,7 +100,7 @@ public Boolean apply(Entry entry) { }); } - public Map getReadOnly() { + public Map getReadOnly() { return keyValues( new Functional.Function() { @Override @@ -110,7 +110,7 @@ public Boolean apply(Entry entry) { }); } - public Map getAll() { + public Map getAll() { return keyValues(null); } diff --git a/modMcf/src/org/aion/mcf/db/AbstractRepository.java b/modMcf/src/org/aion/mcf/db/AbstractRepository.java index df8cf8a5ee..9a25949dec 100644 --- a/modMcf/src/org/aion/mcf/db/AbstractRepository.java +++ b/modMcf/src/org/aion/mcf/db/AbstractRepository.java @@ -11,11 +11,11 @@ import java.util.Properties; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.db.IRepository; -import org.aion.base.db.IRepositoryConfig; -import org.aion.base.type.IBlockHeader; -import org.aion.base.type.ITransaction; +import org.aion.interfaces.block.BlockHeader; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.Repository; +import org.aion.interfaces.db.RepositoryConfig; +import org.aion.interfaces.tx.Transaction; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.aion.mcf.config.CfgDb.Names; @@ -31,17 +31,17 @@ /** Abstract Repository class. */ public abstract class AbstractRepository< - BLK extends AbstractBlock, - BH extends IBlockHeader, + BLK extends AbstractBlock, + BH extends BlockHeader, BSB extends IBlockStoreBase> - implements IRepository { + implements Repository { // Logger protected static final Logger LOG = AionLoggerFactory.getLogger(LogEnum.DB.name()); protected static final Logger LOGGEN = AionLoggerFactory.getLogger(LogEnum.GEN.name()); // Configuration parameter - protected IRepositoryConfig cfg; + protected RepositoryConfig cfg; /** ********* Database Name Constants ********** */ protected static final String TRANSACTION_DB = Names.TRANSACTION; @@ -49,6 +49,7 @@ public abstract class AbstractRepository< protected static final String INDEX_DB = Names.INDEX; protected static final String BLOCK_DB = Names.BLOCK; protected static final String PENDING_BLOCK_DB = Names.PENDING_BLOCK; + protected static final String CONTRACT_INDEX_DB = Names.CONTRACT_INDEX; protected static final String DETAILS_DB = Names.DETAILS; protected static final String STORAGE_DB = Names.STORAGE; protected static final String STATE_DB = Names.STATE; @@ -64,18 +65,19 @@ public abstract class AbstractRepository< // File(System.getProperty("user.dir"), "database").getAbsolutePath(); /** ******** Database and Cache parameters ************* */ - protected IByteArrayKeyValueDatabase transactionDatabase; + protected ByteArrayKeyValueDatabase transactionDatabase; - protected IByteArrayKeyValueDatabase detailsDatabase; - protected IByteArrayKeyValueDatabase storageDatabase; - protected IByteArrayKeyValueDatabase indexDatabase; - protected IByteArrayKeyValueDatabase blockDatabase; - protected IByteArrayKeyValueDatabase stateDatabase; - protected IByteArrayKeyValueDatabase stateArchiveDatabase; - protected IByteArrayKeyValueDatabase txPoolDatabase; - protected IByteArrayKeyValueDatabase pendingTxCacheDatabase; + protected ByteArrayKeyValueDatabase contractIndexDatabase; + protected ByteArrayKeyValueDatabase detailsDatabase; + protected ByteArrayKeyValueDatabase storageDatabase; + protected ByteArrayKeyValueDatabase indexDatabase; + protected ByteArrayKeyValueDatabase blockDatabase; + protected ByteArrayKeyValueDatabase stateDatabase; + protected ByteArrayKeyValueDatabase stateArchiveDatabase; + protected ByteArrayKeyValueDatabase txPoolDatabase; + protected ByteArrayKeyValueDatabase pendingTxCacheDatabase; - protected Collection databaseGroup; + protected Collection databaseGroup; protected ArchivedDataSource stateWithArchive; protected JournalPruneDataSource stateDSPrune; @@ -184,6 +186,17 @@ protected void initializeDatabasesAndCaches() throws InvalidFilePathException { } databaseGroup.add(transactionDatabase); + // getting details specific properties + sharedProps = cfg.getDatabaseConfig(CONTRACT_INDEX_DB); + sharedProps.setProperty(Props.ENABLE_LOCKING, "false"); + sharedProps.setProperty(Props.DB_PATH, cfg.getDbPath()); + sharedProps.setProperty(Props.DB_NAME, CONTRACT_INDEX_DB); + this.contractIndexDatabase = connectAndOpen(sharedProps, LOG); + if (contractIndexDatabase == null || contractIndexDatabase.isClosed()) { + throw newException(CONTRACT_INDEX_DB, sharedProps); + } + databaseGroup.add(contractIndexDatabase); + // getting details specific properties sharedProps = cfg.getDatabaseConfig(DETAILS_DB); sharedProps.setProperty(Props.ENABLE_LOCKING, "false"); diff --git a/modMcf/src/org/aion/mcf/db/AbstractRepositoryCache.java b/modMcf/src/org/aion/mcf/db/AbstractRepositoryCache.java deleted file mode 100644 index 5cc0202e84..0000000000 --- a/modMcf/src/org/aion/mcf/db/AbstractRepositoryCache.java +++ /dev/null @@ -1,388 +0,0 @@ -package org.aion.mcf.db; - -import static org.aion.crypto.HashUtil.h256; -import static org.aion.util.bytes.ByteUtil.EMPTY_BYTE_ARRAY; - -import java.math.BigInteger; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import org.aion.base.db.IContractDetails; -import org.aion.base.db.IRepository; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.log.AionLoggerFactory; -import org.aion.log.LogEnum; -import org.aion.mcf.core.AccountState; -import org.aion.vm.api.interfaces.Address; -import org.slf4j.Logger; - -/** - * Abstract repository cache. - * - * @author Alexandra Roatis - */ -public abstract class AbstractRepositoryCache> - implements IRepositoryCache { - - // Logger - protected static final Logger LOG = AionLoggerFactory.getLogger(LogEnum.DB.name()); - - /** the repository being tracked */ - protected IRepository repository; - - /** local accounts cache */ - protected Map cachedAccounts; - - protected ReadWriteLock lockAccounts = new ReentrantReadWriteLock(); - /** local contract details cache */ - protected Map cachedDetails; - - protected ReadWriteLock lockDetails = new ReentrantReadWriteLock(); - - @Override - public AccountState createAccount(Address address) { - fullyWriteLock(); - try { - AccountState accountState = new AccountState(); - cachedAccounts.put(address, accountState); - - // TODO: unify contract details initialization from Impl and Track - IContractDetails contractDetails = new ContractDetailsCacheImpl(null); - // TODO: refactor to use makeDirty() from AbstractState - contractDetails.setDirty(true); - cachedDetails.put(address, contractDetails); - - return accountState; - } finally { - fullyWriteUnlock(); - } - } - - /** - * Retrieves the current state of the account associated with the given address. - * - * @param address the address of the account of interest - * @return a {@link AccountState} object representing the account state as is stored in the - * database or cache - * @implNote If there is no account associated with the given address, it will create it. - */ - @Override - public AccountState getAccountState(Address address) { - lockAccounts.readLock().lock(); - - try { - // check if the account is cached locally - AccountState accountState = this.cachedAccounts.get(address); - - // when the account is not cached load it from the repository - if (accountState == null) { - // must unlock to perform write operation from loadAccountState(address) - lockAccounts.readLock().unlock(); - loadAccountState(address); - lockAccounts.readLock().lock(); - accountState = this.cachedAccounts.get(address); - } - - return accountState; - } finally { - try { - lockAccounts.readLock().unlock(); - } catch (Exception e) { - // there was nothing to unlock - } - } - } - - public boolean hasAccountState(Address address) { - lockAccounts.readLock().lock(); - try { - AccountState accountState = cachedAccounts.get(address); - - if (accountState != null) { - // checks that the account is not cached as deleted - // TODO: may also need to check if the state is empty - return !accountState.isDeleted(); - } else { - // check repository when not cached - return repository.hasAccountState(address); - } - } finally { - lockAccounts.readLock().unlock(); - } - } - - @Override - public IContractDetails getContractDetails(Address address) { - lockDetails.readLock().lock(); - - try { - IContractDetails contractDetails = this.cachedDetails.get(address); - - if (contractDetails == null) { - // loads the address into cache - // must unlock to perform write operation from loadAccountState(address) - lockDetails.readLock().unlock(); - loadAccountState(address); - lockDetails.readLock().lock(); - // retrieves the contract details - contractDetails = this.cachedDetails.get(address); - } - - return contractDetails; - } finally { - try { - lockDetails.readLock().unlock(); - } catch (Exception e) { - // there was nothing to unlock - } - } - } - - @Override - public boolean hasContractDetails(Address address) { - lockDetails.readLock().lock(); - - try { - IContractDetails contractDetails = cachedDetails.get(address); - - if (contractDetails == null) { - // ask repository when not cached - return repository.hasContractDetails(address); - } else { - // TODO: may also need to check if the details are empty - return !contractDetails.isDeleted(); - } - } finally { - lockDetails.readLock().unlock(); - } - } - - /** - * @implNote The loaded objects are fresh copies of the locally cached account state and - * contract details. - */ - @Override - public void loadAccountState( - Address address, - Map accounts, - Map details) { - fullyReadLock(); - - try { - // check if the account is cached locally - AccountState accountState = this.cachedAccounts.get(address); - IContractDetails contractDetails = this.cachedDetails.get(address); - - // when account not cached load from repository - if (accountState == null) { - // load directly to the caches given as parameters - repository.loadAccountState(address, accounts, details); - } else { - // copy the objects if they were cached locally - accounts.put(address, new AccountState(accountState)); - details.put(address, new ContractDetailsCacheImpl(contractDetails)); - } - } finally { - fullyReadUnlock(); - } - } - - /** - * Loads the state of the account into this object' caches. Requires write locks on both - * {@link #lockAccounts} and {@link #lockDetails}. - * - * @implNote If the calling method has acquired a weaker lock, the lock must be released before - * calling this method. - * @apiNote If the account was never stored this call will create it. - */ - private void loadAccountState(Address address) { - fullyWriteLock(); - try { - repository.loadAccountState(address, this.cachedAccounts, this.cachedDetails); - } finally { - fullyWriteUnlock(); - } - } - - @Override - public void deleteAccount(Address address) { - fullyWriteLock(); - try { - getAccountState(address).delete(); - getContractDetails(address).setDeleted(true); - } finally { - fullyWriteUnlock(); - } - } - - @Override - public BigInteger incrementNonce(Address address) { - lockAccounts.writeLock().lock(); - try { - return getAccountState(address).incrementNonce(); - } finally { - lockAccounts.writeLock().unlock(); - } - } - - @Override - public BigInteger setNonce(Address address, BigInteger newNonce) { - lockAccounts.writeLock().lock(); - try { - return getAccountState(address).setNonce(newNonce); - } finally { - lockAccounts.writeLock().unlock(); - } - } - - @Override - public BigInteger getNonce(Address address) { - AccountState accountState = getAccountState(address); - // account state can never be null, but may be empty or deleted - return (accountState.isEmpty() || accountState.isDeleted()) - ? BigInteger.ZERO - : accountState.getNonce(); - } - - @Override - public BigInteger getBalance(Address address) { - AccountState accountState = getAccountState(address); - // account state can never be null, but may be empty or deleted - return (accountState.isEmpty() || accountState.isDeleted()) - ? BigInteger.ZERO - : accountState.getBalance(); - } - - @Override - public BigInteger addBalance(Address address, BigInteger value) { - lockAccounts.writeLock().lock(); - try { - // TODO: where do we ensure that this does not result in a negative value? - AccountState accountState = getAccountState(address); - return accountState.addToBalance(value); - } finally { - lockAccounts.writeLock().unlock(); - } - } - - @Override - public void saveCode(Address address, byte[] code) { - fullyWriteLock(); - try { - // save the code - // TODO: why not create contract here directly? also need to check that there is no - // preexisting code! - IContractDetails contractDetails = getContractDetails(address); - contractDetails.setCode(code); - // TODO: ensure that setDirty is done by the class itself - contractDetails.setDirty(true); - - // update the code hash - getAccountState(address).setCodeHash(h256(code)); - } finally { - fullyWriteUnlock(); - } - } - - @Override - public byte[] getCode(Address address) { - if (!hasAccountState(address)) { - return EMPTY_BYTE_ARRAY; - } - - byte[] codeHash = getAccountState(address).getCodeHash(); - - // TODO: why use codeHash here? may require refactoring - return getContractDetails(address).getCode(codeHash); - } - - @Override - public void addStorageRow(Address address, ByteArrayWrapper key, ByteArrayWrapper value) { - lockDetails.writeLock().lock(); - try { - getContractDetails(address).put(key, value); - } finally { - lockDetails.writeLock().unlock(); - } - } - - @Override - public void removeStorageRow(Address address, ByteArrayWrapper key) { - lockDetails.writeLock().lock(); - try { - getContractDetails(address).delete(key); - } finally { - lockDetails.writeLock().unlock(); - } - } - - @Override - public ByteArrayWrapper getStorageValue(Address address, ByteArrayWrapper key) { - return getContractDetails(address).get(key); - } - - @Override - public Map getStorage( - Address address, Collection keys) { - IContractDetails details = getContractDetails(address); - return (details == null) ? Collections.emptyMap() : details.getStorage(keys); - } - - @Override - public void rollback() { - fullyWriteLock(); - try { - cachedAccounts.clear(); - cachedDetails.clear(); - } finally { - fullyWriteUnlock(); - } - } - - @Override - public IRepository getSnapshotTo(byte[] root) { - return repository.getSnapshotTo(root); - } - - // This method was originally disabled because changes to the blockstore - // can not be reverted. The reason for re-enabling it is that we have no way - // to - // get a reference of the blockstore without using - // NProgInvoke/NcpProgInvoke. - @Override - public BSB getBlockStore() { - return repository.getBlockStore(); - } - - /** Lock to prevent writing on both accounts and details. */ - protected void fullyWriteLock() { - lockAccounts.writeLock().lock(); - lockDetails.writeLock().lock(); - } - - /** Unlock to allow writing on both accounts and details. */ - protected void fullyWriteUnlock() { - lockDetails.writeLock().unlock(); - lockAccounts.writeLock().unlock(); - } - - /** Lock for reading both accounts and details. */ - protected void fullyReadLock() { - lockAccounts.readLock().lock(); - lockDetails.readLock().lock(); - } - - /** Unlock reading for both accounts and details. */ - protected void fullyReadUnlock() { - lockDetails.readLock().unlock(); - lockAccounts.readLock().unlock(); - } - - @Override - public boolean isSnapshot() { - return repository.isSnapshot(); - } -} diff --git a/modMcf/src/org/aion/mcf/db/DatabaseUtils.java b/modMcf/src/org/aion/mcf/db/DatabaseUtils.java index 55e21019a6..8276dad4a0 100644 --- a/modMcf/src/org/aion/mcf/db/DatabaseUtils.java +++ b/modMcf/src/org/aion/mcf/db/DatabaseUtils.java @@ -9,19 +9,19 @@ import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.Properties; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.db.PersistenceMethod; import org.aion.db.impl.DatabaseFactory; import org.aion.db.impl.DatabaseFactory.Props; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.PersistenceMethod; import org.aion.mcf.db.exception.InvalidFilePathException; import org.slf4j.Logger; /** @author Alexandra Roatis */ public class DatabaseUtils { - public static IByteArrayKeyValueDatabase connectAndOpen(Properties info, Logger LOG) { + public static ByteArrayKeyValueDatabase connectAndOpen(Properties info, Logger LOG) { // get the database object - IByteArrayKeyValueDatabase db = DatabaseFactory.connect(info, LOG.isDebugEnabled()); + ByteArrayKeyValueDatabase db = DatabaseFactory.connect(info, LOG.isDebugEnabled()); // open the database connection db.open(); diff --git a/modMcf/src/org/aion/mcf/db/DetailsDataStore.java b/modMcf/src/org/aion/mcf/db/DetailsDataStore.java index a6060d7c7a..e89a39ad62 100644 --- a/modMcf/src/org/aion/mcf/db/DetailsDataStore.java +++ b/modMcf/src/org/aion/mcf/db/DetailsDataStore.java @@ -1,45 +1,45 @@ package org.aion.mcf.db; -import static org.aion.base.util.ByteArrayWrapper.wrap; +import static org.aion.types.ByteArrayWrapper.wrap; import java.util.HashSet; import java.util.Iterator; import java.util.Optional; import java.util.Set; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.db.IContractDetails; -import org.aion.base.db.IRepositoryConfig; -import org.aion.base.type.IBlockHeader; -import org.aion.base.type.ITransaction; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.block.BlockHeader; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.ContractDetails; +import org.aion.interfaces.db.RepositoryConfig; +import org.aion.interfaces.tx.Transaction; import org.aion.mcf.trie.JournalPruneDataSource; import org.aion.mcf.types.AbstractBlock; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; /** Detail data storage , */ public class DetailsDataStore< - BLK extends AbstractBlock, BH extends IBlockHeader> { + BLK extends AbstractBlock, BH extends BlockHeader> { private JournalPruneDataSource storageDSPrune; - private IRepositoryConfig repoConfig; + private RepositoryConfig repoConfig; - private IByteArrayKeyValueDatabase detailsSrc; - private IByteArrayKeyValueDatabase storageSrc; + private ByteArrayKeyValueDatabase detailsSrc; + private ByteArrayKeyValueDatabase storageSrc; private Set removes = new HashSet<>(); public DetailsDataStore() {} public DetailsDataStore( - IByteArrayKeyValueDatabase detailsCache, - IByteArrayKeyValueDatabase storageCache, - IRepositoryConfig repoConfig) { + ByteArrayKeyValueDatabase detailsCache, + ByteArrayKeyValueDatabase storageCache, + RepositoryConfig repoConfig) { this.repoConfig = repoConfig; withDb(detailsCache, storageCache); } public DetailsDataStore withDb( - IByteArrayKeyValueDatabase detailsSrc, IByteArrayKeyValueDatabase storageSrc) { + ByteArrayKeyValueDatabase detailsSrc, ByteArrayKeyValueDatabase storageSrc) { this.detailsSrc = detailsSrc; this.storageSrc = storageSrc; this.storageDSPrune = new JournalPruneDataSource(storageSrc); @@ -52,7 +52,7 @@ public DetailsDataStore withDb( * @param key * @return */ - public synchronized IContractDetails get(byte[] key) { + public synchronized ContractDetails get(byte[] key) { ByteArrayWrapper wrappedKey = wrap(key); Optional rawDetails = detailsSrc.get(key); @@ -67,7 +67,7 @@ public synchronized IContractDetails get(byte[] key) { } // Found something from cache or database, return it by decoding it. - IContractDetails detailsImpl = repoConfig.contractDetailsImpl(); + ContractDetails detailsImpl = repoConfig.contractDetailsImpl(); detailsImpl.setDataSource(storageDSPrune); detailsImpl.decode(rawDetails.get()); // We can safely get as we checked // if it is present. @@ -75,7 +75,7 @@ public synchronized IContractDetails get(byte[] key) { return detailsImpl; } - public synchronized void update(Address key, IContractDetails contractDetails) { + public synchronized void update(Address key, ContractDetails contractDetails) { contractDetails.setAddress(key); ByteArrayWrapper wrappedKey = wrap(key.toBytes()); @@ -139,12 +139,12 @@ public void syncLargeStorage() { } // Decode the details. - IContractDetails detailsImpl = repoConfig.contractDetailsImpl(); + ContractDetails detailsImpl = repoConfig.contractDetailsImpl(); detailsImpl.setDataSource(storageDSPrune); detailsImpl.decode(rawDetails.get(), true); // We can safely get as we checked if it is present. - // IContractDetails details = entry.getValue(); + // ContractDetails details = entry.getValue(); detailsImpl.syncStorage(); } } @@ -157,6 +157,15 @@ public synchronized Iterator keys() { return new DetailsIteratorWrapper(detailsSrc.keys()); } + public synchronized void close() { + try { + detailsSrc.close(); + storageSrc.close(); + } catch (Exception e) { + throw new RuntimeException("error closing db"); + } + } + /** * A wrapper for the iterator needed by {@link DetailsDataStore} conforming to the {@link * Iterator} interface. @@ -184,13 +193,4 @@ public ByteArrayWrapper next() { return wrap(sourceIterator.next()); } } - - public synchronized void close() { - try { - detailsSrc.close(); - storageSrc.close(); - } catch (Exception e) { - throw new RuntimeException("error closing db"); - } - } } diff --git a/modMcf/src/org/aion/mcf/db/IBlockStoreBase.java b/modMcf/src/org/aion/mcf/db/IBlockStoreBase.java index 6f9070f115..d3e7f8e25c 100644 --- a/modMcf/src/org/aion/mcf/db/IBlockStoreBase.java +++ b/modMcf/src/org/aion/mcf/db/IBlockStoreBase.java @@ -1,7 +1,7 @@ package org.aion.mcf.db; import java.util.List; -import org.aion.base.type.IBlock; +import org.aion.interfaces.block.Block; import org.aion.mcf.types.AbstractBlockHeader; /** @@ -10,7 +10,7 @@ * @param * @param */ -public interface IBlockStoreBase, BH extends AbstractBlockHeader> { +public interface IBlockStoreBase, BH extends AbstractBlockHeader> { byte[] getBlockHashByNumber(long blockNumber); diff --git a/modMcf/src/org/aion/mcf/db/IBlockStorePow.java b/modMcf/src/org/aion/mcf/db/IBlockStorePow.java index 21111701df..4a7cd5c17d 100644 --- a/modMcf/src/org/aion/mcf/db/IBlockStorePow.java +++ b/modMcf/src/org/aion/mcf/db/IBlockStorePow.java @@ -1,7 +1,7 @@ package org.aion.mcf.db; import java.math.BigInteger; -import org.aion.base.type.IBlock; +import org.aion.interfaces.block.Block; import org.aion.mcf.types.AbstractBlockHeader; /** @@ -10,7 +10,7 @@ * @param * @param */ -public interface IBlockStorePow, BH extends AbstractBlockHeader> +public interface IBlockStorePow, BH extends AbstractBlockHeader> extends IBlockStoreBase { BigInteger getTotalDifficultyForHash(byte[] hash); diff --git a/modMcf/src/org/aion/mcf/db/TransactionStore.java b/modMcf/src/org/aion/mcf/db/TransactionStore.java index c47e7a3f53..fd5883b0a1 100644 --- a/modMcf/src/org/aion/mcf/db/TransactionStore.java +++ b/modMcf/src/org/aion/mcf/db/TransactionStore.java @@ -1,6 +1,6 @@ package org.aion.mcf.db; -import static org.aion.base.util.Utils.dummy; +import static org.aion.util.others.Utils.dummy; import java.io.Closeable; import java.util.ArrayList; @@ -8,14 +8,14 @@ import java.util.List; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import org.aion.base.db.Flushable; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.Flushable; import org.aion.mcf.core.AbstractTxInfo; import org.aion.mcf.ds.ObjectDataSource; import org.aion.mcf.ds.Serializer; import org.aion.mcf.types.AbstractTransaction; import org.aion.mcf.types.AbstractTxReceipt; +import org.aion.types.ByteArrayWrapper; import org.apache.commons.collections4.map.LRUMap; public class TransactionStore< @@ -29,7 +29,7 @@ public class TransactionStore< private final ReadWriteLock lock = new ReentrantReadWriteLock(); public TransactionStore( - IByteArrayKeyValueDatabase src, Serializer, byte[]> serializer) { + ByteArrayKeyValueDatabase src, Serializer, byte[]> serializer) { source = new ObjectDataSource(src, serializer); } diff --git a/modMcf/src/org/aion/mcf/ds/ArchivedDataSource.java b/modMcf/src/org/aion/mcf/ds/ArchivedDataSource.java index 9261e7c50e..75280cdd87 100644 --- a/modMcf/src/org/aion/mcf/ds/ArchivedDataSource.java +++ b/modMcf/src/org/aion/mcf/ds/ArchivedDataSource.java @@ -4,19 +4,19 @@ import java.util.Iterator; import java.util.Map; import java.util.Optional; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.db.IByteArrayKeyValueStore; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.ByteArrayKeyValueStore; /** * A data source with archived data that must no be deleted. * * @author Alexandra Roatis */ -public class ArchivedDataSource implements IByteArrayKeyValueStore { +public class ArchivedDataSource implements ByteArrayKeyValueStore { - IByteArrayKeyValueDatabase data, archive; + ByteArrayKeyValueDatabase data, archive; - public ArchivedDataSource(IByteArrayKeyValueDatabase _db, IByteArrayKeyValueDatabase _archive) { + public ArchivedDataSource(ByteArrayKeyValueDatabase _db, ByteArrayKeyValueDatabase _archive) { this.data = _db; this.archive = _archive; } @@ -99,7 +99,7 @@ public void close() { archive.close(); } - public IByteArrayKeyValueDatabase getArchiveDatabase() { + public ByteArrayKeyValueDatabase getArchiveDatabase() { return archive; } } diff --git a/modMcf/src/org/aion/mcf/ds/DataSourceArray.java b/modMcf/src/org/aion/mcf/ds/DataSourceArray.java index 3de2ce400d..43ce82ce46 100644 --- a/modMcf/src/org/aion/mcf/ds/DataSourceArray.java +++ b/modMcf/src/org/aion/mcf/ds/DataSourceArray.java @@ -2,7 +2,7 @@ import java.io.Closeable; import java.util.Optional; -import org.aion.base.db.Flushable; +import org.aion.interfaces.db.Flushable; import org.aion.util.bytes.ByteUtil; import org.aion.util.conversions.Hex; diff --git a/modMcf/src/org/aion/mcf/ds/ObjectDataSource.java b/modMcf/src/org/aion/mcf/ds/ObjectDataSource.java index 927156b55b..6ff80ef61a 100644 --- a/modMcf/src/org/aion/mcf/ds/ObjectDataSource.java +++ b/modMcf/src/org/aion/mcf/ds/ObjectDataSource.java @@ -2,8 +2,8 @@ import java.io.Closeable; import java.util.Optional; -import org.aion.base.db.Flushable; -import org.aion.base.db.IByteArrayKeyValueDatabase; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.Flushable; /** * Object Datasource. @@ -12,10 +12,10 @@ */ public class ObjectDataSource implements Flushable, Closeable { - private IByteArrayKeyValueDatabase src; - Serializer serializer; + private ByteArrayKeyValueDatabase src; + private Serializer serializer; - public ObjectDataSource(IByteArrayKeyValueDatabase src, Serializer serializer) { + public ObjectDataSource(ByteArrayKeyValueDatabase src, Serializer serializer) { this.src = src; this.serializer = serializer; } @@ -62,7 +62,7 @@ public V get(byte[] key) { } /** Returns the underlying cache source. */ - protected IByteArrayKeyValueDatabase getSrc() { + protected ByteArrayKeyValueDatabase getSrc() { return src; } diff --git a/modMcf/src/org/aion/mcf/ds/XorDataSource.java b/modMcf/src/org/aion/mcf/ds/XorDataSource.java index d004e5020e..5e67a675b9 100644 --- a/modMcf/src/org/aion/mcf/ds/XorDataSource.java +++ b/modMcf/src/org/aion/mcf/ds/XorDataSource.java @@ -5,15 +5,15 @@ import java.util.Iterator; import java.util.Map; import java.util.Optional; -import org.aion.base.db.IByteArrayKeyValueStore; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.db.ByteArrayKeyValueStore; +import org.aion.types.ByteArrayWrapper; import org.aion.util.bytes.ByteUtil; -public class XorDataSource implements IByteArrayKeyValueStore { - private final IByteArrayKeyValueStore source; +public class XorDataSource implements ByteArrayKeyValueStore { + private final ByteArrayKeyValueStore source; private final byte[] subKey; - public XorDataSource(IByteArrayKeyValueStore source, byte[] subKey) { + public XorDataSource(ByteArrayKeyValueStore source, byte[] subKey) { this.source = source; this.subKey = subKey; } @@ -92,7 +92,10 @@ public void close() throws Exception { @Override public void deleteBatch(Collection keys) { - // TODO Auto-generated method stub + // NOTE: implementing this method will cause a break in consensus + // due to the fact that the serialized storage must have old roots + // to enable reverting to a different state for the account in case of a fork + // TODO remove this black magic :P } @Override diff --git a/modMcf/src/org/aion/mcf/evt/IListenerBase.java b/modMcf/src/org/aion/mcf/evt/IListenerBase.java index d6955489bd..d3afcdffe2 100644 --- a/modMcf/src/org/aion/mcf/evt/IListenerBase.java +++ b/modMcf/src/org/aion/mcf/evt/IListenerBase.java @@ -1,15 +1,15 @@ package org.aion.mcf.evt; -import org.aion.base.type.IBlock; -import org.aion.base.type.ITransaction; +import org.aion.interfaces.block.Block; +import org.aion.interfaces.tx.Transaction; import org.aion.mcf.blockchain.IPendingStateInternal; import org.aion.mcf.types.AbstractBlockSummary; import org.aion.mcf.types.AbstractTxReceipt; /** Listener base interface. */ public interface IListenerBase< - BLK extends IBlock, - TX extends ITransaction, + BLK extends Block, + TX extends Transaction, TXR extends AbstractTxReceipt, BS extends AbstractBlockSummary> { diff --git a/modMcf/src/org/aion/mcf/evt/IPowListener.java b/modMcf/src/org/aion/mcf/evt/IPowListener.java index 0e0952b6f2..f483083df1 100644 --- a/modMcf/src/org/aion/mcf/evt/IPowListener.java +++ b/modMcf/src/org/aion/mcf/evt/IPowListener.java @@ -1,9 +1,9 @@ package org.aion.mcf.evt; import java.util.List; -import org.aion.base.type.IBlock; -import org.aion.base.type.ITransaction; -import org.aion.base.type.ITxExecSummary; +import org.aion.interfaces.block.Block; +import org.aion.interfaces.tx.Transaction; +import org.aion.interfaces.tx.TxExecSummary; import org.aion.mcf.types.AbstractBlockSummary; import org.aion.mcf.types.AbstractTxReceipt; @@ -16,8 +16,8 @@ * @param */ public interface IPowListener< - BLK extends IBlock, - TX extends ITransaction, + BLK extends Block, + TX extends Transaction, TXR extends AbstractTxReceipt, BS extends AbstractBlockSummary> extends IListenerBase { @@ -33,5 +33,5 @@ public interface IPowListener< void onVMTraceCreated(String transactionHash, String trace); - void onTransactionExecuted(ITxExecSummary summary); + void onTransactionExecuted(TxExecSummary summary); } diff --git a/modMcf/src/org/aion/mcf/mine/AbstractMineRunner.java b/modMcf/src/org/aion/mcf/mine/AbstractMineRunner.java index 84eddbe0dc..a24aead720 100644 --- a/modMcf/src/org/aion/mcf/mine/AbstractMineRunner.java +++ b/modMcf/src/org/aion/mcf/mine/AbstractMineRunner.java @@ -1,12 +1,12 @@ package org.aion.mcf.mine; -import org.aion.base.type.IBlock; +import org.aion.interfaces.block.Block; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.slf4j.Logger; /** Abstract Miner. */ -public abstract class AbstractMineRunner> implements IMineRunner { +public abstract class AbstractMineRunner> implements IMineRunner { protected static final Logger LOG = AionLoggerFactory.getLogger(LogEnum.CONS.name()); diff --git a/modMcf/src/org/aion/mcf/mine/IMiner.java b/modMcf/src/org/aion/mcf/mine/IMiner.java index 09e9481353..89d38015a9 100644 --- a/modMcf/src/org/aion/mcf/mine/IMiner.java +++ b/modMcf/src/org/aion/mcf/mine/IMiner.java @@ -1,7 +1,7 @@ package org.aion.mcf.mine; import com.google.common.util.concurrent.ListenableFuture; -import org.aion.base.type.IBlock; +import org.aion.interfaces.block.Block; import org.aion.mcf.types.AbstractBlockHeader; /** @@ -10,7 +10,7 @@ * @param * @param */ -public interface IMiner, BH extends AbstractBlockHeader> { +public interface IMiner, BH extends AbstractBlockHeader> { ListenableFuture mine(Blk block); diff --git a/modMcf/src/org/aion/mcf/mine/IMinerListener.java b/modMcf/src/org/aion/mcf/mine/IMinerListener.java index 77eccc3e0f..0eae458535 100644 --- a/modMcf/src/org/aion/mcf/mine/IMinerListener.java +++ b/modMcf/src/org/aion/mcf/mine/IMinerListener.java @@ -1,13 +1,13 @@ package org.aion.mcf.mine; -import org.aion.base.type.IBlock; +import org.aion.interfaces.block.Block; /** * Miner Listener interface. * * @param */ -public interface IMinerListener> { +public interface IMinerListener> { void miningStarted(); diff --git a/modMcf/src/org/aion/mcf/trie/Cache.java b/modMcf/src/org/aion/mcf/trie/Cache.java index 5ee283f42d..71d437c2af 100644 --- a/modMcf/src/org/aion/mcf/trie/Cache.java +++ b/modMcf/src/org/aion/mcf/trie/Cache.java @@ -1,7 +1,7 @@ package org.aion.mcf.trie; -import static org.aion.base.util.ByteArrayWrapper.wrap; import static org.aion.rlp.Value.fromRlpEncoded; +import static org.aion.types.ByteArrayWrapper.wrap; import java.util.ArrayList; import java.util.Arrays; @@ -14,12 +14,12 @@ import java.util.Map.Entry; import java.util.Optional; import java.util.Set; -import org.aion.base.db.IByteArrayKeyValueStore; -import org.aion.base.util.ByteArrayWrapper; import org.aion.crypto.HashUtil; +import org.aion.interfaces.db.ByteArrayKeyValueStore; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.aion.rlp.Value; +import org.aion.types.ByteArrayWrapper; import org.slf4j.Logger; /** Cache class */ @@ -27,12 +27,12 @@ public class Cache { private static final Logger LOG = AionLoggerFactory.getLogger(LogEnum.DB.name()); - private IByteArrayKeyValueStore dataSource; + private ByteArrayKeyValueStore dataSource; private Map nodes = new LinkedHashMap<>(); private Set removedNodes = new HashSet<>(); private boolean isDirty; - public Cache(IByteArrayKeyValueStore dataSource) { + public Cache(ByteArrayKeyValueStore dataSource) { this.dataSource = dataSource; } @@ -152,7 +152,7 @@ public synchronized Map getNodes() { return nodes; } - public synchronized IByteArrayKeyValueStore getDb() { + public synchronized ByteArrayKeyValueStore getDb() { return dataSource; } @@ -174,7 +174,7 @@ public synchronized IByteArrayKeyValueStore getDb() { // } @SuppressWarnings("OptionalGetWithoutIsPresent") - public synchronized void setDB(IByteArrayKeyValueStore kvds) { + public synchronized void setDB(ByteArrayKeyValueStore kvds) { if (this.dataSource == kvds) { return; } diff --git a/modMcf/src/org/aion/mcf/trie/JournalPruneDataSource.java b/modMcf/src/org/aion/mcf/trie/JournalPruneDataSource.java index 77aa6d207b..49943f3ef9 100644 --- a/modMcf/src/org/aion/mcf/trie/JournalPruneDataSource.java +++ b/modMcf/src/org/aion/mcf/trie/JournalPruneDataSource.java @@ -13,12 +13,12 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.db.IByteArrayKeyValueStore; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.ByteArrayKeyValueStore; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.aion.mcf.ds.ArchivedDataSource; +import org.aion.types.ByteArrayWrapper; import org.slf4j.Logger; /** @@ -28,7 +28,7 @@ * submitted to the underlying DataSource with respect to following inserts. E.g. if the key was * deleted at block N and then inserted at block N + 10 this delete is not passed. */ -public class JournalPruneDataSource implements IByteArrayKeyValueStore { +public class JournalPruneDataSource implements ByteArrayKeyValueStore { private final ReadWriteLock lock = new ReentrantReadWriteLock(); private static final Logger LOG = AionLoggerFactory.getLogger(LogEnum.DB.name()); @@ -61,14 +61,14 @@ public String toString() { Map refCount = new HashMap<>(); - private IByteArrayKeyValueStore src; + private ByteArrayKeyValueStore src; // block hash => updates private LinkedHashMap blockUpdates = new LinkedHashMap<>(); private Updates currentUpdates = new Updates(); private AtomicBoolean enabled = new AtomicBoolean(false); private final boolean hasArchive; - public JournalPruneDataSource(IByteArrayKeyValueStore src) { + public JournalPruneDataSource(ByteArrayKeyValueStore src) { this.src = src; this.hasArchive = src instanceof ArchivedDataSource; } @@ -403,11 +403,11 @@ public boolean isEmpty() { } } - public IByteArrayKeyValueStore getSrc() { + public ByteArrayKeyValueStore getSrc() { return src; } - public IByteArrayKeyValueDatabase getArchiveSource() { + public ByteArrayKeyValueDatabase getArchiveSource() { if (!hasArchive) { return null; } else { diff --git a/modMcf/src/org/aion/mcf/trie/SecureTrie.java b/modMcf/src/org/aion/mcf/trie/SecureTrie.java index 771cd79fbc..f4cc8d69f6 100644 --- a/modMcf/src/org/aion/mcf/trie/SecureTrie.java +++ b/modMcf/src/org/aion/mcf/trie/SecureTrie.java @@ -3,15 +3,15 @@ import static org.aion.crypto.HashUtil.h256; import java.util.Arrays; -import org.aion.base.db.IByteArrayKeyValueStore; +import org.aion.interfaces.db.ByteArrayKeyValueStore; public class SecureTrie extends TrieImpl implements Trie { - public SecureTrie(IByteArrayKeyValueStore db) { + public SecureTrie(ByteArrayKeyValueStore db) { this(db, ""); } - public SecureTrie(IByteArrayKeyValueStore db, Object root) { + public SecureTrie(ByteArrayKeyValueStore db, Object root) { super(db, root); } @@ -38,7 +38,7 @@ public void delete(byte[] key) { * Returns a copy of this trie. * *

    The {@link Cache} object returned will be a copy of this object's cache, but the two will - * share the same references to their data sources ({@link IByteArrayKeyValueStore} objects) and + * share the same references to their data sources ({@link ByteArrayKeyValueStore} objects) and * each {@link Node} will retain the same references as the original node's {@link * org.aion.rlp.Value} objects. * diff --git a/modMcf/src/org/aion/mcf/trie/Trie.java b/modMcf/src/org/aion/mcf/trie/Trie.java index 09942b5262..1c6714cca3 100644 --- a/modMcf/src/org/aion/mcf/trie/Trie.java +++ b/modMcf/src/org/aion/mcf/trie/Trie.java @@ -2,8 +2,8 @@ import java.util.Map; import java.util.Set; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.types.ByteArrayWrapper; /** * Trie interface for the main data structure in Ethereum which is used to store both the account @@ -99,7 +99,7 @@ public interface Trie { */ Map getReferencedTrieNodes(byte[] value, int limit); - long saveFullStateToDatabase(byte[] stateRoot, IByteArrayKeyValueDatabase db); + long saveFullStateToDatabase(byte[] stateRoot, ByteArrayKeyValueDatabase db); - long saveDiffStateToDatabase(byte[] stateRoot, IByteArrayKeyValueDatabase db); + long saveDiffStateToDatabase(byte[] stateRoot, ByteArrayKeyValueDatabase db); } diff --git a/modMcf/src/org/aion/mcf/trie/TrieImpl.java b/modMcf/src/org/aion/mcf/trie/TrieImpl.java index 94a5458e76..39af497aad 100644 --- a/modMcf/src/org/aion/mcf/trie/TrieImpl.java +++ b/modMcf/src/org/aion/mcf/trie/TrieImpl.java @@ -1,13 +1,13 @@ package org.aion.mcf.trie; import static java.util.Arrays.copyOfRange; -import static org.aion.base.util.ByteArrayWrapper.wrap; import static org.aion.crypto.HashUtil.EMPTY_TRIE_HASH; import static org.aion.rlp.CompactEncoder.binToNibbles; import static org.aion.rlp.CompactEncoder.hasTerminator; import static org.aion.rlp.CompactEncoder.packNibbles; import static org.aion.rlp.CompactEncoder.unpackToNibbles; import static org.aion.rlp.RLP.calcElementPrefixSize; +import static org.aion.types.ByteArrayWrapper.wrap; import static org.aion.util.bytes.ByteUtil.matchingNibbleLength; import static org.spongycastle.util.Arrays.concatenate; @@ -22,10 +22,9 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.aion.base.db.IByteArrayKeyValueDatabase; -import org.aion.base.db.IByteArrayKeyValueStore; -import org.aion.base.util.ByteArrayWrapper; import org.aion.crypto.HashUtil; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; +import org.aion.interfaces.db.ByteArrayKeyValueStore; import org.aion.mcf.trie.scan.CollectFullSetOfNodes; import org.aion.mcf.trie.scan.CollectMappings; import org.aion.mcf.trie.scan.CountNodes; @@ -36,6 +35,7 @@ import org.aion.rlp.RLPItem; import org.aion.rlp.RLPList; import org.aion.rlp.Value; +import org.aion.types.ByteArrayWrapper; import org.aion.util.conversions.Hex; /** @@ -75,11 +75,11 @@ public class TrieImpl implements Trie { private boolean pruningEnabled; - public TrieImpl(IByteArrayKeyValueStore db) { + public TrieImpl(ByteArrayKeyValueStore db) { this(db, ""); } - public TrieImpl(IByteArrayKeyValueStore db, Object root) { + public TrieImpl(ByteArrayKeyValueStore db, Object root) { this(new Cache(db), root); } @@ -179,9 +179,10 @@ public void update(byte[] key, byte[] value) { if (value.length == 0) { throw new IllegalArgumentException("The value should not be empty."); } - synchronized (cache) { - byte[] k = binToNibbles(key); + byte[] k = binToNibbles(key); + + synchronized (cache) { if (isEmptyNode(root)) { cache.markRemoved(getRootHash()); } @@ -466,14 +467,14 @@ private Object putToCache(Object node) { return this.cache.put(node); } - private boolean isEmptyNode(Object node) { + private static boolean isEmptyNode(Object node) { Value n = new Value(node); return (node == null || (n.isString() && (n.asString().isEmpty() || n.get(0).isNull())) || n.length() == 0); } - private Object[] copyNode(Value currentNode) { + private static Object[] copyNode(Value currentNode) { Object[] itemList = emptyStringSlice(LIST_SIZE); for (int i = 0; i < LIST_SIZE; i++) { Object cpy = currentNode.get(i).asObj(); @@ -643,7 +644,7 @@ private void scanTreeLoop(byte[] hash, ScanAction scanAction) { * @param db database containing keys that need not be explored */ private void scanTreeDiffLoop( - byte[] hash, ScanAction scanAction, IByteArrayKeyValueDatabase db) { + byte[] hash, ScanAction scanAction, ByteArrayKeyValueDatabase db) { ArrayList hashes = new ArrayList<>(); hashes.add(hash); @@ -991,13 +992,13 @@ private void appendHashes(Value node, ArrayList hashes) { } @Override - public long saveFullStateToDatabase(byte[] stateRoot, IByteArrayKeyValueDatabase db) { + public long saveFullStateToDatabase(byte[] stateRoot, ByteArrayKeyValueDatabase db) { ExtractToDatabase traceAction = new ExtractToDatabase(db); traceTrie(stateRoot, traceAction); return traceAction.count; } - private void traceDiffTrie(byte[] stateRoot, ScanAction action, IByteArrayKeyValueDatabase db) { + private void traceDiffTrie(byte[] stateRoot, ScanAction action, ByteArrayKeyValueDatabase db) { synchronized (cache) { Value value = new Value(stateRoot); @@ -1010,7 +1011,7 @@ private void traceDiffTrie(byte[] stateRoot, ScanAction action, IByteArrayKeyVal } @Override - public long saveDiffStateToDatabase(byte[] stateRoot, IByteArrayKeyValueDatabase db) { + public long saveDiffStateToDatabase(byte[] stateRoot, ByteArrayKeyValueDatabase db) { ExtractToDatabase traceAction = new ExtractToDatabase(db); traceDiffTrie(stateRoot, traceAction, db); return traceAction.count; diff --git a/modMcf/src/org/aion/mcf/trie/scan/CollectFullSetOfNodes.java b/modMcf/src/org/aion/mcf/trie/scan/CollectFullSetOfNodes.java index bb30c7d11d..7722899699 100644 --- a/modMcf/src/org/aion/mcf/trie/scan/CollectFullSetOfNodes.java +++ b/modMcf/src/org/aion/mcf/trie/scan/CollectFullSetOfNodes.java @@ -2,8 +2,8 @@ import java.util.HashSet; import java.util.Set; -import org.aion.base.util.ByteArrayWrapper; import org.aion.rlp.Value; +import org.aion.types.ByteArrayWrapper; public class CollectFullSetOfNodes implements ScanAction { Set nodes = new HashSet<>(); diff --git a/modMcf/src/org/aion/mcf/trie/scan/CollectMappings.java b/modMcf/src/org/aion/mcf/trie/scan/CollectMappings.java index a7f8d792b0..09b05f3469 100644 --- a/modMcf/src/org/aion/mcf/trie/scan/CollectMappings.java +++ b/modMcf/src/org/aion/mcf/trie/scan/CollectMappings.java @@ -2,8 +2,8 @@ import java.util.HashMap; import java.util.Map; -import org.aion.base.util.ByteArrayWrapper; import org.aion.rlp.Value; +import org.aion.types.ByteArrayWrapper; /** @author Alexandra Roatis */ public class CollectMappings implements ScanAction { diff --git a/modMcf/src/org/aion/mcf/trie/scan/ExtractToDatabase.java b/modMcf/src/org/aion/mcf/trie/scan/ExtractToDatabase.java index e4e023cdaf..b7dcf1243a 100644 --- a/modMcf/src/org/aion/mcf/trie/scan/ExtractToDatabase.java +++ b/modMcf/src/org/aion/mcf/trie/scan/ExtractToDatabase.java @@ -1,6 +1,6 @@ package org.aion.mcf.trie.scan; -import org.aion.base.db.IByteArrayKeyValueDatabase; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; import org.aion.rlp.Value; /** @author Alexandra Roatis */ @@ -8,10 +8,10 @@ public class ExtractToDatabase implements ScanAction { // only the keys are relevant so the value will be this constant byte[] dummy_value = new byte[] {0}; - IByteArrayKeyValueDatabase db; + ByteArrayKeyValueDatabase db; public long count = 0; - public ExtractToDatabase(IByteArrayKeyValueDatabase _db) { + public ExtractToDatabase(ByteArrayKeyValueDatabase _db) { this.db = _db; } diff --git a/modMcf/src/org/aion/mcf/tx/AbstractTxTask.java b/modMcf/src/org/aion/mcf/tx/AbstractTxTask.java index 09884276e9..852834b4fc 100644 --- a/modMcf/src/org/aion/mcf/tx/AbstractTxTask.java +++ b/modMcf/src/org/aion/mcf/tx/AbstractTxTask.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.Callable; -import org.aion.base.type.ITransaction; +import org.aion.interfaces.tx.Transaction; import org.aion.p2p.INode; import org.aion.p2p.IP2pMgr; import org.aion.p2p.Msg; @@ -13,10 +13,10 @@ * @author jin * @modified jay@Sep.2017 */ -// public abstract class AbstractTxTask implements Callable> // { -public abstract class AbstractTxTask +public abstract class AbstractTxTask implements Callable> { protected final List tx; diff --git a/modMcf/src/org/aion/mcf/tx/TransactionTypes.java b/modMcf/src/org/aion/mcf/tx/TransactionTypes.java new file mode 100644 index 0000000000..25a9253be0 --- /dev/null +++ b/modMcf/src/org/aion/mcf/tx/TransactionTypes.java @@ -0,0 +1,19 @@ +package org.aion.mcf.tx; + +import java.util.Set; + +/** Transaction type values supported by the kernel implementation. */ +public class TransactionTypes { + public static final byte DEFAULT = 0x00; + public static final byte FVM_CREATE_CODE = 0x01; + public static final byte AVM_CREATE_CODE = 0x0f; + + /** Set of transaction types allowed by any of the Virtual Machine implementations. */ + public static final Set ALL = Set.of(DEFAULT, FVM_CREATE_CODE, AVM_CREATE_CODE); + + /** Set of transaction types allowed by the Fast Virtual Machine implementation. */ + public static final Set FVM = Set.of(DEFAULT, FVM_CREATE_CODE); + + /** Set of transaction types allowed by the Aion Virtual Machine implementation. */ + public static final Set AVM = Set.of(DEFAULT, AVM_CREATE_CODE); +} diff --git a/modMcf/src/org/aion/mcf/types/AbstractBlock.java b/modMcf/src/org/aion/mcf/types/AbstractBlock.java index 4e9290e75c..1cb882b729 100644 --- a/modMcf/src/org/aion/mcf/types/AbstractBlock.java +++ b/modMcf/src/org/aion/mcf/types/AbstractBlock.java @@ -4,20 +4,20 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -import org.aion.base.type.IBlock; -import org.aion.base.type.IBlockHeader; +import org.aion.interfaces.block.Block; +import org.aion.interfaces.block.BlockHeader; import org.aion.rlp.RLP; /** Abstract Block class. */ -public abstract class AbstractBlock - implements IBlock { +public abstract class AbstractBlock + implements Block { protected BH header; protected List transactionsList = new CopyOnWriteArrayList<>(); @Override - public boolean isEqual(IBlock block) { + public boolean isEqual(Block block) { return Arrays.equals(this.getHash(), block.getHash()); } @@ -31,7 +31,7 @@ public boolean isEqual(IBlock block) { * @param block - possible a son of this * @return - true if this block is parent of param block */ - public boolean isParentOf(IBlock block) { + public boolean isParentOf(Block block) { return Arrays.equals(this.getHash(), block.getParentHash()); } diff --git a/modMcf/src/org/aion/mcf/types/AbstractBlockHeader.java b/modMcf/src/org/aion/mcf/types/AbstractBlockHeader.java index 42741ba569..c00fc5ddcb 100644 --- a/modMcf/src/org/aion/mcf/types/AbstractBlockHeader.java +++ b/modMcf/src/org/aion/mcf/types/AbstractBlockHeader.java @@ -1,9 +1,8 @@ package org.aion.mcf.types; import java.math.BigInteger; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.log.AionLoggerFactory; -import org.aion.vm.api.interfaces.Address; import org.spongycastle.util.BigIntegers; /** Abstract BlockHeader. */ @@ -22,7 +21,7 @@ public abstract class AbstractBlockHeader { * The 256-bit address to which all fees collected from the successful * mining of this block be transferred; formally */ - protected AionAddress coinbase; + protected Address coinbase; /* * The SHA3 256-bit hash of the root node of the state trie, after all * transactions are executed and finalisations applied @@ -107,7 +106,7 @@ public Address getCoinbase() { } public void setCoinbase(Address coinbase) { - this.coinbase = (AionAddress) coinbase; + this.coinbase = (Address) coinbase; } public byte[] getStateRoot() { diff --git a/modMcf/src/org/aion/mcf/types/AbstractBlockHeaderWrapper.java b/modMcf/src/org/aion/mcf/types/AbstractBlockHeaderWrapper.java index bc8c1432dc..3e0ee6ed4c 100644 --- a/modMcf/src/org/aion/mcf/types/AbstractBlockHeaderWrapper.java +++ b/modMcf/src/org/aion/mcf/types/AbstractBlockHeaderWrapper.java @@ -1,12 +1,12 @@ package org.aion.mcf.types; import java.util.Arrays; -import org.aion.base.type.IBlockHeader; +import org.aion.interfaces.block.BlockHeader; import org.aion.rlp.RLP; import org.aion.util.conversions.Hex; /** AbstractBlockHeaderWrapper */ -public abstract class AbstractBlockHeaderWrapper { +public abstract class AbstractBlockHeaderWrapper { protected BH header; diff --git a/modMcf/src/org/aion/mcf/types/AbstractBlockSummary.java b/modMcf/src/org/aion/mcf/types/AbstractBlockSummary.java index dab6452575..13c7f38d85 100644 --- a/modMcf/src/org/aion/mcf/types/AbstractBlockSummary.java +++ b/modMcf/src/org/aion/mcf/types/AbstractBlockSummary.java @@ -5,25 +5,24 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.aion.base.type.AionAddress; -import org.aion.base.type.IBlock; -import org.aion.base.type.ITransaction; -import org.aion.base.type.ITxExecSummary; -import org.aion.base.util.Functional; +import org.aion.interfaces.block.Block; +import org.aion.interfaces.functional.Functional; +import org.aion.interfaces.tx.Transaction; +import org.aion.interfaces.tx.TxExecSummary; +import org.aion.types.Address; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.aion.rlp.RLP; import org.aion.rlp.RLPElement; import org.aion.rlp.RLPList; -import org.aion.vm.api.interfaces.Address; import org.slf4j.Logger; /** AbstractBlockSummary */ public class AbstractBlockSummary< - BLK extends IBlock, - TX extends ITransaction, + BLK extends Block, + TX extends Transaction, TXR extends AbstractTxReceipt, - TXES extends ITxExecSummary> { + TXES extends TxExecSummary> { protected BLK block; protected Map rewards; @@ -68,7 +67,7 @@ protected static Map decodeRewards(RLPList rewards) { new Functional.Function() { @Override public Address apply(byte[] bytes) { - return AionAddress.wrap(bytes); + return Address.wrap(bytes); } }, new Functional.Function() { diff --git a/modMcf/src/org/aion/mcf/types/AbstractBlockWrapper.java b/modMcf/src/org/aion/mcf/types/AbstractBlockWrapper.java index 91e3d2394b..9fc0e7f7bd 100644 --- a/modMcf/src/org/aion/mcf/types/AbstractBlockWrapper.java +++ b/modMcf/src/org/aion/mcf/types/AbstractBlockWrapper.java @@ -1,14 +1,14 @@ package org.aion.mcf.types; -import static org.aion.base.util.TimeUtils.secondsToMillis; +import static org.aion.util.time.TimeUtils.secondsToMillis; import java.math.BigInteger; import java.util.Arrays; -import org.aion.base.type.IBlock; +import org.aion.interfaces.block.Block; import org.aion.rlp.RLP; /** AbstractBlockWrapper */ -public abstract class AbstractBlockWrapper> { +public abstract class AbstractBlockWrapper> { protected static final long SOLID_BLOCK_DURATION_THRESHOLD = secondsToMillis(60); diff --git a/modMcf/src/org/aion/mcf/types/AbstractTransaction.java b/modMcf/src/org/aion/mcf/types/AbstractTransaction.java index 1653cd0006..cc160ff4ac 100644 --- a/modMcf/src/org/aion/mcf/types/AbstractTransaction.java +++ b/modMcf/src/org/aion/mcf/types/AbstractTransaction.java @@ -1,15 +1,15 @@ package org.aion.mcf.types; import java.math.BigInteger; -import org.aion.base.type.ITransaction; -import org.aion.base.vm.VirtualMachineSpecs; import org.aion.crypto.ISignature; +import org.aion.interfaces.tx.Transaction; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; -import org.aion.vm.api.interfaces.Address; +import org.aion.mcf.tx.TransactionTypes; +import org.aion.types.Address; import org.slf4j.Logger; -public abstract class AbstractTransaction implements ITransaction { +public abstract class AbstractTransaction implements Transaction { private static final int nrgDigits = 64; @@ -55,7 +55,7 @@ public AbstractTransaction(byte[] nonce, Address receiveAddress, byte[] value, b this.value = value; this.data = data; // default type 0x01; reserve date for multi-type transaction - this.type = VirtualMachineSpecs.FVM_DEFAULT_TX_TYPE; + this.type = TransactionTypes.DEFAULT; } public AbstractTransaction( diff --git a/modMcf/src/org/aion/mcf/types/AbstractTxReceipt.java b/modMcf/src/org/aion/mcf/types/AbstractTxReceipt.java index bd7eccd8c0..b3a7f5668d 100644 --- a/modMcf/src/org/aion/mcf/types/AbstractTxReceipt.java +++ b/modMcf/src/org/aion/mcf/types/AbstractTxReceipt.java @@ -4,15 +4,14 @@ import java.util.ArrayList; import java.util.List; -import org.aion.base.type.ITransaction; -import org.aion.base.type.ITxReceipt; -import org.aion.base.util.Bytesable; +import org.aion.interfaces.Bytesable; +import org.aion.interfaces.tx.Transaction; +import org.aion.interfaces.tx.TxReceipt; import org.aion.mcf.vm.types.Bloom; -import org.aion.mcf.vm.types.Log; import org.aion.vm.api.interfaces.IExecutionLog; -public abstract class AbstractTxReceipt - implements Bytesable, ITxReceipt { +public abstract class AbstractTxReceipt + implements Bytesable, TxReceipt { protected TX transaction; diff --git a/modMcf/src/org/aion/mcf/types/BlockIdentifier.java b/modMcf/src/org/aion/mcf/types/BlockIdentifierImpl.java similarity index 74% rename from modMcf/src/org/aion/mcf/types/BlockIdentifier.java rename to modMcf/src/org/aion/mcf/types/BlockIdentifierImpl.java index 6e3945a79a..0366a7918c 100644 --- a/modMcf/src/org/aion/mcf/types/BlockIdentifier.java +++ b/modMcf/src/org/aion/mcf/types/BlockIdentifierImpl.java @@ -3,13 +3,14 @@ import static org.aion.util.bytes.ByteUtil.byteArrayToLong; import java.math.BigInteger; -import org.aion.base.type.IBlockIdentifier; + +import org.aion.interfaces.block.BlockIdentifier; import org.aion.rlp.RLP; import org.aion.rlp.RLPList; import org.aion.util.conversions.Hex; /** Block identifier holds block hash and number
    */ -public class BlockIdentifier implements IBlockIdentifier { +public class BlockIdentifierImpl implements BlockIdentifier { /** Block hash */ private byte[] hash; @@ -17,12 +18,12 @@ public class BlockIdentifier implements IBlockIdentifier { /** Block number */ private long number; - public BlockIdentifier(RLPList rlp) { + public BlockIdentifierImpl(RLPList rlp) { this.hash = rlp.get(0).getRLPData(); this.number = byteArrayToLong(rlp.get(1).getRLPData()); } - public BlockIdentifier(byte[] hash, long number) { + public BlockIdentifierImpl(byte[] hash, long number) { this.hash = hash; this.number = number; } @@ -44,6 +45,6 @@ public byte[] getEncoded() { @Override public String toString() { - return "BlockIdentifier {" + "hash=" + Hex.toHexString(hash) + ", number=" + number + '}'; + return "BlockIdentifierImpl {" + "hash=" + Hex.toHexString(hash) + ", number=" + number + '}'; } } diff --git a/modMcf/src/org/aion/mcf/valid/BlockNumberRule.java b/modMcf/src/org/aion/mcf/valid/BlockNumberRule.java index 1ec8d38250..8f5aee230e 100644 --- a/modMcf/src/org/aion/mcf/valid/BlockNumberRule.java +++ b/modMcf/src/org/aion/mcf/valid/BlockNumberRule.java @@ -1,9 +1,9 @@ package org.aion.mcf.valid; import java.util.List; -import org.aion.base.type.IBlockHeader; +import org.aion.interfaces.block.BlockHeader; -public class BlockNumberRule extends DependentBlockHeaderRule { +public class BlockNumberRule extends DependentBlockHeaderRule { @Override public boolean validate(BH header, BH parent, List errors) { diff --git a/modMcf/src/org/aion/mcf/valid/DependentBlockHeaderRule.java b/modMcf/src/org/aion/mcf/valid/DependentBlockHeaderRule.java index 72d1a72c11..31446d0285 100644 --- a/modMcf/src/org/aion/mcf/valid/DependentBlockHeaderRule.java +++ b/modMcf/src/org/aion/mcf/valid/DependentBlockHeaderRule.java @@ -1,12 +1,12 @@ package org.aion.mcf.valid; import java.util.List; -import org.aion.base.type.IBlockHeader; +import org.aion.interfaces.block.BlockHeader; import org.aion.mcf.blockchain.valid.AbstractValidRule; import org.aion.mcf.blockchain.valid.IBlockHeaderValidRule; /** A class of rules that requires memory of the previous block */ -public abstract class DependentBlockHeaderRule extends AbstractValidRule +public abstract class DependentBlockHeaderRule extends AbstractValidRule implements IBlockHeaderValidRule { /** diff --git a/modMcf/src/org/aion/mcf/valid/GrandParentBlockHeaderValidator.java b/modMcf/src/org/aion/mcf/valid/GrandParentBlockHeaderValidator.java index 7989ce08d7..46890b53a8 100644 --- a/modMcf/src/org/aion/mcf/valid/GrandParentBlockHeaderValidator.java +++ b/modMcf/src/org/aion/mcf/valid/GrandParentBlockHeaderValidator.java @@ -2,11 +2,11 @@ import java.util.LinkedList; import java.util.List; -import org.aion.base.type.IBlockHeader; +import org.aion.interfaces.block.BlockHeader; import org.aion.mcf.blockchain.valid.IValidRule; import org.slf4j.Logger; -public class GrandParentBlockHeaderValidator +public class GrandParentBlockHeaderValidator extends AbstractBlockHeaderValidator { private List> rules; diff --git a/modMcf/src/org/aion/mcf/valid/GrandParentDependantBlockHeaderRule.java b/modMcf/src/org/aion/mcf/valid/GrandParentDependantBlockHeaderRule.java index 217bd038cd..12eae92efd 100644 --- a/modMcf/src/org/aion/mcf/valid/GrandParentDependantBlockHeaderRule.java +++ b/modMcf/src/org/aion/mcf/valid/GrandParentDependantBlockHeaderRule.java @@ -1,10 +1,10 @@ package org.aion.mcf.valid; import java.util.List; -import org.aion.base.type.IBlockHeader; +import org.aion.interfaces.block.BlockHeader; import org.aion.mcf.blockchain.valid.AbstractValidRule; -public abstract class GrandParentDependantBlockHeaderRule +public abstract class GrandParentDependantBlockHeaderRule extends AbstractValidRule { /** diff --git a/modMcf/src/org/aion/mcf/valid/ParentBlockHeaderValidator.java b/modMcf/src/org/aion/mcf/valid/ParentBlockHeaderValidator.java index 9a6bb4a3a7..8d895a515d 100644 --- a/modMcf/src/org/aion/mcf/valid/ParentBlockHeaderValidator.java +++ b/modMcf/src/org/aion/mcf/valid/ParentBlockHeaderValidator.java @@ -2,13 +2,13 @@ import java.util.LinkedList; import java.util.List; -import org.aion.base.type.IBlockHeader; +import org.aion.interfaces.block.BlockHeader; import org.aion.mcf.blockchain.valid.IBlockHeaderValidRule; import org.aion.mcf.blockchain.valid.IValidRule; import org.slf4j.Logger; /** validation rules depending on parent's block header */ -public class ParentBlockHeaderValidator +public class ParentBlockHeaderValidator extends AbstractBlockHeaderValidator { private List> rules; diff --git a/modMcf/src/org/aion/mcf/valid/TimeStampRule.java b/modMcf/src/org/aion/mcf/valid/TimeStampRule.java index f70c685fbe..8fb2ef6692 100644 --- a/modMcf/src/org/aion/mcf/valid/TimeStampRule.java +++ b/modMcf/src/org/aion/mcf/valid/TimeStampRule.java @@ -1,10 +1,10 @@ package org.aion.mcf.valid; import java.util.List; -import org.aion.base.type.IBlockHeader; +import org.aion.interfaces.block.BlockHeader; /** Validates whether the timestamp of the current block is > the timestamp of the parent block */ -public class TimeStampRule extends DependentBlockHeaderRule { +public class TimeStampRule extends DependentBlockHeaderRule { @Override public boolean validate(BH header, BH dependency, List errors) { diff --git a/modMcf/src/org/aion/mcf/valid/TransactionTypeRule.java b/modMcf/src/org/aion/mcf/valid/TransactionTypeRule.java index f467189f2e..8ae3fb9c5e 100644 --- a/modMcf/src/org/aion/mcf/valid/TransactionTypeRule.java +++ b/modMcf/src/org/aion/mcf/valid/TransactionTypeRule.java @@ -1,6 +1,12 @@ package org.aion.mcf.valid; -import org.aion.base.vm.VirtualMachineSpecs; +import static org.aion.mcf.tx.TransactionTypes.ALL; +import static org.aion.mcf.tx.TransactionTypes.AVM; +import static org.aion.mcf.tx.TransactionTypes.AVM_CREATE_CODE; +import static org.aion.mcf.tx.TransactionTypes.FVM; +import static org.aion.mcf.tx.TransactionTypes.FVM_CREATE_CODE; + +import com.google.common.annotations.VisibleForTesting; /** * Rules for validating transactions based on allowed types. @@ -9,12 +15,61 @@ */ public class TransactionTypeRule { - public static boolean isValidFVMTransactionType(byte type) { - return type == VirtualMachineSpecs.FVM_DEFAULT_TX_TYPE - || type == VirtualMachineSpecs.FVM_ALLOWED_TX_TYPE; + // allowing only balance transfers on AVM when this flag is equal to false. + private static boolean DEPLOY_AVM_CONTRACT_ALLOWED = false; + + /** + * Compares the given transaction type with all the transaction types allowed. + * + * @param type the type of a transaction applicable on any of the allowed VMs + * @return {@code true} is this is a valid transaction type, {@code false} otherwise + */ + public static boolean isValidTransactionType(byte type) { + return ALL.contains(type); + } + + /** + * Compares the given transaction type with all the transaction types allowed by the FastVM. + * + * @param type the type of a transaction applicable on the FastVM + * @return {@code true} is this is an FastVM transaction, {@code false} otherwise + */ + public static boolean isValidFVMTransaction(byte type) { + return FVM.contains(type); + } + + /** + * Checks if the given transaction is a valid contract deployment on the FastVM. + * + * @param type the type of a contract creation transaction + * @return {@code true} is this is a valid FastVM contract deployment, {@code false} otherwise + */ + public static boolean isValidFVMContractDeployment(byte type) { + return type == FVM_CREATE_CODE || true; // anything is valid here before the fork + } + + /** + * Compares the given transaction type with all the transaction types allowed by the AVM. + * + * @param type the type of a transaction applicable on the AVM + * @return {@code true} is this is an AVM transaction, {@code false} otherwise + */ + public static boolean isValidAVMTransaction(byte type) { + return AVM.contains(type); + } + + /** + * Checks if the given transaction is a valid contract deployment on the AVM. + * + * @param type the type of a contract creation transaction + * @return {@code true} is this is a valid AVM contract deployment, {@code false} otherwise + */ + public static boolean isValidAVMContractDeployment(byte type) { + return type == AVM_CREATE_CODE && DEPLOY_AVM_CONTRACT_ALLOWED; } - public static boolean isValidAVMTransactionType(byte type) { - return type == VirtualMachineSpecs.AVM_CREATE_CODE; + @VisibleForTesting + public static void allowAVMContractDeployment() { + DEPLOY_AVM_CONTRACT_ALLOWED = true; } } diff --git a/modMcf/src/org/aion/mcf/vm/types/Bloom.java b/modMcf/src/org/aion/mcf/vm/types/Bloom.java index 92b906f5cf..6ff8836b48 100644 --- a/modMcf/src/org/aion/mcf/vm/types/Bloom.java +++ b/modMcf/src/org/aion/mcf/vm/types/Bloom.java @@ -8,7 +8,7 @@ /** Utility class for creating/operating bloom. */ public class Bloom implements IBloomFilter { - public byte[] data = new byte[256]; + public byte[] data = new byte[IBloomFilter.SIZE]; public Bloom() {} @@ -24,7 +24,7 @@ public static Bloom create(byte[] toBloom) { int mov3 = (((toBloom[4] & 0xff) & 7) << 8) + ((toBloom[5]) & 0xff); // # bits: 8 * 256 = 2048 - byte[] data = new byte[256]; + byte[] data = new byte[IBloomFilter.SIZE]; Bloom bloom = new Bloom(data); ByteUtil.setBit(data, mov1, 1); diff --git a/modMcf/src/org/aion/mcf/vm/types/DataWord.java b/modMcf/src/org/aion/mcf/vm/types/DataWordImpl.java similarity index 83% rename from modMcf/src/org/aion/mcf/vm/types/DataWord.java rename to modMcf/src/org/aion/mcf/vm/types/DataWordImpl.java index 91422654c2..9ca10d8b9a 100644 --- a/modMcf/src/org/aion/mcf/vm/types/DataWord.java +++ b/modMcf/src/org/aion/mcf/vm/types/DataWordImpl.java @@ -3,44 +3,44 @@ import java.math.BigInteger; import java.nio.ByteBuffer; import java.util.Arrays; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.vm.IDataWord; +import org.aion.interfaces.vm.DataWord; +import org.aion.types.ByteArrayWrapper; import org.aion.util.bytes.ByteUtil; import org.aion.util.conversions.Hex; /** * Data word is the basic unit data used by virtual machine. The size of a data word is 128 bits. */ -public class DataWord implements Comparable, IDataWord { +public class DataWordImpl implements Comparable, DataWord { public static final BigInteger MAX_VALUE = BigInteger.valueOf(2).pow(128).subtract(BigInteger.ONE); - public static final DataWord ZERO = new DataWord(0); - public static final DataWord ONE = new DataWord(1); + public static final DataWordImpl ZERO = new DataWordImpl(0); + public static final DataWordImpl ONE = new DataWordImpl(1); public static final int BYTES = 16; private byte[] data; - public DataWord() { + public DataWordImpl() { data = new byte[BYTES]; } - public DataWord(int num) { + public DataWordImpl(int num) { ByteBuffer bb = ByteBuffer.allocate(BYTES); bb.position(12); bb.putInt(num); data = bb.array(); } - public DataWord(long num) { + public DataWordImpl(long num) { ByteBuffer bb = ByteBuffer.allocate(BYTES); bb.position(8); bb.putLong(num); data = bb.array(); } - public DataWord(byte[] data) { + public DataWordImpl(byte[] data) { if (data == null) { throw new NullPointerException("Input data"); } else if (data.length == BYTES) { @@ -53,8 +53,8 @@ public DataWord(byte[] data) { } } - public DataWord(BigInteger num) { - // NOTE: DataWord.value() produces a signed positive BigInteger. The byte array + public DataWordImpl(BigInteger num) { + // NOTE: DataWordImpl.value() produces a signed positive BigInteger. The byte array // representation of such a number must prepend a zero byte so that this can be decoded // correctly. This means that a 16-byte array with a non-zero starting bit will become 17 // bytes when BigInteger::toByteArray is called, and therefore we must remove any leading @@ -76,16 +76,16 @@ public DataWord(BigInteger num) { */ private static byte[] removeLargeBigIntegerLeadingZeroByte(BigInteger number) { byte[] bytes = number.toByteArray(); - return ((bytes.length == (DataWord.BYTES + 1)) && (bytes[0] == 0x0)) + return ((bytes.length == (DataWordImpl.BYTES + 1)) && (bytes[0] == 0x0)) ? Arrays.copyOfRange(bytes, 1, bytes.length) : bytes; } - public DataWord(String data) { + public DataWordImpl(String data) { this(Hex.decode(data)); } - public DataWord(ByteArrayWrapper wrapper) { + public DataWordImpl(ByteArrayWrapper wrapper) { this(wrapper.getData()); } @@ -140,7 +140,7 @@ public boolean isNegative() { public DataWord copy() { byte[] bs = new byte[BYTES]; System.arraycopy(data, 0, bs, 0, BYTES); - return new DataWord(bs); + return new DataWordImpl(bs); } @Override @@ -152,7 +152,7 @@ public boolean equals(Object o) { return false; } - DataWord dataWord = (DataWord) o; + DataWordImpl dataWord = (DataWordImpl) o; return Arrays.equals(data, dataWord.data); } @@ -164,7 +164,7 @@ public int hashCode() { @Override public int compareTo(DataWord o) { - return Arrays.compare(this.data, o.data); + return Arrays.compare(this.data, ((DataWordImpl)o).data); } @Override diff --git a/modMcf/src/org/aion/mcf/vm/types/DoubleDataWord.java b/modMcf/src/org/aion/mcf/vm/types/DoubleDataWord.java index 4a2faa639f..fc2de51648 100644 --- a/modMcf/src/org/aion/mcf/vm/types/DoubleDataWord.java +++ b/modMcf/src/org/aion/mcf/vm/types/DoubleDataWord.java @@ -3,17 +3,18 @@ import java.math.BigInteger; import java.nio.ByteBuffer; import java.util.Arrays; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.vm.IDataWord; + +import org.aion.interfaces.vm.DataWord; +import org.aion.types.ByteArrayWrapper; import org.aion.util.bytes.ByteUtil; import org.aion.util.conversions.Hex; /** - * DoubleDataWord is double the size of the basic unit data (DataWord) used by the VM. A + * DoubleDataWord is double the size of the basic unit data (DataWordImpl) used by the VM. A * DoubleDataWord is 256 bits. Its intended use is strictly within pre-compiled contracts, which * often have need of 32-byte storage keys. */ -public class DoubleDataWord implements Comparable, IDataWord { +public class DoubleDataWord implements Comparable, DataWord { public static final BigInteger MAX_VALUE = BigInteger.valueOf(2).pow(256).subtract(BigInteger.ONE); @@ -114,7 +115,7 @@ public boolean isNegative() { } @Override - public IDataWord copy() { + public DataWord copy() { byte[] bs = new byte[BYTES]; System.arraycopy(data, 0, bs, 0, BYTES); return new DoubleDataWord(bs); diff --git a/modMcf/src/org/aion/mcf/vm/types/KernelInterfaceForFastVM.java b/modMcf/src/org/aion/mcf/vm/types/KernelInterfaceForFastVM.java index b7c575ab6f..9312c25c21 100644 --- a/modMcf/src/org/aion/mcf/vm/types/KernelInterfaceForFastVM.java +++ b/modMcf/src/org/aion/mcf/vm/types/KernelInterfaceForFastVM.java @@ -1,21 +1,21 @@ package org.aion.mcf.vm.types; import java.math.BigInteger; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.vm.VirtualMachineSpecs; +import org.aion.interfaces.db.RepositoryCache; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; +import org.aion.mcf.valid.TransactionTypeRule; import org.aion.mcf.valid.TxNrgRule; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.vm.api.interfaces.KernelInterface; public class KernelInterfaceForFastVM implements KernelInterface { - private IRepositoryCache> repositoryCache; + private RepositoryCache> repositoryCache; private boolean allowNonceIncrement, isLocalCall; public KernelInterfaceForFastVM( - IRepositoryCache> repositoryCache, + RepositoryCache> repositoryCache, boolean allowNonceIncrement, boolean isLocalCall) { @@ -48,7 +48,7 @@ public void rollback() { this.repositoryCache.rollback(); } - public IRepositoryCache> getRepositoryCache() { + public RepositoryCache> getRepositoryCache() { return this.repositoryCache; } @@ -72,6 +72,17 @@ public byte[] getCode(Address address) { return this.repositoryCache.getCode(address); } + @Override + public void putObjectGraph(Address contract, byte[] graph) { + //Todo: implement it when avm is ready. + } + + @Override + public byte[] getObjectGraph(Address contract) { + //Todo: implement it when avm is ready. + return new byte[0]; + } + @Override public void putStorage(Address address, byte[] key, byte[] value) { ByteArrayWrapper storageKey = alignDataToWordSize(key); @@ -100,7 +111,7 @@ public byte[] getStorage(Address address, byte[] key) { throw new IllegalStateException( "A zero or empty value was retrieved from storage. Storing zeros is not allowed by the FVM. An incorrect put was previously performed instead of an explicit call to the delete method."); } - return (value == null) ? DataWord.ZERO.getData() : alignValueToWordSizeForGet(value); + return (value == null) ? DataWordImpl.ZERO.getData() : alignValueToWordSizeForGet(value); } @Override @@ -180,7 +191,7 @@ public boolean isValidEnergyLimitForNonCreate(long energyLimit) { @Override public boolean destinationAddressIsSafeForThisVM(Address address) { - return address.toBytes()[0] != VirtualMachineSpecs.AVM_CREATE_CODE; + return TransactionTypeRule.isValidFVMContractDeployment(repositoryCache.getVMUsed(address)); } /** @@ -194,7 +205,7 @@ private ByteArrayWrapper alignValueToWordSizeForPut(byte[] value) { if (value.length == DoubleDataWord.BYTES) { return new ByteArrayWrapper(new DoubleDataWord(value).getData()); } else { - DataWord valueAsWord = new DataWord(value); + DataWordImpl valueAsWord = new DataWordImpl(value); return (valueAsWord.isZero()) ? valueAsWord.toWrapper() : new ByteArrayWrapper(valueAsWord.getNoLeadZeroesData()); @@ -211,10 +222,10 @@ private ByteArrayWrapper alignValueToWordSizeForPut(byte[] value) { private byte[] alignValueToWordSizeForGet(ByteArrayWrapper wrappedValue) { byte[] value = wrappedValue.getData(); - if (value.length > DataWord.BYTES) { + if (value.length > DataWordImpl.BYTES) { return new DoubleDataWord(value).getData(); } else { - return new DataWord(value).getData(); + return new DataWordImpl(value).getData(); } } @@ -229,7 +240,7 @@ private ByteArrayWrapper alignDataToWordSize(byte[] data) { if (data.length == DoubleDataWord.BYTES) { return new ByteArrayWrapper(new DoubleDataWord(data).getData()); } else { - return new ByteArrayWrapper(new DataWord(data).getData()); + return new ByteArrayWrapper(new DataWordImpl(data).getData()); } } } diff --git a/modMcf/src/org/aion/mcf/vm/types/Log.java b/modMcf/src/org/aion/mcf/vm/types/Log.java index a8e0e0e5e0..073edae7a9 100644 --- a/modMcf/src/org/aion/mcf/vm/types/Log.java +++ b/modMcf/src/org/aion/mcf/vm/types/Log.java @@ -2,7 +2,7 @@ import java.util.ArrayList; import java.util.List; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.crypto.HashUtil; import org.aion.rlp.RLP; import org.aion.rlp.RLPElement; @@ -11,7 +11,6 @@ import org.aion.util.conversions.Hex; import org.aion.vm.api.interfaces.IBloomFilter; import org.aion.vm.api.interfaces.IExecutionLog; -import org.aion.vm.api.interfaces.Address; /** A log is emitted by the LOGX vm instruction. It's composed of address, topics and data. */ public class Log implements IExecutionLog { @@ -28,7 +27,7 @@ public Log(byte[] rlp) { RLPList topics = (RLPList) logInfo.get(1); RLPItem data = (RLPItem) logInfo.get(2); - this.addr = address.getRLPData() != null ? AionAddress.wrap(address.getRLPData()) : null; + this.addr = address.getRLPData() != null ? Address.wrap(address.getRLPData()) : null; this.data = data.getRLPData() != null ? data.getRLPData() : new byte[] {}; for (RLPElement topic1 : topics) { diff --git a/modMcf/test/org/aion/mcf/account/AccountManagerTest.java b/modMcf/test/org/aion/mcf/account/AccountManagerTest.java index a8805ff199..9c8ea9b955 100644 --- a/modMcf/test/org/aion/mcf/account/AccountManagerTest.java +++ b/modMcf/test/org/aion/mcf/account/AccountManagerTest.java @@ -11,10 +11,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; -import org.aion.vm.api.interfaces.Address; + import org.junit.After; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -23,7 +23,7 @@ public class AccountManagerTest { private static AccountManager accountManager = AccountManager.inst(); private Address notRegistered = - AionAddress.wrap("a011111111111111111111111111111101010101010101010101010101010101"); + Address.wrap("a011111111111111111111111111111101010101010101010101010101010101"); private final int DEFAULT_TEST_TIMEOUT = 10; private static ECKey k1; @@ -77,11 +77,11 @@ public void testUnlockAccount() { // unlock 2 accounts assertTrue( accountManager.unlockAccount( - AionAddress.wrap(k1.getAddress()), p1, DEFAULT_TEST_TIMEOUT)); + Address.wrap(k1.getAddress()), p1, DEFAULT_TEST_TIMEOUT)); long timeOutTotal1 = Instant.now().getEpochSecond() + DEFAULT_TEST_TIMEOUT; assertTrue( accountManager.unlockAccount( - AionAddress.wrap(k2.getAddress()), p2, DEFAULT_TEST_TIMEOUT)); + Address.wrap(k2.getAddress()), p2, DEFAULT_TEST_TIMEOUT)); long timeOutTotal2 = Instant.now().getEpochSecond() + DEFAULT_TEST_TIMEOUT; // check account manager @@ -111,8 +111,8 @@ public void testUnlockAccountUpdateTimeout() { // update the timeout from 1s to 2s assertTrue( accountManager.unlockAccount( - AionAddress.wrap(k1.getAddress()), p1, DEFAULT_TEST_TIMEOUT)); - assertTrue(accountManager.unlockAccount(AionAddress.wrap(k1.getAddress()), p1, 20)); + Address.wrap(k1.getAddress()), p1, DEFAULT_TEST_TIMEOUT)); + assertTrue(accountManager.unlockAccount(Address.wrap(k1.getAddress()), p1, 20)); // check that the timeout is updated assertThat(accountManager.getAccounts().get(0).getTimeout()) @@ -133,7 +133,7 @@ public void testUnlockAccountWithNotRegisteredKey() { public void testUnlockAccountWithWrongPassword() { assertFalse( accountManager.unlockAccount( - AionAddress.wrap(k1.getAddress()), "not p1", DEFAULT_TEST_TIMEOUT)); + Address.wrap(k1.getAddress()), "not p1", DEFAULT_TEST_TIMEOUT)); // check that no account has been put into the manager assertThat(accountManager.getAccounts().size()).isEqualTo(0); @@ -144,7 +144,7 @@ public void testUnlockAccountTimeoutGreaterThanMax() { // unlock account with timeout greater than max assertTrue( accountManager.unlockAccount( - AionAddress.wrap(k1.getAddress()), p1, AccountManager.UNLOCK_MAX + 10)); + Address.wrap(k1.getAddress()), p1, AccountManager.UNLOCK_MAX + 10)); // check that the recoded timeout is no bigger than max assertThat(accountManager.getAccounts().get(0).getTimeout()) @@ -153,13 +153,13 @@ public void testUnlockAccountTimeoutGreaterThanMax() { // now update the timeout back to a small value so it can be cleared easily during @After assertTrue( accountManager.unlockAccount( - AionAddress.wrap(k1.getAddress()), p1, DEFAULT_TEST_TIMEOUT)); + Address.wrap(k1.getAddress()), p1, DEFAULT_TEST_TIMEOUT)); } @Test public void testUnlockAccountWithNegativeTimeout() { // try to unlock account with a negative integer as the timeout - assertTrue(accountManager.unlockAccount(AionAddress.wrap(k1.getAddress()), p1, -1)); + assertTrue(accountManager.unlockAccount(Address.wrap(k1.getAddress()), p1, -1)); int expectedTimeout = (int) Instant.now().getEpochSecond() + AccountManager.UNLOCK_DEFAULT; // check that the account is created and added to the manager @@ -176,10 +176,10 @@ public void testLockAccount() { // first unlock an account assertTrue( accountManager.unlockAccount( - AionAddress.wrap(k1.getAddress()), p1, DEFAULT_TEST_TIMEOUT)); + Address.wrap(k1.getAddress()), p1, DEFAULT_TEST_TIMEOUT)); // now try to lock it, the timeout will change - assertTrue(accountManager.lockAccount(AionAddress.wrap(k1.getAddress()), p1)); + assertTrue(accountManager.lockAccount(Address.wrap(k1.getAddress()), p1)); // check that the account is now locked List accountList = accountManager.getAccounts(); @@ -193,10 +193,10 @@ public void testLockAccountNotInManager() { // first unlock an account assertTrue( accountManager.unlockAccount( - AionAddress.wrap(k1.getAddress()), p1, DEFAULT_TEST_TIMEOUT)); + Address.wrap(k1.getAddress()), p1, DEFAULT_TEST_TIMEOUT)); // try to lock a different account - assertTrue(accountManager.lockAccount(AionAddress.wrap(k2.getAddress()), p2)); + assertTrue(accountManager.lockAccount(Address.wrap(k2.getAddress()), p2)); // check that there is still only the first account in the manager assertThat(accountManager.getAccounts().size()).isEqualTo(1); @@ -215,13 +215,13 @@ public void testLockAccountWithWrongPassword() { // first unlock an account assertTrue( accountManager.unlockAccount( - AionAddress.wrap(k1.getAddress()), p1, DEFAULT_TEST_TIMEOUT + 1)); + Address.wrap(k1.getAddress()), p1, DEFAULT_TEST_TIMEOUT + 1)); // check if its there assertThat(accountManager.getAccounts().size()).isEqualTo(1); // try to lock with wrong password - assertFalse(accountManager.lockAccount(AionAddress.wrap(k1.getAddress()), "not p1")); + assertFalse(accountManager.lockAccount(Address.wrap(k1.getAddress()), "not p1")); } @Test @@ -229,10 +229,10 @@ public void testGetKeyReturned() { // first unlock an account assertTrue( accountManager.unlockAccount( - AionAddress.wrap(k1.getAddress()), p1, DEFAULT_TEST_TIMEOUT)); + Address.wrap(k1.getAddress()), p1, DEFAULT_TEST_TIMEOUT)); // retrieve the key - ECKey ret = accountManager.getKey(AionAddress.wrap(k1.getAddress())); + ECKey ret = accountManager.getKey(Address.wrap(k1.getAddress())); // check equality assertArrayEquals(ret.getAddress(), k1.getAddress()); @@ -243,13 +243,13 @@ public void testGetKeyRemoved() { // first unlock an account assertTrue( accountManager.unlockAccount( - AionAddress.wrap(k1.getAddress()), p1, DEFAULT_TEST_TIMEOUT)); + Address.wrap(k1.getAddress()), p1, DEFAULT_TEST_TIMEOUT)); // lock the account - assertTrue(accountManager.lockAccount(AionAddress.wrap(k1.getAddress()), p1)); + assertTrue(accountManager.lockAccount(Address.wrap(k1.getAddress()), p1)); // retrieve key, but instead it is removed - assertNull(accountManager.getKey(AionAddress.wrap(k1.getAddress()))); + assertNull(accountManager.getKey(Address.wrap(k1.getAddress()))); // check that it was removed assertThat(accountManager.getAccounts().size()).isEqualTo(0); @@ -261,7 +261,7 @@ public void testGetKeyNotInMap() { assertThat(accountManager.getAccounts().size()).isEqualTo(0); // try to get a key not in the manager - assertNull(accountManager.getKey(AionAddress.wrap(k1.getAddress()))); + assertNull(accountManager.getKey(Address.wrap(k1.getAddress()))); } @Test @@ -269,11 +269,11 @@ public void testUnlockAndLockMultipleTimes() { // first an account assertTrue( accountManager.unlockAccount( - AionAddress.wrap(k1.getAddress()), p1, AccountManager.UNLOCK_DEFAULT)); + Address.wrap(k1.getAddress()), p1, AccountManager.UNLOCK_DEFAULT)); assertThat(accountManager.getAccounts().size()).isEqualTo(1); // lock k1 and check that timeout is changed - assertTrue(accountManager.lockAccount(AionAddress.wrap(k1.getAddress()), p1)); + assertTrue(accountManager.lockAccount(Address.wrap(k1.getAddress()), p1)); List accountsList; accountsList = accountManager.getAccounts(); assertThat(accountsList.size()).isEqualTo(1); @@ -282,7 +282,7 @@ public void testUnlockAndLockMultipleTimes() { // now unlock account with k1 again and check that timeout is changed assertTrue( accountManager.unlockAccount( - AionAddress.wrap(k1.getAddress()), p1, AccountManager.UNLOCK_DEFAULT)); + Address.wrap(k1.getAddress()), p1, AccountManager.UNLOCK_DEFAULT)); assertThat(accountManager.getAccounts().size()).isEqualTo(1); assertThat(accountsList.get(0).getTimeout()) .isEqualTo(Instant.now().getEpochSecond() + AccountManager.UNLOCK_DEFAULT); @@ -290,14 +290,14 @@ public void testUnlockAndLockMultipleTimes() { private static void cleanAccountManager() { // lock all the accounts, which modifies the timeout - accountManager.lockAccount(AionAddress.wrap(k1.getAddress()), p1); - accountManager.lockAccount(AionAddress.wrap(k2.getAddress()), p2); - accountManager.lockAccount(AionAddress.wrap(k3.getAddress()), p3); + accountManager.lockAccount(Address.wrap(k1.getAddress()), p1); + accountManager.lockAccount(Address.wrap(k2.getAddress()), p2); + accountManager.lockAccount(Address.wrap(k3.getAddress()), p3); // remove accounts - accountManager.getKey(AionAddress.wrap(k1.getAddress())); - accountManager.getKey(AionAddress.wrap(k2.getAddress())); - accountManager.getKey(AionAddress.wrap(k3.getAddress())); + accountManager.getKey(Address.wrap(k1.getAddress())); + accountManager.getKey(Address.wrap(k2.getAddress())); + accountManager.getKey(Address.wrap(k3.getAddress())); // check that manager is cleared assertThat(accountManager.getAccounts().size()).isEqualTo(0); diff --git a/modMcf/test/org/aion/mcf/account/KeystoreTest.java b/modMcf/test/org/aion/mcf/account/KeystoreTest.java index 2bc2b902a9..42e4a25435 100644 --- a/modMcf/test/org/aion/mcf/account/KeystoreTest.java +++ b/modMcf/test/org/aion/mcf/account/KeystoreTest.java @@ -13,12 +13,12 @@ import java.util.List; import java.util.Map; import java.util.Random; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.util.bytes.ByteUtil; -import org.aion.vm.api.interfaces.Address; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -130,11 +130,11 @@ public void testAccountExport() { assertEquals(addr.substring(2), ByteUtil.toHexString(key.getAddress())); Map arg = new HashMap<>(); - arg.put(AionAddress.wrap(addr), password); + arg.put(Address.wrap(addr), password); Map export = Keystore.exportAccount(arg); - assertTrue(export.containsKey(AionAddress.wrap(addr))); + assertTrue(export.containsKey(Address.wrap(addr))); assertTrue(export.containsValue(ByteArrayWrapper.wrap(key.getPrivKeyBytes()))); filesToRemove.add(addr); } @@ -149,7 +149,7 @@ public void testAccountBackup() { assertEquals(addr.substring(2), ByteUtil.toHexString(key.getAddress())); Map arg = new HashMap<>(); - arg.put(AionAddress.wrap(addr), password); + arg.put(Address.wrap(addr), password); Map export = Keystore.backupAccount(arg); @@ -158,7 +158,7 @@ public void testAccountBackup() { File f = Keystore.getAccountFile(addr.substring(2), password); assertNotNull(f); - assertTrue(export.containsKey(AionAddress.wrap(addr))); + assertTrue(export.containsKey(Address.wrap(addr))); try { assertTrue(export.containsValue(ByteArrayWrapper.wrap(Files.readAllBytes(f.toPath())))); } catch (IOException e) { diff --git a/modMcf/test/org/aion/mcf/ds/DataSourceArrayTest.java b/modMcf/test/org/aion/mcf/ds/DataSourceArrayTest.java index 02fe15fb76..8eb2fdb57c 100644 --- a/modMcf/test/org/aion/mcf/ds/DataSourceArrayTest.java +++ b/modMcf/test/org/aion/mcf/ds/DataSourceArrayTest.java @@ -9,9 +9,9 @@ import java.util.Random; import junitparams.JUnitParamsRunner; import junitparams.Parameters; -import org.aion.base.db.IByteArrayKeyValueDatabase; import org.aion.crypto.HashUtil; import org.aion.db.impl.mockdb.MockDB; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; import org.aion.zero.impl.db.AionBlockStore; import org.junit.After; import org.junit.Before; @@ -28,7 +28,7 @@ public class DataSourceArrayTest { private static List infoList; - private static IByteArrayKeyValueDatabase db; + private static ByteArrayKeyValueDatabase db; private static DataSourceArray> testIndex; private static final Random random = new Random(); diff --git a/modMcf/test/org/aion/mcf/trie/JournalPruneDataSourceTest.java b/modMcf/test/org/aion/mcf/trie/JournalPruneDataSourceTest.java index d4a59cc47f..77b2a76afa 100644 --- a/modMcf/test/org/aion/mcf/trie/JournalPruneDataSourceTest.java +++ b/modMcf/test/org/aion/mcf/trie/JournalPruneDataSourceTest.java @@ -14,8 +14,8 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import org.aion.base.db.IByteArrayKeyValueDatabase; import org.aion.db.impl.DatabaseFactory; +import org.aion.interfaces.db.ByteArrayKeyValueDatabase; import org.aion.log.AionLoggerFactory; import org.junit.After; import org.junit.Before; @@ -26,7 +26,7 @@ public class JournalPruneDataSourceTest { private static final String dbName = "TestDB"; - private static final IByteArrayKeyValueDatabase source_db = DatabaseFactory.connect(dbName); + private static final ByteArrayKeyValueDatabase source_db = DatabaseFactory.connect(dbName); private static JournalPruneDataSource db; private static final byte[] k1 = "key1".getBytes(); diff --git a/modMcf/test/org/aion/mcf/trie/TrieTest.java b/modMcf/test/org/aion/mcf/trie/TrieTest.java index 73ed8f0643..fa32928404 100644 --- a/modMcf/test/org/aion/mcf/trie/TrieTest.java +++ b/modMcf/test/org/aion/mcf/trie/TrieTest.java @@ -2,6 +2,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.aion.crypto.HashUtil.EMPTY_TRIE_HASH; +import static org.aion.util.bytes.ByteUtil.hexStringToBytes; import static org.aion.util.bytes.ByteUtil.intToBytes; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -18,7 +19,7 @@ import java.util.Set; import junitparams.JUnitParamsRunner; import junitparams.Parameters; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.HashUtil; import org.aion.db.impl.mockdb.MockDB; import org.aion.rlp.Value; @@ -969,11 +970,11 @@ public void testGetMissingNodes_wIncompleteTrie() { // removing two of the nodes from the trie Set expected = new HashSet<>(); expected.add( - new ByteArrayWrapper( - "59c2a26cebd0ed50053bba185a7d13e1ae58314e2c37d46c1f7b885fd93b687a")); + new ByteArrayWrapper(hexStringToBytes( + "59c2a26cebd0ed50053bba185a7d13e1ae58314e2c37d46c1f7b885fd93b687a"))); expected.add( - new ByteArrayWrapper( - "ddf1b495a3e98e1897a9b1257d4172d59fcbe0dba23b8b87812ca2a55919d9ab")); + new ByteArrayWrapper(hexStringToBytes( + "ddf1b495a3e98e1897a9b1257d4172d59fcbe0dba23b8b87812ca2a55919d9ab"))); for (ByteArrayWrapper key : expected) { mockDB.delete(key.getData()); diff --git a/modMcf/test/org/aion/valid/BlockNumberRuleTest.java b/modMcf/test/org/aion/valid/BlockNumberRuleTest.java index 9bdab60de7..f1179aa1f4 100644 --- a/modMcf/test/org/aion/valid/BlockNumberRuleTest.java +++ b/modMcf/test/org/aion/valid/BlockNumberRuleTest.java @@ -5,7 +5,7 @@ import java.util.LinkedList; import java.util.List; -import org.aion.base.type.IBlockHeader; +import org.aion.interfaces.block.BlockHeader; import org.aion.mcf.blockchain.valid.IValidRule; import org.aion.mcf.valid.BlockNumberRule; import org.junit.Before; @@ -20,8 +20,8 @@ */ public class BlockNumberRuleTest { - @Mock IBlockHeader mockChildBH; - @Mock IBlockHeader mockParentBH; + @Mock BlockHeader mockChildBH; + @Mock BlockHeader mockParentBH; @Before public void setUp() { diff --git a/modMcf/test/org/aion/valid/DifficultyRuleTest.java b/modMcf/test/org/aion/valid/DifficultyRuleTest.java index 1ffda0b84f..4558075f0a 100644 --- a/modMcf/test/org/aion/valid/DifficultyRuleTest.java +++ b/modMcf/test/org/aion/valid/DifficultyRuleTest.java @@ -8,15 +8,15 @@ import java.math.BigInteger; import java.util.LinkedList; import java.util.List; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.mcf.blockchain.IChainCfg; import org.aion.mcf.blockchain.valid.IValidRule.RuleError; import org.aion.mcf.core.IDifficultyCalculator; import org.aion.util.bytes.ByteUtil; +import org.aion.zero.impl.types.AionBlock; import org.aion.zero.impl.valid.AionDifficultyRule; import org.aion.zero.types.A0BlockHeader; import org.aion.zero.types.AionTransaction; -import org.aion.zero.types.IAionBlock; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; @@ -31,7 +31,7 @@ public class DifficultyRuleTest { private A0BlockHeader grandParentHeader; private A0BlockHeader parentHeader; private A0BlockHeader currentHeader; - @Mock IChainCfg mockChainCfg; + @Mock IChainCfg mockChainCfg; @Mock IDifficultyCalculator mockDiffCalculator; @Before @@ -43,7 +43,7 @@ public void setUp() { (byte) 0x01, 1, new byte[32], - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), new byte[256], ByteUtil.intToBytes(1), null, @@ -57,7 +57,7 @@ public void setUp() { (byte) 0x01, 2, new byte[32], - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), new byte[256], ByteUtil.intToBytes(1), null, @@ -80,7 +80,7 @@ public void testInvalidDifficultyLength() { (byte) 0x01, 3, new byte[32], - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), new byte[256], new byte[17], null, @@ -113,7 +113,7 @@ public void testDifficultyLength() { (byte) 0x01, 3, new byte[32], - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), new byte[256], ByteUtil.bigIntegerToBytes(BigInteger.ONE, 16), null, diff --git a/modMcf/test/org/aion/valid/TimeStampRuleTest.java b/modMcf/test/org/aion/valid/TimeStampRuleTest.java index c317f04a8b..a03f56dca1 100644 --- a/modMcf/test/org/aion/valid/TimeStampRuleTest.java +++ b/modMcf/test/org/aion/valid/TimeStampRuleTest.java @@ -5,7 +5,7 @@ import java.util.LinkedList; import java.util.List; -import org.aion.base.type.IBlockHeader; +import org.aion.interfaces.block.BlockHeader; import org.aion.mcf.blockchain.valid.IValidRule; import org.aion.mcf.valid.TimeStampRule; import org.junit.Before; @@ -20,8 +20,8 @@ */ public class TimeStampRuleTest { - @Mock IBlockHeader mockHeader; - @Mock IBlockHeader mockDependency; + @Mock BlockHeader mockHeader; + @Mock BlockHeader mockDependency; @Before public void setUp() throws Exception { diff --git a/modP2p/src/org/aion/p2p/P2pConstant.java b/modP2p/src/org/aion/p2p/P2pConstant.java index 8e85a63259..7a40b49b17 100644 --- a/modP2p/src/org/aion/p2p/P2pConstant.java +++ b/modP2p/src/org/aion/p2p/P2pConstant.java @@ -33,7 +33,6 @@ public class P2pConstant { */ CLOSE_OVERLAPPING_BLOCKS = 15, STEP_COUNT = 6, - MIN_NORMAL_PEERS = 4, MAX_NORMAL_PEERS = 16, COEFFICIENT_NORMAL_PEERS = 2, diff --git a/modP2p/src/org/aion/p2p/V1Constants.java b/modP2p/src/org/aion/p2p/V1Constants.java index d3e2bae057..f030ec4cef 100644 --- a/modP2p/src/org/aion/p2p/V1Constants.java +++ b/modP2p/src/org/aion/p2p/V1Constants.java @@ -16,6 +16,10 @@ public class V1Constants { /** Limits the number of key-value pairs returned to one trie data request. */ public static final int TRIE_DATA_REQUEST_MAXIMUM_BATCH_SIZE = 100; + /** Limits the number of blocks returned to one blocks request. */ + // TODO: also add limit for the size of the resulting message + public static final int BLOCKS_REQUEST_MAXIMUM_BATCH_SIZE = 60; + /** The number of components contained in a trie data response. */ public static int TRIE_DATA_RESPONSE_COMPONENTS = 4; } diff --git a/modP2p/src/org/aion/p2p/Ver.java b/modP2p/src/org/aion/p2p/Ver.java index aa57fa391e..1a1606ae09 100644 --- a/modP2p/src/org/aion/p2p/Ver.java +++ b/modP2p/src/org/aion/p2p/Ver.java @@ -8,7 +8,7 @@ public class Ver { public static final short V0 = 0; - // new protocol version supporting fast sync + /** New protocol version supporting fast sync. */ public static final short V1 = 1; // for test diff --git a/modP2pImpl/build.gradle b/modP2pImpl/build.gradle index 336add7c50..94b04a99c5 100644 --- a/modP2pImpl/build.gradle +++ b/modP2pImpl/build.gradle @@ -9,9 +9,10 @@ sourceSets { } dependencies { - compile project(':modUtil') + compile 'network.aion:util4j:0.4.0' + compile 'network.aion:log4j:0.4.0' + compile project(':modP2p') - compile project(':modLogger') compile files('../lib/miniupnpc_linux.jar') compile 'org.apache.commons:commons-collections4:4.0' compile 'org.slf4j:slf4j-api:1.7.25' diff --git a/modP2pImpl/test/org/aion/p2p/impl/TaskRequestActiveNodesTest.java b/modP2pImpl/test/org/aion/p2p/impl/TaskRequestActiveNodesTest.java index aab3e10180..1f5500bfa7 100644 --- a/modP2pImpl/test/org/aion/p2p/impl/TaskRequestActiveNodesTest.java +++ b/modP2pImpl/test/org/aion/p2p/impl/TaskRequestActiveNodesTest.java @@ -39,7 +39,7 @@ public void setup() { p2pLOG = AionLoggerFactory.getLogger(LogEnum.P2P.name()); } - @Test + @Test(timeout = 10_000) public void TestRun() throws InterruptedException { when(mgr.getRandom()).thenReturn(node); when(node.getIdShort()).thenReturn("inode"); diff --git a/modP2pImpl/test/org/aion/p2p/impl/comm/NodeMgrTest.java b/modP2pImpl/test/org/aion/p2p/impl/comm/NodeMgrTest.java index 2e89728687..1847e28792 100644 --- a/modP2pImpl/test/org/aion/p2p/impl/comm/NodeMgrTest.java +++ b/modP2pImpl/test/org/aion/p2p/impl/comm/NodeMgrTest.java @@ -111,7 +111,7 @@ private void addNodetoInbound(INode node, UUID _uuid) { assertNotNull(nMgr.getInboundNode(channel.hashCode())); } - @Test + @Test(timeout = 10_000) public void testTempNode() throws InterruptedException { nMgr.addTempNode(node); assertEquals(1, nMgr.tempNodesSize()); @@ -127,7 +127,7 @@ public void testTempNode() throws InterruptedException { assertEquals(2, nMgr.tempNodesSize()); } - @Test + @Test(timeout = 30_000) public void testTempNodeMax_128() throws InterruptedException { String[] nodes_max = new String[130]; @@ -148,7 +148,7 @@ public void testTempNodeMax_128() throws InterruptedException { assertEquals(128, nMgr.tempNodesSize()); } - @Test + @Test(timeout = 30_000) public void testTempNodesTake() throws InterruptedException { int port2 = 30305; @@ -179,7 +179,7 @@ public void testTempNodesTake() throws InterruptedException { assertEquals(0, mgr.tempNodesSize()); } - @Test + @Test(timeout = 30_000) public void testTempNodeMax_Any() throws InterruptedException { NodeMgr mgr = new NodeMgr(p2p, 512, 512, LOGGER); @@ -211,7 +211,7 @@ public void testTempNodeMax_Any() throws InterruptedException { assertEquals(512, mgr.tempNodesSize()); } - @Test + @Test(timeout = 30_000) public void testAddInOutBoundNode() { INode node = nMgr.allocNode(ip1, 1); @@ -227,7 +227,7 @@ public void testAddInOutBoundNode() { assertEquals(ip1, oNode.getIpStr()); } - @Test + @Test(timeout = 30_000) public void testGetActiveNodesList() { NodeMgr nMgr = new NodeMgr(p2p, MAX_ACTIVE_NODES, MAX_TEMP_NODES, LOGGER); @@ -250,7 +250,7 @@ public void testGetActiveNodesList() { } } - @Test + @Test(timeout = 30_000) public void testDropActive() { INode node = nMgr.allocNode(ip2, 1); @@ -272,7 +272,7 @@ public void testDropActive() { assertEquals(0, nMgr.activeNodesSize()); } - @Test + @Test(timeout = 30_000) public void testBan() { INode node = nMgr.allocNode(ip2, 1); @@ -291,7 +291,7 @@ public void testBan() { assertFalse(node.getPeerMetric().notBan()); } - @Test + @Test(timeout = 30_000) public void testTimeoutInbound() { INode node = nMgr.allocNode(ip2, 1); @@ -308,7 +308,7 @@ public void testTimeoutInbound() { assertNull(nMgr.getInboundNode(channel.hashCode())); } - @Test + @Test(timeout = 30_000) public void testTimeoutOutbound() { INode node = nMgr.allocNode(ip2, 1); addNodetoOutbound(node, UUID.fromString(nodeId1)); @@ -324,7 +324,7 @@ public void testTimeoutOutbound() { assertNull(nMgr.getOutboundNode(node.getIdHash())); } - @Test + @Test(timeout = 30_000) public void testAllocate() { INode node = nMgr.allocNode(ip2, 1); assertNotNull(node); @@ -336,7 +336,7 @@ public void testAllocate() { assertTrue(node.getIfFromBootList()); } - @Test + @Test(timeout = 30_000) public void testGetOutBoundNode() { INode node = nMgr.allocNode(ip2, 1); addNodetoOutbound(node, UUID.fromString(nodeId1)); @@ -352,7 +352,7 @@ public void testGetOutBoundNode() { assertNull(nMgr.getOutboundNode(node.getIdHash())); } - @Test + @Test(timeout = 30_000) public void testMoveOutboundToActive() { INode node = nMgr.allocNode(ip2, 1); addNodetoOutbound(node, UUID.fromString(nodeId1)); @@ -365,7 +365,7 @@ public void testMoveOutboundToActive() { assertEquals(node, activeNode); } - @Test + @Test(timeout = 30_000) public void testMoveInboundToActive() { INode node = nMgr.allocNode(ip2, 1); addNodetoInbound(node, UUID.fromString(nodeId1)); @@ -378,7 +378,7 @@ public void testMoveInboundToActive() { assertEquals(node, activeNode); } - @Test + @Test(timeout = 30_000) public void testTimeoutActive() throws InterruptedException { INode node = nMgr.allocNode(ip2, 1); addNodetoInbound(node, UUID.fromString(nodeId1)); @@ -394,7 +394,7 @@ public void testTimeoutActive() throws InterruptedException { assertNull(nMgr.getActiveNode(node.getIdHash())); } - @Test + @Test(timeout = 30_000) public void testGetActiveNodesMap() { INode node = nMgr.allocNode(ip2, 1); addNodetoInbound(node, UUID.fromString(nodeId1)); @@ -406,7 +406,7 @@ public void testGetActiveNodesMap() { assertEquals(1, activeMap.size()); } - @Test + @Test(timeout = 30_000) public void testNotAtOutBoundList() { INode node = nMgr.allocNode(ip2, 1); addNodetoOutbound(node, UUID.fromString(nodeId1)); @@ -416,7 +416,7 @@ public void testNotAtOutBoundList() { assertTrue(nMgr.notAtOutboundList(node.getIdHash())); } - @Test + @Test(timeout = 30_000) public void testGetRandom() { assertNull(nMgr.getRandom()); @@ -429,7 +429,7 @@ public void testGetRandom() { assertEquals(node, nodeRandom); } - @Test + @Test(timeout = 30_000) public void testMovePeerToActive() { INode node = nMgr.allocNode(ip2, 1); node.setChannel(channel); @@ -437,7 +437,7 @@ public void testMovePeerToActive() { assertTrue(nMgr.getActiveNodesMap().isEmpty()); } - @Test + @Test(timeout = 30_000) public void testMovePeerToActive2() { nMgr = new NodeMgr(p2p, 2, 2, LOGGER); INode node = nMgr.allocNode(ip2, 1); @@ -456,7 +456,7 @@ public void testMovePeerToActive2() { assertEquals(2, nMgr.getActiveNodesMap().size()); } - @Test + @Test(timeout = 30_000) public void testMovePeerToActive3() { INode node = nMgr.allocNode(ip2, 1); addNodetoOutbound(node, UUID.fromString(nodeId1)); @@ -467,7 +467,7 @@ public void testMovePeerToActive3() { assertTrue(nMgr.getActiveNodesMap().isEmpty()); } - @Test + @Test(timeout = 30_000) public void testShutDown() { INode node = nMgr.allocNode(ip2, 1); addNodetoOutbound(node, UUID.randomUUID()); @@ -486,7 +486,7 @@ public void testShutDown() { assertTrue(nMgr.getActiveNodesMap().isEmpty()); } - @Test + @Test(timeout = 30_000) public void testDumpNodeInfo() { String dump = nMgr.dumpNodeInfo("testId", false); assertNotNull(dump); @@ -502,7 +502,7 @@ public void testDumpNodeInfo() { assertTrue(dump3.length() > dump2.length()); } - @Test + @Test(timeout = 30_000) public void testDumpNodeInfo2() { String dump = nMgr.dumpNodeInfo("testId", false); assertNotNull(dump); @@ -529,7 +529,7 @@ public void testDumpNodeInfo2() { assertEquals(dump3.length(), dump2.length()); } - @Test + @Test(timeout = 30_000) public void testDumpNodeInfo3() { String dump = nMgr.dumpNodeInfo("testId", false); assertNotNull(dump); @@ -542,9 +542,9 @@ public void testDumpNodeInfo3() { assertTrue(dump2.length() > dump.length()); } - @Test + @Test(timeout = 60_000) public void testConcurrency() throws InterruptedException { - AtomicInteger count = new AtomicInteger(1000); + AtomicInteger count = new AtomicInteger(100); AtomicBoolean start = new AtomicBoolean(false); @@ -562,7 +562,7 @@ public void run() { e.printStackTrace(); } try { - Thread.sleep(r.nextInt(5) + 5); + Thread.sleep(r.nextInt(5) + 20); } catch (InterruptedException e) { e.printStackTrace(); } @@ -598,7 +598,7 @@ private INode genNode() { () -> { while (start.get()) { try { - Thread.sleep(15); + Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } @@ -623,7 +623,7 @@ private INode genNode() { () -> { while (start.get()) { try { - Thread.sleep(15); + Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } @@ -670,7 +670,7 @@ private INode genNode() { count.getAndDecrement(); try { - Thread.sleep(8); + Thread.sleep(15); } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/modP2pImpl/test/org/aion/p2p/impl1/tasks/TaskRecvTest.java b/modP2pImpl/test/org/aion/p2p/impl1/tasks/TaskRecvTest.java index 292029cad4..a7a2750282 100644 --- a/modP2pImpl/test/org/aion/p2p/impl1/tasks/TaskRecvTest.java +++ b/modP2pImpl/test/org/aion/p2p/impl1/tasks/TaskRecvTest.java @@ -9,14 +9,10 @@ import static org.mockito.Mockito.when; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.atomic.AtomicBoolean; -import org.aion.log.AionLoggerFactory; -import org.aion.log.LogEnum; -import org.aion.log.LogLevel; import org.aion.p2p.Handler; import org.junit.Before; import org.junit.Test; @@ -34,10 +30,6 @@ public class TaskRecvTest { @Before public void setup() { MockitoAnnotations.initMocks(this); - - Map logMap = new HashMap<>(); - logMap.put(LogEnum.P2P.name(), LogLevel.INFO.name()); - AionLoggerFactory.init(logMap); } @Test(timeout = 10_000) diff --git a/modPrecompiled/build.gradle b/modPrecompiled/build.gradle index a7a5e4ea99..faaed734ce 100644 --- a/modPrecompiled/build.gradle +++ b/modPrecompiled/build.gradle @@ -3,11 +3,12 @@ test.dependsOn copyNativeLibsForModuleTests clean.dependsOn deleteNativeLibs dependencies { - compile project(':modAionBase') + compile project(':aion_vm_api') + compile 'network.aion:util4j:0.4.0' + compile 'network.aion:crypto4j:0.4.0' + compile project(':modMcf') - compile project(':modCrypto') compile project(':modAion') - compile project(':aion_vm_api') compile 'com.google.guava:guava:25.1-jre' compile 'com.google.code.findbugs:jsr305:3.0.2' compile group: 'org.apache.commons', name: 'commons-collections4', version: '4.0' @@ -15,11 +16,11 @@ dependencies { testCompile project(':modMcf') testCompile project(':modEvtMgr') - testCompile project(':modRlp') testCompile project(':modPrecompiled') testCompile project(':modAionImpl') - testCompile project(':modLogger') testCompile project(':modDbImpl') + testCompile 'network.aion:rlp4j:0.4.0' + testCompile 'network.aion:log4j:0.4.0' testCompile 'junit:junit:4.12' testCompile 'org.hamcrest:hamcrest-all:1.3' testCompile group: 'com.googlecode.java-diff-utils', name: 'diffutils', version: '1.2' diff --git a/modPrecompiled/src/module-info.java b/modPrecompiled/src/module-info.java index 7a109fb2ab..c06d793bdd 100644 --- a/modPrecompiled/src/module-info.java +++ b/modPrecompiled/src/module-info.java @@ -1,14 +1,13 @@ module aion.precompiled { requires aion.zero; requires aion.mcf; - requires aion.base; requires aion.crypto; requires slf4j.api; requires jsr305; requires commons.collections4; requires com.google.common; - requires aion.vm.api; requires aion.util; + requires aion.vm.api; exports org.aion.precompiled; exports org.aion.precompiled.type; diff --git a/modPrecompiled/src/org/aion/precompiled/ContractFactory.java b/modPrecompiled/src/org/aion/precompiled/ContractFactory.java index e8cda8205f..b968e33e51 100644 --- a/modPrecompiled/src/org/aion/precompiled/ContractFactory.java +++ b/modPrecompiled/src/org/aion/precompiled/ContractFactory.java @@ -1,6 +1,6 @@ package org.aion.precompiled; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.mcf.config.CfgFork; import org.aion.mcf.vm.types.KernelInterfaceForFastVM; import org.aion.precompiled.contracts.ATB.TokenBridgeContract; @@ -9,7 +9,6 @@ import org.aion.precompiled.contracts.TXHashContract; import org.aion.precompiled.contracts.TotalCurrencyContract; import org.aion.precompiled.type.PrecompiledContract; -import org.aion.vm.api.interfaces.Address; import org.aion.vm.api.interfaces.KernelInterface; import org.aion.vm.api.interfaces.TransactionContext; @@ -68,11 +67,11 @@ public PrecompiledContract getPrecompiledContract( new TokenBridgeContract( context, ((KernelInterfaceForFastVM) track).getRepositoryCache(), - AionAddress.wrap(ADDR_TOKEN_BRIDGE_INITIAL_OWNER), - AionAddress.wrap(ADDR_TOKEN_BRIDGE)); + Address.wrap(ADDR_TOKEN_BRIDGE_INITIAL_OWNER), + Address.wrap(ADDR_TOKEN_BRIDGE)); if (!context.getOriginAddress() - .equals(AionAddress.wrap(ADDR_TOKEN_BRIDGE_INITIAL_OWNER)) + .equals(Address.wrap(ADDR_TOKEN_BRIDGE_INITIAL_OWNER)) && !contract.isInitialized()) { return null; } @@ -90,7 +89,7 @@ public PrecompiledContract getPrecompiledContract( : new TotalCurrencyContract( ((KernelInterfaceForFastVM) track).getRepositoryCache(), context.getSenderAddress(), - AionAddress.wrap(ADDR_OWNER)); + Address.wrap(ADDR_OWNER)); default: return null; } @@ -121,7 +120,7 @@ public static boolean isPrecompiledContract(Address address) { * @return the contract address. */ public static Address getTotalCurrencyContractAddress() { - return AionAddress.wrap(ADDR_TOTAL_CURRENCY); + return Address.wrap(ADDR_TOTAL_CURRENCY); } /** @@ -130,7 +129,7 @@ public static Address getTotalCurrencyContractAddress() { * @return the contract address */ public static Address getEdVerifyContractAddress() { - return AionAddress.wrap(ADDR_ED_VERIFY); + return Address.wrap(ADDR_ED_VERIFY); } /** @@ -139,7 +138,7 @@ public static Address getEdVerifyContractAddress() { * @return the contract address */ public static Address getTxHashContractAddress() { - return AionAddress.wrap(ADDR_TX_HASH); + return Address.wrap(ADDR_TX_HASH); } /** @@ -148,6 +147,6 @@ public static Address getTxHashContractAddress() { * @return the contract address */ public static Address getBlake2bHashContractAddress() { - return AionAddress.wrap(ADDR_BLAKE2B_HASH); + return Address.wrap(ADDR_BLAKE2B_HASH); } } diff --git a/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeController.java b/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeController.java index a4dd1dde9a..775049d45f 100644 --- a/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeController.java +++ b/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeController.java @@ -10,14 +10,14 @@ import java.util.Collections; import java.util.List; import javax.annotation.Nonnull; -import org.aion.base.util.ByteUtil; import org.aion.crypto.ISignature; import org.aion.crypto.SignatureFac; import org.aion.mcf.vm.types.Log; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; import org.aion.precompiled.PrecompiledUtilities; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; +import org.aion.util.bytes.ByteUtil; import org.aion.vm.api.interfaces.TransactionSideEffects; /** diff --git a/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeDeserializer.java b/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeDeserializer.java index aefdf1ab5d..1079e3d461 100644 --- a/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeDeserializer.java +++ b/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeDeserializer.java @@ -2,7 +2,7 @@ import java.math.BigInteger; import javax.annotation.Nonnull; -import org.aion.base.util.ByteUtil; +import org.aion.util.bytes.ByteUtil; public class BridgeDeserializer { diff --git a/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeFuncSig.java b/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeFuncSig.java index 3555cefa22..96c7d15d45 100644 --- a/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeFuncSig.java +++ b/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeFuncSig.java @@ -5,7 +5,7 @@ import java.util.HashMap; import java.util.Map; import javax.annotation.Nonnull; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; enum BridgeFuncSig { SIG_CHANGE_OWNER("changeOwner(address)"), diff --git a/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeStorageConnector.java b/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeStorageConnector.java index f200c6776b..f4ed6fca4c 100644 --- a/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeStorageConnector.java +++ b/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeStorageConnector.java @@ -3,16 +3,16 @@ import java.math.BigInteger; import java.util.Arrays; import javax.annotation.Nonnull; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.HashUtil; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; -import org.aion.mcf.vm.types.DataWord; import org.aion.mcf.vm.types.DoubleDataWord; import org.aion.precompiled.PrecompiledUtilities; -import org.aion.vm.api.interfaces.Address; +import org.aion.util.bytes.ByteUtil; /** * Storage layout mapping as the following: @@ -40,17 +40,17 @@ public class BridgeStorageConnector { private enum S_OFFSET { - OWNER(new DataWord(0x0)), - NEW_OWNER(new DataWord(0x1)), - MEMBER_COUNT(new DataWord(0x2)), - MIN_THRESH(new DataWord(0x3)), - RING_LOCKED(new DataWord(0x4)), - RELAYER(new DataWord(0x5)), - INITIALIZED(new DataWord(0x42)); + OWNER(new DataWordImpl(0x0)), + NEW_OWNER(new DataWordImpl(0x1)), + MEMBER_COUNT(new DataWordImpl(0x2)), + MIN_THRESH(new DataWordImpl(0x3)), + RING_LOCKED(new DataWordImpl(0x4)), + RELAYER(new DataWordImpl(0x5)), + INITIALIZED(new DataWordImpl(0x42)); - private final DataWord offset; + private final DataWordImpl offset; - S_OFFSET(DataWord offset) { + S_OFFSET(DataWordImpl offset) { this.offset = offset; } } @@ -66,18 +66,18 @@ private enum M_ID { } } - private final IRepositoryCache> track; + private final RepositoryCache> track; private final Address contractAddress; public BridgeStorageConnector( - @Nonnull final IRepositoryCache> track, + @Nonnull final RepositoryCache> track, @Nonnull final Address contractAddress) { this.track = track; this.contractAddress = contractAddress; } public void setInitialized(final boolean initialized) { - DataWord init = initialized ? new DataWord(1) : new DataWord(0); + DataWordImpl init = initialized ? new DataWordImpl(1) : new DataWordImpl(0); this.setWORD(S_OFFSET.INITIALIZED.offset, init); } @@ -115,7 +115,7 @@ public byte[] getRelayer() { public void setMemberCount(int amount) { assert amount >= 0 : "amount must be positive"; - this.setWORD(S_OFFSET.MEMBER_COUNT.offset, new DataWord(amount)); + this.setWORD(S_OFFSET.MEMBER_COUNT.offset, new DataWordImpl(amount)); } public int getMemberCount() { @@ -126,7 +126,7 @@ public int getMemberCount() { public void setMinThresh(int amount) { assert amount >= 0 : "amount must be positive"; - this.setWORD(S_OFFSET.MIN_THRESH.offset, new DataWord(amount)); + this.setWORD(S_OFFSET.MIN_THRESH.offset, new DataWordImpl(amount)); } public int getMinThresh() { @@ -138,7 +138,7 @@ public int getMinThresh() { // TODO: this can be optimized public void setRingLocked(boolean value) { - DataWord lockedDw = value ? new DataWord(1) : new DataWord(0); + DataWordImpl lockedDw = value ? new DataWordImpl(1) : new DataWordImpl(0); this.setWORD(S_OFFSET.RING_LOCKED.offset, lockedDw); } @@ -154,15 +154,15 @@ public boolean getRingLocked() { public void setActiveMember(@Nonnull final byte[] key, final boolean value) { assert key.length == 32; byte[] h = ByteUtil.chop(HashUtil.h256(ByteUtil.merge(M_ID.ACTIVE_MAP.id, key))); - DataWord hWord = new DataWord(h); - DataWord b = value ? new DataWord(1) : new DataWord(0); + DataWordImpl hWord = new DataWordImpl(h); + DataWordImpl b = value ? new DataWordImpl(1) : new DataWordImpl(0); this.setWORD(hWord, b); } public boolean getActiveMember(@Nonnull final byte[] key) { assert key.length == 32; byte[] h = ByteUtil.chop(HashUtil.h256(ByteUtil.merge(M_ID.ACTIVE_MAP.id, key))); - DataWord hWord = new DataWord(h); + DataWordImpl hWord = new DataWordImpl(h); // C1 covered by getWORD byte[] activeMemberWord = this.getWORD(hWord); @@ -182,7 +182,7 @@ public void setBundle(@Nonnull final byte[] key, @Nonnull final byte[] value) { assert value.length == 32; byte[] h = ByteUtil.chop(HashUtil.h256(ByteUtil.merge(M_ID.BUNDLE_MAP.id, key))); - DataWord hWord = new DataWord(h); + DataWordImpl hWord = new DataWordImpl(h); this.setDWORD(hWord, value); } @@ -198,7 +198,7 @@ public void setBundle(@Nonnull final byte[] key, @Nonnull final byte[] value) { public byte[] getBundle(@Nonnull final byte[] key) { assert key.length == 32; byte[] h = ByteUtil.chop(HashUtil.h256(ByteUtil.merge(M_ID.BUNDLE_MAP.id, key))); - DataWord hWord = new DataWord(h); + DataWordImpl hWord = new DataWordImpl(h); byte[] bundleDoubleWord = this.getDWORD(hWord); if (bundleDoubleWord == null) return ByteUtil.EMPTY_WORD; @@ -211,14 +211,14 @@ public byte[] getBundle(@Nonnull final byte[] key) { // DWORD helpers - private byte[] getWORD(@Nonnull final DataWord key) { + private byte[] getWORD(@Nonnull final DataWordImpl key) { ByteArrayWrapper word = this.track.getStorageValue(contractAddress, key.toWrapper()); // C1 if (word == null || Arrays.equals(word.getData(), ByteUtil.EMPTY_HALFWORD)) return null; return alignBytes(word.getData()); } - private void setWORD(@Nonnull final DataWord key, @Nonnull final DataWord word) { + private void setWORD(@Nonnull final DataWordImpl key, @Nonnull final DataWordImpl word) { if (word.isZero()) { this.track.removeStorageRow(contractAddress, key.toWrapper()); } else { @@ -229,7 +229,7 @@ private void setWORD(@Nonnull final DataWord key, @Nonnull final DataWord word) } } - private void setDWORD(@Nonnull final DataWord key, @Nonnull final byte[] dword) { + private void setDWORD(@Nonnull final DataWordImpl key, @Nonnull final byte[] dword) { assert dword.length > 16; DoubleDataWord ddw = new DoubleDataWord(dword); if (ddw.isZero()) { @@ -239,7 +239,7 @@ private void setDWORD(@Nonnull final DataWord key, @Nonnull final byte[] dword) } } - private byte[] getDWORD(@Nonnull final DataWord key) { + private byte[] getDWORD(@Nonnull final DataWordImpl key) { ByteArrayWrapper word = this.track.getStorageValue(contractAddress, key.toWrapper()); if (word == null) return null; @@ -252,8 +252,8 @@ private byte[] alignBytes(byte[] unalignedBytes) { return null; } - return (unalignedBytes.length > DataWord.BYTES) + return (unalignedBytes.length > DataWordImpl.BYTES) ? new DoubleDataWord(unalignedBytes).getData() - : new DataWord(unalignedBytes).getData(); + : new DataWordImpl(unalignedBytes).getData(); } } diff --git a/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeUtilities.java b/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeUtilities.java index 75be937d40..975a67d1b6 100644 --- a/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeUtilities.java +++ b/modPrecompiled/src/org/aion/precompiled/contracts/ATB/BridgeUtilities.java @@ -4,9 +4,9 @@ import java.nio.ByteBuffer; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.aion.base.util.ByteUtil; import org.aion.crypto.HashUtil; import org.aion.precompiled.PrecompiledUtilities; +import org.aion.util.bytes.ByteUtil; public class BridgeUtilities { diff --git a/modPrecompiled/src/org/aion/precompiled/contracts/ATB/TokenBridgeContract.java b/modPrecompiled/src/org/aion/precompiled/contracts/ATB/TokenBridgeContract.java index 4bf228a854..08c9062137 100644 --- a/modPrecompiled/src/org/aion/precompiled/contracts/ATB/TokenBridgeContract.java +++ b/modPrecompiled/src/org/aion/precompiled/contracts/ATB/TokenBridgeContract.java @@ -11,15 +11,14 @@ import java.math.BigInteger; import javax.annotation.Nonnull; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; -import org.aion.mcf.vm.types.DataWord; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; import org.aion.precompiled.type.StatefulPrecompiledContract; -import org.aion.vm.api.interfaces.Address; import org.aion.vm.api.interfaces.TransactionContext; import org.aion.zero.types.AionInternalTx; @@ -30,7 +29,7 @@ public class TokenBridgeContract extends StatefulPrecompiledContract implements // queries private final TransactionContext context; - private final IRepositoryCache> track; + private final RepositoryCache> track; private final BridgeStorageConnector connector; private final BridgeController controller; @@ -41,7 +40,7 @@ public class TokenBridgeContract extends StatefulPrecompiledContract implements public TokenBridgeContract( @Nonnull final TransactionContext context, - @Nonnull final IRepositoryCache> track, + @Nonnull final RepositoryCache> track, @Nonnull final Address ownerAddress, @Nonnull final Address contractAddress) { super(track); @@ -244,7 +243,7 @@ private PrecompiledTransactionResult success(@Nonnull final byte[] response) { private boolean isFromAddress(byte[] address) { if (address == null) return false; - return this.context.getSenderAddress().equals(AionAddress.wrap(address)); + return this.context.getSenderAddress().equals(Address.wrap(address)); } /** @@ -267,9 +266,9 @@ public PrecompiledTransactionResult transfer( // assemble an internal transaction Address from = this.contractAddress; - Address recipient = new AionAddress(to); + Address recipient = new Address(to); BigInteger nonce = this.track.getNonce(from); - DataWord valueToSend = new DataWord(value); + DataWordImpl valueToSend = new DataWordImpl(value); byte[] dataToSend = new byte[0]; AionInternalTx tx = newInternalTx(from, recipient, nonce, valueToSend, dataToSend, "call"); @@ -291,7 +290,7 @@ public PrecompiledTransactionResult transfer( *

    NOTE: copied from {@code Callback} */ private AionInternalTx newInternalTx( - Address from, Address to, BigInteger nonce, DataWord value, byte[] data, String note) { + Address from, Address to, BigInteger nonce, DataWordImpl value, byte[] data, String note) { byte[] parentHash = context.getTransactionHash(); int depth = context.getTransactionStackDepth(); int index = context.getSideEffects().getInternalTransactions().size(); @@ -300,7 +299,7 @@ private AionInternalTx newInternalTx( parentHash, depth, index, - new DataWord(nonce).getData(), + new DataWordImpl(nonce).getData(), from, to, value.getData(), diff --git a/modPrecompiled/src/org/aion/precompiled/contracts/AionAuctionContract.java b/modPrecompiled/src/org/aion/precompiled/contracts/AionAuctionContract.java index 9932e426f3..b467439b70 100644 --- a/modPrecompiled/src/org/aion/precompiled/contracts/AionAuctionContract.java +++ b/modPrecompiled/src/org/aion/precompiled/contracts/AionAuctionContract.java @@ -15,9 +15,10 @@ import java.util.Set; import java.util.Timer; import java.util.TimerTask; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.crypto.ed25519.ECKeyEd25519; @@ -25,12 +26,10 @@ import org.aion.mcf.core.AccountState; import org.aion.mcf.core.IBlockchain; import org.aion.mcf.db.IBlockStoreBase; -import org.aion.mcf.vm.types.DataWord; import org.aion.mcf.vm.types.DoubleDataWord; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; import org.aion.precompiled.type.StatefulPrecompiledContract; -import org.aion.vm.api.interfaces.Address; import org.apache.commons.collections4.map.LRUMap; /** @@ -44,27 +43,27 @@ */ public class AionAuctionContract extends StatefulPrecompiledContract { private static final Address AION = - AionAddress.wrap("0xa0eeaeabdbc92953b072afbd21f3e3fd8a4a4f5e6a6e22200db746ab75e9a99a"); + Address.wrap("0xa0eeaeabdbc92953b072afbd21f3e3fd8a4a4f5e6a6e22200db746ab75e9a99a"); private Address activeDomainsAddress = - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000600"); + Address.wrap("0000000000000000000000000000000000000000000000000000000000000600"); private Address activeDomainsAddressTime = - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000601"); + Address.wrap("0000000000000000000000000000000000000000000000000000000000000601"); private Address activeDomainsAddressName = - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000602"); + Address.wrap("0000000000000000000000000000000000000000000000000000000000000602"); private Address activeDomainsAddressValue = - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000603"); + Address.wrap("0000000000000000000000000000000000000000000000000000000000000603"); private Address auctionDomainsAddress = - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000700"); + Address.wrap("0000000000000000000000000000000000000000000000000000000000000700"); private Address auctionDomainsAddressName = - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000702"); + Address.wrap("0000000000000000000000000000000000000000000000000000000000000702"); private Address allAddresses = - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000800"); + Address.wrap("0000000000000000000000000000000000000000000000000000000000000800"); private Address domainNameAddressPair = - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000801"); + Address.wrap("0000000000000000000000000000000000000000000000000000000000000801"); private Address domainAddressNamePair = - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000802"); + Address.wrap("0000000000000000000000000000000000000000000000000000000000000802"); private static final long COST = 20000L; private static final int SIG_LEN = 96; @@ -100,7 +99,7 @@ public class AionAuctionContract extends StatefulPrecompiledContract { * @param address The callerAddress of the calling account, use AION address for testing */ public AionAuctionContract( - IRepositoryCache> track, + RepositoryCache> track, Address address, IBlockchain blockchain) { super(track); @@ -204,7 +203,7 @@ public PrecompiledTransactionResult execute(byte[] input, long nrg) { domainName = domainName.substring(0, 32); Ed25519Signature sig = Ed25519Signature.fromBytes(sign); - Address bidderAddress = AionAddress.wrap(bidderAddressInByte); + Address bidderAddress = Address.wrap(bidderAddressInByte); // user should have the signature signed with its callerAddress byte[] data = new byte[ADDR_LEN]; @@ -217,7 +216,7 @@ public PrecompiledTransactionResult execute(byte[] input, long nrg) { PrecompiledResultCode.FAILURE, nrg - COST, "incorrect signature".getBytes()); } - if (!bidderAddress.equals(AionAddress.wrap(sig.getAddress()))) { + if (!bidderAddress.equals(Address.wrap(sig.getAddress()))) { return new PrecompiledTransactionResult( PrecompiledResultCode.FAILURE, nrg - COST, "incorrect key".getBytes()); } @@ -226,7 +225,7 @@ public PrecompiledTransactionResult execute(byte[] input, long nrg) { if (this.track .getStorageValue( domainNameAddressPair, - new DataWord(blake128(domainName.getBytes())).toWrapper()) + new DataWordImpl(blake128(domainName.getBytes())).toWrapper()) .equals(DoubleDataWord.ZERO)) { domainAddress = createAddressForDomain(domainName); } else { // extract the callerAddress corresponding to the domain name @@ -489,7 +488,7 @@ private void processAuction(Address domainAddress) { addBigIntegerToStorage(domainAddress, BID_KEY_COUNTER, new BigInteger("0")); // remove from auction domains this.track.removeStorageRow( - auctionDomainsAddress, new DataWord(blake128(domainAddress.toBytes())).toWrapper()); + auctionDomainsAddress, new DataWordImpl(blake128(domainAddress.toBytes())).toWrapper()); addToActiveDomains(domainAddress, winnerAddress, domainName, secondHighestBid); printWinner(domainAddress, winnerAddress, secondHighestBid, domainName); } @@ -514,7 +513,7 @@ private byte[] fillByteArray(byte[] inputBytes) { * @return the trimmed byte array */ private boolean isActiveDomain(Address domainAddress) { - DataWord key = new DataWord(blake128(domainAddress.toBytes())); + DataWordImpl key = new DataWordImpl(blake128(domainAddress.toBytes())); return !(this.track .getStorageValue(activeDomainsAddress, key.toWrapper()) .equals(DoubleDataWord.ZERO.toWrapper())); @@ -526,7 +525,7 @@ private boolean isActiveDomain(Address domainAddress) { * @param domainAddress a domain callerAddress */ private boolean isAuctionDomain(Address domainAddress) { - DataWord key = new DataWord(blake128(domainAddress.toBytes())); + DataWordImpl key = new DataWordImpl(blake128(domainAddress.toBytes())); ByteArrayWrapper ret = this.track.getStorageValue(auctionDomainsAddress, key.toWrapper()); return !ret.equals(DoubleDataWord.ZERO.toWrapper()); } @@ -605,22 +604,22 @@ private void removeActiveDomain(Address domainAddress, long expireTime) { printRemoveActiveDomain(domainAddress); // erase this.track.removeStorageRow( - activeDomainsAddress, new DataWord(blake128(domainAddress.toBytes())).toWrapper()); + activeDomainsAddress, new DataWordImpl(blake128(domainAddress.toBytes())).toWrapper()); this.track.removeStorageRow( activeDomainsAddress, - new DataWord(blake128(blake128(domainAddress.toBytes()))).toWrapper()); + new DataWordImpl(blake128(blake128(domainAddress.toBytes()))).toWrapper()); this.track.removeStorageRow( activeDomainsAddressName, - new DataWord(blake128(domainAddress.toBytes())).toWrapper()); + new DataWordImpl(blake128(domainAddress.toBytes())).toWrapper()); this.track.removeStorageRow( activeDomainsAddressName, - new DataWord(blake128(blake128(domainAddress.toBytes()))).toWrapper()); + new DataWordImpl(blake128(blake128(domainAddress.toBytes()))).toWrapper()); this.track.removeStorageRow( activeDomainsAddressValue, - new DataWord(blake128(domainAddress.toBytes())).toWrapper()); + new DataWordImpl(blake128(domainAddress.toBytes())).toWrapper()); this.track.removeStorageRow( activeDomainsAddressTime, - new DataWord(blake128(domainAddress.toBytes())).toWrapper()); + new DataWordImpl(blake128(domainAddress.toBytes())).toWrapper()); } /** @@ -660,7 +659,7 @@ private boolean hasActiveParentDomain(String domainName) { } // check if domain exists, and if it is active - AionAddress parentAddr = null; + Address parentAddr = null; try { parentAddr = getAddressFromName( @@ -687,7 +686,7 @@ private boolean hasActiveParentDomain(String domainName) { */ private Address createAddressForDomain(String domainName) { ECKey domainAddr = ECKeyFac.inst().create(); - Address domainAddress = AionAddress.wrap(domainAddr.getAddress()); + Address domainAddress = Address.wrap(domainAddr.getAddress()); // store callerAddress -> name pair & name -> callerAddress pair addNameToStorage(domainAddressNamePair, domainAddress, domainName); @@ -700,20 +699,20 @@ private Address createAddressForDomain(String domainName) { * @param domainName name of domain * @return callerAddress of domain */ - private AionAddress getAddressFromName(String domainName) { + private Address getAddressFromName(String domainName) { byte[] addrFirstPart = this.track .getStorageValue( domainNameAddressPair, - new DataWord(blake128(domainName.getBytes())).toWrapper()) + new DataWordImpl(blake128(domainName.getBytes())).toWrapper()) .getData(); byte[] addrSecondPart = this.track .getStorageValue( domainNameAddressPair, - new DataWord(blake128(blake128(domainName.getBytes()))).toWrapper()) + new DataWordImpl(blake128(blake128(domainName.getBytes()))).toWrapper()) .getData(); - return AionAddress.wrap(combineTwoBytes(addrFirstPart, addrSecondPart)); + return Address.wrap(combineTwoBytes(addrFirstPart, addrSecondPart)); } /** @@ -726,59 +725,59 @@ private void storeNewAddress(Address domainAddress) { BigInteger counter = getBigIntegerFromStorage(allAddresses, ALL_ADDR_COUNTER_KEY); this.track.addStorageRow( allAddresses, - new DataWord(blake128(ALL_ADDR_COUNTER_KEY.getBytes())).toWrapper(), - new DataWord(counter.add(BigInteger.ONE)).toWrapper()); + new DataWordImpl(blake128(ALL_ADDR_COUNTER_KEY.getBytes())).toWrapper(), + new DataWordImpl(counter.add(BigInteger.ONE)).toWrapper()); addAddressToStorage(allAddresses, ALL_ADDR_KEY + counter, domainAddress); } private Address getAddressFromStorage(Address key, Address key2) { byte[] addrFirstPart = this.track - .getStorageValue(key, new DataWord(blake128(key2.toBytes())).toWrapper()) + .getStorageValue(key, new DataWordImpl(blake128(key2.toBytes())).toWrapper()) .getData(); byte[] addrSecondPart = this.track .getStorageValue( - key, new DataWord(blake128(blake128(key2.toBytes()))).toWrapper()) + key, new DataWordImpl(blake128(blake128(key2.toBytes()))).toWrapper()) .getData(); - return AionAddress.wrap(combineTwoBytes(addrFirstPart, addrSecondPart)); + return Address.wrap(combineTwoBytes(addrFirstPart, addrSecondPart)); } private Address getAddressFromStorage(Address key, String key2) { byte[] addrFirstPart = this.track - .getStorageValue(key, new DataWord(blake128(key2.getBytes())).toWrapper()) + .getStorageValue(key, new DataWordImpl(blake128(key2.getBytes())).toWrapper()) .getData(); byte[] addrSecondPart = this.track .getStorageValue( - key, new DataWord(blake128(blake128(key2.getBytes()))).toWrapper()) + key, new DataWordImpl(blake128(blake128(key2.getBytes()))).toWrapper()) .getData(); - return AionAddress.wrap(combineTwoBytes(addrFirstPart, addrSecondPart)); + return Address.wrap(combineTwoBytes(addrFirstPart, addrSecondPart)); } private BigInteger getBigIntegerFromStorage(Address key, String key2) { ByteArrayWrapper data = this.track.getStorageValue( - key, new DataWord(blake128(key2.getBytes())).toWrapper()); + key, new DataWordImpl(blake128(key2.getBytes())).toWrapper()); return new BigInteger(data.getData()); } private BigInteger getBigIntegerFromStorage(Address key, Address key2) { ByteArrayWrapper data = - this.track.getStorageValue(key, new DataWord(blake128(key2.toBytes())).toWrapper()); + this.track.getStorageValue(key, new DataWordImpl(blake128(key2.toBytes())).toWrapper()); return new BigInteger(data.getData()); } private String getNameFromStorage(Address key, Address key2) { byte[] domainNameFirstPart = this.track - .getStorageValue(key, new DataWord(blake128(key2.toBytes())).toWrapper()) + .getStorageValue(key, new DataWordImpl(blake128(key2.toBytes())).toWrapper()) .getData(); byte[] domainNameSecondPart = this.track .getStorageValue( - key, new DataWord(blake128(blake128(key2.toBytes()))).toWrapper()) + key, new DataWordImpl(blake128(blake128(key2.toBytes()))).toWrapper()) .getData(); String tempDomainName; try { @@ -796,7 +795,7 @@ key, new DataWord(blake128(blake128(key2.toBytes()))).toWrapper()) private Date getDateFromStorage(Address key, Address key2) { byte[] expireDateData = this.track - .getStorageValue(key, new DataWord(blake128(key2.toBytes())).toWrapper()) + .getStorageValue(key, new DataWordImpl(blake128(key2.toBytes())).toWrapper()) .getData(); byte[] trimmedExpireDateData = trimLeadingZeros16(expireDateData); String expireDateStr; @@ -816,12 +815,12 @@ private void addAddressToStorage(Address key, Address key2, Address value) { this.track.addStorageRow( key, - new DataWord(blake128(key2.toBytes())).toWrapper(), - new DataWord(addrFirstPart).toWrapper()); + new DataWordImpl(blake128(key2.toBytes())).toWrapper(), + new DataWordImpl(addrFirstPart).toWrapper()); this.track.addStorageRow( key, - new DataWord(blake128(blake128(key2.toBytes()))).toWrapper(), - new DataWord(addrSecondPart).toWrapper()); + new DataWordImpl(blake128(blake128(key2.toBytes()))).toWrapper(), + new DataWordImpl(addrSecondPart).toWrapper()); } private void addAddressToStorage(Address key, String key2, Address value) { @@ -832,12 +831,12 @@ private void addAddressToStorage(Address key, String key2, Address value) { this.track.addStorageRow( key, - new DataWord(blake128(key2.getBytes())).toWrapper(), - new DataWord(addrFirstPart).toWrapper()); + new DataWordImpl(blake128(key2.getBytes())).toWrapper(), + new DataWordImpl(addrFirstPart).toWrapper()); this.track.addStorageRow( key, - new DataWord(blake128(blake128(key2.getBytes()))).toWrapper(), - new DataWord(addrSecondPart).toWrapper()); + new DataWordImpl(blake128(blake128(key2.getBytes()))).toWrapper(), + new DataWordImpl(addrSecondPart).toWrapper()); } private void addDateToStorage(Address key, Address key2, Date value) { @@ -854,8 +853,8 @@ private void addDateToStorage(Address key, Address key2, Date value) { } this.track.addStorageRow( key, - new DataWord(blake128(key2.toBytes())).toWrapper(), - new DataWord(fillByteArray(date)).toWrapper()); + new DataWordImpl(blake128(key2.toBytes())).toWrapper(), + new DataWordImpl(fillByteArray(date)).toWrapper()); } private void addNameToStorage(Address key, Address key2, String name) { @@ -863,12 +862,12 @@ private void addNameToStorage(Address key, Address key2, String name) { byte[] nameSecondPart = name.substring(16, 32).getBytes(); this.track.addStorageRow( key, - new DataWord(blake128(key2.toBytes())).toWrapper(), - new DataWord(nameFirstPart).toWrapper()); + new DataWordImpl(blake128(key2.toBytes())).toWrapper(), + new DataWordImpl(nameFirstPart).toWrapper()); this.track.addStorageRow( key, - new DataWord(blake128(blake128(key2.toBytes()))).toWrapper(), - new DataWord(nameSecondPart).toWrapper()); + new DataWordImpl(blake128(blake128(key2.toBytes()))).toWrapper(), + new DataWordImpl(nameSecondPart).toWrapper()); } private void addNameToStorage2(Address key, Address key2, String name) { @@ -878,26 +877,26 @@ private void addNameToStorage2(Address key, Address key2, String name) { System.arraycopy(addZeros, 16, value2, 0, 16); this.track.addStorageRow( key, - new DataWord(blake128(key2.toBytes())).toWrapper(), - new DataWord(value1).toWrapper()); + new DataWordImpl(blake128(key2.toBytes())).toWrapper(), + new DataWordImpl(value1).toWrapper()); this.track.addStorageRow( key, - new DataWord(blake128(key2.toBytes())).toWrapper(), - new DataWord(value2).toWrapper()); + new DataWordImpl(blake128(key2.toBytes())).toWrapper(), + new DataWordImpl(value2).toWrapper()); } private void addBigIntegerToStorage(Address key, String key2, BigInteger value) { this.track.addStorageRow( key, - new DataWord(blake128(key2.getBytes())).toWrapper(), - new DataWord(value).toWrapper()); + new DataWordImpl(blake128(key2.getBytes())).toWrapper(), + new DataWordImpl(value).toWrapper()); } private void addBigIntegerToStorage(Address key, Address key2, BigInteger value) { this.track.addStorageRow( key, - new DataWord(blake128(key2.toBytes())).toWrapper(), - new DataWord(value).toWrapper()); + new DataWordImpl(blake128(key2.toBytes())).toWrapper(), + new DataWordImpl(value).toWrapper()); } // tasks @@ -937,7 +936,7 @@ public void run() { // data processing helpers // ---------------------------------------------------------------------------------------// /** - * Combines two length 16 byte[] (usually retrieved from repo as a DataWord(length 16) into a + * Combines two length 16 byte[] (usually retrieved from repo as a DataWordImpl(length 16) into a * length 32 byte[]. * * @param byte1 input1 @@ -999,7 +998,7 @@ private List getAllAuctionDomains() { if (!this.track .getStorageValue( auctionDomainsAddress, - new DataWord(blake128(tempDomainAddr.toBytes())).toWrapper()) + new DataWordImpl(blake128(tempDomainAddr.toBytes())).toWrapper()) .equals(DoubleDataWord.ZERO)) { Date tempExpireDate = getDateFromStorage(auctionDomainsAddress, tempDomainAddr); String tempDomainName = getNameFromStorage(domainAddressNamePair, tempDomainAddr); @@ -1053,7 +1052,7 @@ public void displayAllAuctionDomains() { } public void displayMyBidsLRU(ECKey key) { - Address callerAddress = AionAddress.wrap(key.getAddress()); + Address callerAddress = Address.wrap(key.getAddress()); boolean hasNoBids = true; System.out.println( @@ -1083,7 +1082,7 @@ public void displayMyBidsLRU(ECKey key) { } public void displayMyBidForDomainLRU(String domainNameRaw, ECKey key) { - Address callerAddress = AionAddress.wrap(key.getAddress()); + Address callerAddress = Address.wrap(key.getAddress()); System.out.println( "--------------------------AION NAME SERVICE QUERY: displayMyBidForDomainLRU--------------------------"); @@ -1103,7 +1102,7 @@ public void displayMyBidForDomainLRU(String domainNameRaw, ECKey key) { if (this.track .getStorageValue( auctionDomainsAddress, - new DataWord(blake128(domainAddress.toBytes())).toWrapper()) + new DataWordImpl(blake128(domainAddress.toBytes())).toWrapper()) .equals(DoubleDataWord.ZERO)) { System.out.println(" This domain is not in auction\n"); return; @@ -1137,7 +1136,7 @@ public void displayAuctionDomainLRU(String domainNameRaw) { if (this.track .getStorageValue( auctionDomainsAddress, - new DataWord(blake128(domainAddress.toBytes())).toWrapper()) + new DataWordImpl(blake128(domainAddress.toBytes())).toWrapper()) .equals(DoubleDataWord.ZERO)) { System.out.println("The given domain \'" + domainNameRaw + "\' is not in auction\n"); return; diff --git a/modPrecompiled/src/org/aion/precompiled/contracts/AionNameServiceContract.java b/modPrecompiled/src/org/aion/precompiled/contracts/AionNameServiceContract.java index 6ab5be7d38..a970df94e9 100644 --- a/modPrecompiled/src/org/aion/precompiled/contracts/AionNameServiceContract.java +++ b/modPrecompiled/src/org/aion/precompiled/contracts/AionNameServiceContract.java @@ -9,20 +9,19 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.ECKey; import org.aion.crypto.ed25519.ECKeyEd25519; import org.aion.crypto.ed25519.Ed25519Signature; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; -import org.aion.mcf.vm.types.DataWord; import org.aion.mcf.vm.types.DoubleDataWord; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; import org.aion.precompiled.type.StatefulPrecompiledContract; -import org.aion.vm.api.interfaces.Address; import org.apache.commons.collections4.map.LRUMap; /** @@ -48,19 +47,19 @@ public class AionNameServiceContract extends StatefulPrecompiledContract { private static final String ALL_ADDR_COUNTER_KEY = "allAddressKey"; private Address activeDomainsAddress = - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000600"); + Address.wrap("0000000000000000000000000000000000000000000000000000000000000600"); private Address activeDomainsAddressTime = - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000601"); + Address.wrap("0000000000000000000000000000000000000000000000000000000000000601"); private Address activeDomainsAddressValue = - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000603"); + Address.wrap("0000000000000000000000000000000000000000000000000000000000000603"); private Address allAddresses = - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000800"); + Address.wrap("0000000000000000000000000000000000000000000000000000000000000800"); private Address domainAddressNamePair = - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000802"); + Address.wrap("0000000000000000000000000000000000000000000000000000000000000802"); private Address registeredDomainAddressName = - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000803"); + Address.wrap("0000000000000000000000000000000000000000000000000000000000000803"); private Address registeredDomainNameAddress = - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000804"); + Address.wrap("0000000000000000000000000000000000000000000000000000000000000804"); private Address address; private Address ownerAddress; @@ -74,7 +73,7 @@ public class AionNameServiceContract extends StatefulPrecompiledContract { /** Construct a new ANS Contract */ public AionNameServiceContract( - IRepositoryCache> track, + RepositoryCache> track, Address address, Address ownerAddress) { // byte super(track); @@ -91,7 +90,7 @@ public AionNameServiceContract( if (!(getOwnerAddress().equals(ownerAddress)) && !(getOwnerAddress() .equals( - AionAddress.wrap( + Address.wrap( "0000000000000000000000000000000000000000000000000000000000000000")))) { throw new IllegalArgumentException( "The owner address of this domain from repository is different than the given" @@ -184,7 +183,7 @@ public PrecompiledTransactionResult execute(byte[] input, long nrg) { } // verify public key matches owner - if (!this.ownerAddress.equals(AionAddress.wrap(sig.getAddress()))) { + if (!this.ownerAddress.equals(Address.wrap(sig.getAddress()))) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); } @@ -231,7 +230,7 @@ private PrecompiledTransactionResult setResolver( // set the key byte[] combined = combineTwoBytes(hash1, hash2); - this.resolverAddressKey = new AionAddress(combined); + this.resolverAddressKey = new Address(combined); return new PrecompiledTransactionResult(PrecompiledResultCode.SUCCESS, nrg - SET_COST); } @@ -246,7 +245,7 @@ private PrecompiledTransactionResult setTTL( // set the key byte[] combined = combineTwoBytes(hash1, hash2); - this.TTLKey = new AionAddress(combined); + this.TTLKey = new Address(combined); return new PrecompiledTransactionResult(PrecompiledResultCode.SUCCESS, nrg - SET_COST); } @@ -257,15 +256,15 @@ private PrecompiledTransactionResult transferOwnership( if (nrg < TRANSFER_COST) return new PrecompiledTransactionResult(PrecompiledResultCode.OUT_OF_NRG, 0); - if (!isValidOwnerAddress(AionAddress.wrap(combineTwoBytes(addr1, addr2)))) + if (!isValidOwnerAddress(Address.wrap(combineTwoBytes(addr1, addr2)))) return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, nrg); - AionAddress.wrap(combineTwoBytes(addr1, addr2)); + Address.wrap(combineTwoBytes(addr1, addr2)); storeResult(hash1, hash2, addr1, addr2); // set the key byte[] combined = combineTwoBytes(hash1, hash2); - this.ownerAddressKey = new AionAddress(combined); + this.ownerAddressKey = new Address(combined); return new PrecompiledTransactionResult(PrecompiledResultCode.SUCCESS, nrg - TRANSFER_COST); } @@ -282,16 +281,16 @@ private PrecompiledTransactionResult transferSubdomainOwnership( if (nrg < TRANSFER_COST) return new PrecompiledTransactionResult(PrecompiledResultCode.OUT_OF_NRG, 0); - if (!isValidOwnerAddress(AionAddress.wrap(combineTwoBytes(addr1, addr2)))) + if (!isValidOwnerAddress(Address.wrap(combineTwoBytes(addr1, addr2)))) return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, nrg); - Address sdAddress = AionAddress.wrap(subdomainAddress); + Address sdAddress = Address.wrap(subdomainAddress); if (isSubdomain(subdomain)) { this.track.addStorageRow( - sdAddress, new DataWord(hash1).toWrapper(), new DataWord(addr1).toWrapper()); + sdAddress, new DataWordImpl(hash1).toWrapper(), new DataWordImpl(addr1).toWrapper()); this.track.addStorageRow( - sdAddress, new DataWord(hash2).toWrapper(), new DataWord(addr2).toWrapper()); + sdAddress, new DataWordImpl(hash2).toWrapper(), new DataWordImpl(addr2).toWrapper()); return new PrecompiledTransactionResult( PrecompiledResultCode.SUCCESS, nrg - TRANSFER_COST); } @@ -319,9 +318,9 @@ private void setUpKeys() { byte[] combined2 = combineTwoBytes(TTLHash1, TTLHash2); byte[] combined3 = combineTwoBytes(ownerHash1, ownerHash2); - this.resolverAddressKey = new AionAddress(combined); - this.TTLKey = new AionAddress(combined2); - this.ownerAddressKey = new AionAddress(combined3); + this.resolverAddressKey = new Address(combined); + this.TTLKey = new Address(combined2); + this.ownerAddressKey = new Address(combined3); } private byte[] combineTwoBytes(byte[] byte1, byte[] byte2) { @@ -333,9 +332,9 @@ private byte[] combineTwoBytes(byte[] byte1, byte[] byte2) { private void storeResult(byte[] hash1, byte[] hash2, byte[] addr1, byte[] addr2) { this.track.addStorageRow( - this.address, new DataWord(hash1).toWrapper(), new DataWord(addr1).toWrapper()); + this.address, new DataWordImpl(hash1).toWrapper(), new DataWordImpl(addr1).toWrapper()); this.track.addStorageRow( - this.address, new DataWord(hash2).toWrapper(), new DataWord(addr2).toWrapper()); + this.address, new DataWordImpl(hash2).toWrapper(), new DataWordImpl(addr2).toWrapper()); } private Address getValueFromStorage(Address key) { @@ -347,15 +346,15 @@ private Address getValueFromStorage(Address key) { System.arraycopy(byteKey, 16, key2, 0, 16); ByteArrayWrapper data1 = - this.track.getStorageValue(this.address, new DataWord(key1).toWrapper()); + this.track.getStorageValue(this.address, new DataWordImpl(key1).toWrapper()); ByteArrayWrapper data2 = - this.track.getStorageValue(this.address, new DataWord(key2).toWrapper()); + this.track.getStorageValue(this.address, new DataWordImpl(key2).toWrapper()); byte[] addr1 = data1.getData(); byte[] addr2 = data2.getData(); byte[] addrCombined = combineTwoBytes(addr1, addr2); - return (new AionAddress(addrCombined)); + return (new Address(addrCombined)); } private void addToRegistered(Address domainAddress, String domainName) { @@ -377,22 +376,22 @@ private void addToRegistered(Address domainAddress, String domainName) { // store name -> address pair this.track.addStorageRow( registeredDomainNameAddress, - new DataWord(blake128(domainName.getBytes())).toWrapper(), - new DataWord(addressFirstPart).toWrapper()); + new DataWordImpl(blake128(domainName.getBytes())).toWrapper(), + new DataWordImpl(addressFirstPart).toWrapper()); this.track.addStorageRow( registeredDomainNameAddress, - new DataWord(blake128(blake128(domainName.getBytes()))).toWrapper(), - new DataWord(addressSecondPart).toWrapper()); + new DataWordImpl(blake128(blake128(domainName.getBytes()))).toWrapper(), + new DataWordImpl(addressSecondPart).toWrapper()); // store address -> name pair this.track.addStorageRow( registeredDomainAddressName, - new DataWord(blake128(domainAddress.toBytes())).toWrapper(), - new DataWord(nameFirstPart).toWrapper()); + new DataWordImpl(blake128(domainAddress.toBytes())).toWrapper(), + new DataWordImpl(nameFirstPart).toWrapper()); this.track.addStorageRow( registeredDomainAddressName, - new DataWord(blake128(blake128(domainAddress.toBytes()))).toWrapper(), - new DataWord(nameSecondPart).toWrapper()); + new DataWordImpl(blake128(blake128(domainAddress.toBytes()))).toWrapper(), + new DataWordImpl(nameSecondPart).toWrapper()); } private boolean isSubdomain(String subdomainName) { @@ -444,13 +443,13 @@ private boolean isAvailableDomain(Address domainAddress, Address ownerAddress) { ByteArrayWrapper addrFirstPart = this.track.getStorageValue( activeDomainsAddress, - new DataWord(blake128(domainAddress.toBytes())).toWrapper()); + new DataWordImpl(blake128(domainAddress.toBytes())).toWrapper()); ByteArrayWrapper addrSecondPart = this.track.getStorageValue( activeDomainsAddress, - new DataWord(blake128(blake128(domainAddress.toBytes()))).toWrapper()); + new DataWordImpl(blake128(blake128(domainAddress.toBytes()))).toWrapper()); Address addrFromRepo = - AionAddress.wrap( + Address.wrap( combineTwoBytes(addrFirstPart.getData(), addrSecondPart.getData())); return addrFromRepo.equals(ownerAddress); @@ -517,11 +516,11 @@ private String getDomainNameFromAddress(Address domainAddress) { ByteArrayWrapper nameFirstPartData = this.track.getStorageValue( domainAddressNamePair, - new DataWord(blake128(domainAddress.toBytes())).toWrapper()); + new DataWordImpl(blake128(domainAddress.toBytes())).toWrapper()); ByteArrayWrapper nameSecondPartData = this.track.getStorageValue( domainAddressNamePair, - new DataWord(blake128(blake128(domainAddress.toBytes()))).toWrapper()); + new DataWordImpl(blake128(blake128(domainAddress.toBytes()))).toWrapper()); byte[] nameData = trimLeadingZeros( combineTwoBytes(nameFirstPartData.getData(), nameSecondPartData.getData())); @@ -540,7 +539,7 @@ private List getAllActiveDomains() { ByteArrayWrapper numberOfDomainsTotalData = this.track.getStorageValue( allAddresses, - new DataWord(blake128(ALL_ADDR_COUNTER_KEY.getBytes())).toWrapper()); + new DataWordImpl(blake128(ALL_ADDR_COUNTER_KEY.getBytes())).toWrapper()); BigInteger numberOfDomainsTotal = new BigInteger(numberOfDomainsTotalData.getData()); int counter = numberOfDomainsTotal.intValue(); @@ -551,43 +550,43 @@ private List getAllActiveDomains() { byte[] secondHash = blake128(blake128((ALL_ADDR_KEY + i).getBytes())); byte[] addrFirstPart = this.track - .getStorageValue(allAddresses, new DataWord(firstHash).toWrapper()) + .getStorageValue(allAddresses, new DataWordImpl(firstHash).toWrapper()) .getData(); byte[] addrSecondPart = this.track - .getStorageValue(allAddresses, new DataWord(secondHash).toWrapper()) + .getStorageValue(allAddresses, new DataWordImpl(secondHash).toWrapper()) .getData(); Address tempDomainAddr = - AionAddress.wrap(combineTwoBytes(addrFirstPart, addrSecondPart)); + Address.wrap(combineTwoBytes(addrFirstPart, addrSecondPart)); // if domain exists if (!this.track .getStorageValue( activeDomainsAddress, - new DataWord(blake128(tempDomainAddr.toBytes())).toWrapper()) + new DataWordImpl(blake128(tempDomainAddr.toBytes())).toWrapper()) .equals(DoubleDataWord.ZERO.toWrapper())) { byte[] ownerAddrFirstPart = this.track .getStorageValue( activeDomainsAddress, - new DataWord(blake128(tempDomainAddr.toBytes())) + new DataWordImpl(blake128(tempDomainAddr.toBytes())) .toWrapper()) .getData(); byte[] ownerAddrSecondPart = this.track .getStorageValue( activeDomainsAddress, - new DataWord(blake128(blake128(tempDomainAddr.toBytes()))) + new DataWordImpl(blake128(blake128(tempDomainAddr.toBytes()))) .toWrapper()) .getData(); Address tempOwnerAddr = - AionAddress.wrap(combineTwoBytes(ownerAddrFirstPart, ownerAddrSecondPart)); + Address.wrap(combineTwoBytes(ownerAddrFirstPart, ownerAddrSecondPart)); byte[] expireDateData = this.track .getStorageValue( activeDomainsAddressTime, - new DataWord(blake128(tempDomainAddr.toBytes())) + new DataWordImpl(blake128(tempDomainAddr.toBytes())) .toWrapper()) .getData(); byte[] trimmedExpireDateData = trimLeadingZeros16(expireDateData); @@ -603,14 +602,14 @@ private List getAllActiveDomains() { this.track .getStorageValue( domainAddressNamePair, - new DataWord(blake128(tempDomainAddr.toBytes())) + new DataWordImpl(blake128(tempDomainAddr.toBytes())) .toWrapper()) .getData(); byte[] domainNameSecondPart = this.track .getStorageValue( domainAddressNamePair, - new DataWord(blake128(blake128(tempDomainAddr.toBytes()))) + new DataWordImpl(blake128(blake128(tempDomainAddr.toBytes()))) .toWrapper()) .getData(); String tempDomainName = null; @@ -630,7 +629,7 @@ private List getAllActiveDomains() { this.track .getStorageValue( activeDomainsAddressValue, - new DataWord(blake128(tempDomainAddr.toBytes())) + new DataWordImpl(blake128(tempDomainAddr.toBytes())) .toWrapper()) .getData(); BigInteger tempValue = new BigInteger(valueData); @@ -669,7 +668,7 @@ public void displayAllActiveDomains() { } public void displayMyDomains(ECKey key) { - Address callerAddress = AionAddress.wrap(key.getAddress()); + Address callerAddress = Address.wrap(key.getAddress()); System.out.println( "----------------------------AION NAME SERVICE QUERY: displayMyDomains-----------------------------"); @@ -725,13 +724,13 @@ public String getRegisteredDomainName(Address domainAddress) { this.track .getStorageValue( domainAddressNamePair, - new DataWord(blake128(domainAddress.toBytes())).toWrapper()) + new DataWordImpl(blake128(domainAddress.toBytes())).toWrapper()) .getData(); byte[] domainNameSecondPart = this.track .getStorageValue( domainAddressNamePair, - new DataWord(blake128(blake128(domainAddress.toBytes()))) + new DataWordImpl(blake128(blake128(domainAddress.toBytes()))) .toWrapper()) .getData(); String domainName; @@ -756,16 +755,16 @@ public Address getRegisteredDomainAddress(String domainName) { this.track .getStorageValue( registeredDomainNameAddress, - new DataWord(blake128(domainName.getBytes())).toWrapper()) + new DataWordImpl(blake128(domainName.getBytes())).toWrapper()) .getData(); byte[] addressSecondPart = this.track .getStorageValue( registeredDomainNameAddress, - new DataWord(blake128(blake128(domainName.getBytes()))).toWrapper()) + new DataWordImpl(blake128(blake128(domainName.getBytes()))).toWrapper()) .getData(); - AionAddress domainAddress = - AionAddress.wrap(combineTwoBytes(addressFirstPart, addressSecondPart)); + Address domainAddress = + Address.wrap(combineTwoBytes(addressFirstPart, addressSecondPart)); if (domainAddress.isZeroAddress()) return null; return domainAddress; } diff --git a/modPrecompiled/src/org/aion/precompiled/contracts/EDVerifyContract.java b/modPrecompiled/src/org/aion/precompiled/contracts/EDVerifyContract.java index c83718116b..1799d7cc84 100644 --- a/modPrecompiled/src/org/aion/precompiled/contracts/EDVerifyContract.java +++ b/modPrecompiled/src/org/aion/precompiled/contracts/EDVerifyContract.java @@ -1,6 +1,6 @@ package org.aion.precompiled.contracts; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.crypto.ed25519.ECKeyEd25519; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; @@ -43,7 +43,7 @@ public PrecompiledTransactionResult execute(byte[] input, long nrgLimit) { return new PrecompiledTransactionResult( PrecompiledResultCode.SUCCESS, nrgLimit - COST, - verify ? pubKey : AionAddress.ZERO_ADDRESS().toBytes()); + verify ? pubKey : Address.ZERO_ADDRESS().toBytes()); } catch (Exception e) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); } diff --git a/modPrecompiled/src/org/aion/precompiled/contracts/MultiSignatureContract.java b/modPrecompiled/src/org/aion/precompiled/contracts/MultiSignatureContract.java index 28249317f7..7c80001d0c 100644 --- a/modPrecompiled/src/org/aion/precompiled/contracts/MultiSignatureContract.java +++ b/modPrecompiled/src/org/aion/precompiled/contracts/MultiSignatureContract.java @@ -7,9 +7,10 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.AddressSpecs; import org.aion.crypto.HashUtil; import org.aion.crypto.ISignature; @@ -17,11 +18,9 @@ import org.aion.crypto.ed25519.Ed25519Signature; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; -import org.aion.mcf.vm.types.DataWord; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; import org.aion.precompiled.type.StatefulPrecompiledContract; -import org.aion.vm.api.interfaces.Address; /** * An N of M implementation of a multi-signature pre-compiled contract. @@ -59,7 +58,7 @@ public final class MultiSignatureContract extends StatefulPrecompiledContract { * @throws IllegalArgumentException if track or caller are null. */ public MultiSignatureContract( - IRepositoryCache> track, Address caller) { + RepositoryCache> track, Address caller) { super(track); if (caller == null) { @@ -308,10 +307,10 @@ private PrecompiledTransactionResult sendTransaction(byte[] input, long nrg) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); } - Address wallet = new AionAddress(Arrays.copyOfRange(input, walletStart, sigsStart)); + Address wallet = new Address(Arrays.copyOfRange(input, walletStart, sigsStart)); List sigs = extractSignatures(Arrays.copyOfRange(input, sigsStart, amountStart)); BigInteger amount = new BigInteger(Arrays.copyOfRange(input, amountStart, nrgStart)); - Address recipient = new AionAddress(Arrays.copyOfRange(input, recipientStart, length)); + Address recipient = new Address(Arrays.copyOfRange(input, recipientStart, length)); ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); buffer.put(Arrays.copyOfRange(input, nrgStart, recipientStart)); @@ -321,7 +320,7 @@ private PrecompiledTransactionResult sendTransaction(byte[] input, long nrg) { if (!isValidTxNrg(nrg)) { return new PrecompiledTransactionResult(PrecompiledResultCode.INVALID_NRG_LIMIT, nrg); } - if (track.getStorageValue(wallet, new DataWord(getMetaDataKey()).toWrapper()) == null) { + if (track.getStorageValue(wallet, new DataWordImpl(getMetaDataKey()).toWrapper()) == null) { // Then wallet is not the address of a multi-sig wallet. return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); } @@ -374,11 +373,11 @@ private Set

    extractAddresses(byte[] addresses) { Address addr; boolean addressIsOwner = false; for (int i = 0; i < length; i += ADDR_LEN) { - addr = new AionAddress(Arrays.copyOfRange(addresses, i, i + ADDR_LEN)); + addr = new Address(Arrays.copyOfRange(addresses, i, i + ADDR_LEN)); if (result.contains(addr)) { return null; } - if (track.getStorageValue(addr, new DataWord(getMetaDataKey()).toWrapper()) != null) { + if (track.getStorageValue(addr, new DataWordImpl(getMetaDataKey()).toWrapper()) != null) { return null; } if (addr.equals(this.caller)) { @@ -454,7 +453,7 @@ private Address initNewWallet(Set
    owners, long threshold) { byte[] hash = HashUtil.keccak256(content); hash[0] = AION_PREFIX; - Address walletId = new AionAddress(hash); + Address walletId = new Address(hash); track.createAccount(walletId); saveWalletMetaData(walletId, threshold, owners.size()); saveWalletOwners(walletId, owners); @@ -478,7 +477,7 @@ private Address initNewWallet(Set
    owners, long threshold) { */ private void saveWalletMetaData(Address walletId, long threshold, long numOwners) { byte[] metaKey = getMetaDataKey(); - byte[] metaValue = new byte[DataWord.BYTES]; + byte[] metaValue = new byte[DataWordImpl.BYTES]; ByteBuffer data = ByteBuffer.allocate(Long.BYTES); data.putLong(threshold); @@ -489,7 +488,7 @@ private void saveWalletMetaData(Address walletId, long threshold, long numOwners System.arraycopy(data.array(), 0, metaValue, Long.BYTES, Long.BYTES); track.addStorageRow( - walletId, new DataWord(metaKey).toWrapper(), new DataWord(metaValue).toWrapper()); + walletId, new DataWordImpl(metaKey).toWrapper(), new DataWordImpl(metaValue).toWrapper()); } /** @@ -515,19 +514,19 @@ private void saveWalletOwners(Address walletId, Set
    owners) { secondKey = getOwnerDataKey(false, count); // set the two values for this owner. - firstValue = new byte[DataWord.BYTES]; - secondValue = new byte[DataWord.BYTES]; - System.arraycopy(owner.toBytes(), 0, firstValue, 0, DataWord.BYTES); - System.arraycopy(owner.toBytes(), DataWord.BYTES, secondValue, 0, DataWord.BYTES); + firstValue = new byte[DataWordImpl.BYTES]; + secondValue = new byte[DataWordImpl.BYTES]; + System.arraycopy(owner.toBytes(), 0, firstValue, 0, DataWordImpl.BYTES); + System.arraycopy(owner.toBytes(), DataWordImpl.BYTES, secondValue, 0, DataWordImpl.BYTES); track.addStorageRow( walletId, - new DataWord(firstKey).toWrapper(), - new DataWord(firstValue).toWrapper()); + new DataWordImpl(firstKey).toWrapper(), + new DataWordImpl(firstValue).toWrapper()); track.addStorageRow( walletId, - new DataWord(secondKey).toWrapper(), - new DataWord(secondValue).toWrapper()); + new DataWordImpl(secondKey).toWrapper(), + new DataWordImpl(secondValue).toWrapper()); count++; } } @@ -558,7 +557,7 @@ private boolean areValidSignatures(Address wallet, List signatures, byte if (!signatureIsCorrect(sig, msg)) { return false; } - signer = new AionAddress(AddressSpecs.computeA0Address(Arrays.copyOfRange(sig, 0, 32))); + signer = new Address(AddressSpecs.computeA0Address(Arrays.copyOfRange(sig, 0, 32))); if (txSigners.contains(signer)) { return false; } @@ -569,7 +568,7 @@ private boolean areValidSignatures(Address wallet, List signatures, byte } ByteArrayWrapper metaValue = - track.getStorageValue(wallet, new DataWord(getMetaDataKey()).toWrapper()); + track.getStorageValue(wallet, new DataWordImpl(getMetaDataKey()).toWrapper()); ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); buffer.put(Arrays.copyOfRange(metaValue.getData(), 0, Long.BYTES)); buffer.flip(); @@ -603,9 +602,9 @@ private Set
    getOwners(Address walletId) { Set
    owners = new HashSet<>(); ByteArrayWrapper metaValue = - track.getStorageValue(walletId, new DataWord(getMetaDataKey()).toWrapper()); + track.getStorageValue(walletId, new DataWordImpl(getMetaDataKey()).toWrapper()); ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); - buffer.put(Arrays.copyOfRange(metaValue.getData(), Long.BYTES, DataWord.BYTES)); + buffer.put(Arrays.copyOfRange(metaValue.getData(), Long.BYTES, DataWordImpl.BYTES)); buffer.flip(); long numOwners = buffer.getLong(); @@ -631,14 +630,14 @@ private Address getOwner(Address walletId, long ownerId) { byte[] ownerDataKey1 = getOwnerDataKey(true, ownerId); ByteArrayWrapper addrPortion = - track.getStorageValue(walletId, new DataWord(ownerDataKey1).toWrapper()); - System.arraycopy(addrPortion.getData(), 0, address, 0, DataWord.BYTES); + track.getStorageValue(walletId, new DataWordImpl(ownerDataKey1).toWrapper()); + System.arraycopy(addrPortion.getData(), 0, address, 0, DataWordImpl.BYTES); byte[] ownerDataKey2 = getOwnerDataKey(false, ownerId); - addrPortion = track.getStorageValue(walletId, new DataWord(ownerDataKey2).toWrapper()); - System.arraycopy(addrPortion.getData(), 0, address, DataWord.BYTES, DataWord.BYTES); + addrPortion = track.getStorageValue(walletId, new DataWordImpl(ownerDataKey2).toWrapper()); + System.arraycopy(addrPortion.getData(), 0, address, DataWordImpl.BYTES, DataWordImpl.BYTES); - return new AionAddress(address); + return new Address(address); } /** @@ -647,7 +646,7 @@ private Address getOwner(Address walletId, long ownerId) { * @return the meta data query key. */ private static byte[] getMetaDataKey() { - byte[] metaKey = new byte[DataWord.BYTES]; + byte[] metaKey = new byte[DataWordImpl.BYTES]; metaKey[0] = (byte) 0x80; return metaKey; } @@ -660,13 +659,13 @@ private static byte[] getMetaDataKey() { * @return the owner data query key. */ private static byte[] getOwnerDataKey(boolean isFirstHalf, long ownerId) { - byte[] ownerKey = new byte[DataWord.BYTES]; + byte[] ownerKey = new byte[DataWordImpl.BYTES]; if (!isFirstHalf) { ownerKey[0] = (byte) 0x40; } ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); buffer.putLong(ownerId); - System.arraycopy(buffer.array(), 0, ownerKey, DataWord.BYTES - Long.BYTES, Long.BYTES); + System.arraycopy(buffer.array(), 0, ownerKey, DataWordImpl.BYTES - Long.BYTES, Long.BYTES); return ownerKey; } diff --git a/modPrecompiled/src/org/aion/precompiled/contracts/TRS/AbstractTRS.java b/modPrecompiled/src/org/aion/precompiled/contracts/TRS/AbstractTRS.java index 542ba7020a..3c57dc3711 100644 --- a/modPrecompiled/src/org/aion/precompiled/contracts/TRS/AbstractTRS.java +++ b/modPrecompiled/src/org/aion/precompiled/contracts/TRS/AbstractTRS.java @@ -6,18 +6,17 @@ import java.nio.ByteBuffer; import java.util.Arrays; import java.util.concurrent.TimeUnit; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.mcf.core.AccountState; import org.aion.mcf.core.IBlockchain; import org.aion.mcf.db.IBlockStoreBase; -import org.aion.mcf.vm.types.DataWord; import org.aion.mcf.vm.types.DoubleDataWord; import org.aion.precompiled.PrecompiledTransactionResult; import org.aion.precompiled.type.StatefulPrecompiledContract; -import org.aion.vm.api.interfaces.Address; +import org.aion.util.bytes.ByteUtil; /** * The purpose of this abstract class is mostly as a place to store important constants and methods @@ -26,7 +25,7 @@ public abstract class AbstractTRS extends StatefulPrecompiledContract { // TODO: grab AION from CfgAion later and preferably aion prefix too. static final Address AION = - AionAddress.wrap("0xa0eeaeabdbc92953b072afbd21f3e3fd8a4a4f5e6a6e22200db746ab75e9a99a"); + Address.wrap("0xa0eeaeabdbc92953b072afbd21f3e3fd8a4a4f5e6a6e22200db746ab75e9a99a"); static final long COST = 21000L; // temporary. private static final long TEST_DURATION = 1; private static final long PERIOD_DURATION = TimeUnit.DAYS.toSeconds(30); @@ -60,7 +59,7 @@ public abstract class AbstractTRS extends StatefulPrecompiledContract { private static final byte EXTRA_FUNDS_PREFIX = (byte) 0x92; private static final int DOUBLE_WORD_SIZE = DoubleDataWord.BYTES; - private static final int SINGLE_WORD_SIZE = DataWord.BYTES; + private static final int SINGLE_WORD_SIZE = DataWordImpl.BYTES; private static final int MAX_DEPOSIT_ROWS = 16; private static final byte NULL_BIT = (byte) 0x80; private static final byte VALID_BIT = (byte) 0x40; @@ -101,7 +100,7 @@ public abstract class AbstractTRS extends StatefulPrecompiledContract { // Constructor. AbstractTRS( - IRepositoryCache> track, + RepositoryCache> track, Address caller, IBlockchain blockchain) { super(track); @@ -196,7 +195,7 @@ void setContractSpecs( */ public Address getContractOwner(Address contract) { ByteArrayWrapper owner = track.getStorageValue(contract, OWNER_KEY); - return (owner == null) ? null : new AionAddress(owner.getData()); + return (owner == null) ? null : new Address(owner.getData()); } /** @@ -739,11 +738,11 @@ public void setTimestamp(Address contract, long timestamp) { if (track.getStorageValue(contract, TIMESTAMP) != null) { return; } - byte[] value = new byte[DataWord.BYTES]; + byte[] value = new byte[DataWordImpl.BYTES]; ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); buffer.putLong(timestamp); - System.arraycopy(buffer.array(), 0, value, DataWord.BYTES - Long.BYTES, Long.BYTES); + System.arraycopy(buffer.array(), 0, value, DataWordImpl.BYTES - Long.BYTES, Long.BYTES); track.addStorageRow(contract, TIMESTAMP, toByteArrayWrapper(value)); } @@ -764,7 +763,7 @@ public long getTimestamp(Address contract) { } ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); buffer.put( - Arrays.copyOfRange(value.getData(), DataWord.BYTES - Long.BYTES, DataWord.BYTES)); + Arrays.copyOfRange(value.getData(), DataWordImpl.BYTES - Long.BYTES, DataWordImpl.BYTES)); buffer.flip(); return buffer.getLong(); } @@ -1671,7 +1670,7 @@ private byte[] makeTotalBalanceKey(int row) { */ private byte[] makeBalanceKey(Address account, int row) { if (account == null) { - return DataWord.ZERO.getData(); + return DataWordImpl.ZERO.getData(); } byte[] balKey = new byte[DOUBLE_WORD_SIZE]; balKey[0] = (byte) (BALANCE_PREFIX | row); @@ -1689,7 +1688,7 @@ private byte[] makeBalanceKey(Address account, int row) { */ private byte[] makeWithdrawalKey(Address account) { if (account == null) { - return DataWord.ZERO.getData(); + return DataWordImpl.ZERO.getData(); } return makeWithdrawalKey(account.toBytes()); } @@ -1704,7 +1703,7 @@ private byte[] makeWithdrawalKey(Address account) { */ private byte[] makeWithdrawalKey(byte[] account) { if (account == null) { - return DataWord.ZERO.getData(); + return DataWordImpl.ZERO.getData(); } byte[] withKey = new byte[DOUBLE_WORD_SIZE]; withKey[0] = WITHDRAW_PREFIX; @@ -1751,7 +1750,7 @@ private byte[] toDoubleWordAlignedArray(BigInteger balance) { */ private static ByteArrayWrapper toByteArrayWrapper(byte[] word) { if (word.length == SINGLE_WORD_SIZE) { - return new DataWord(word).toWrapper(); + return new DataWordImpl(word).toWrapper(); } else if (word.length == DOUBLE_WORD_SIZE) { return new DoubleDataWord(word).toWrapper(); } else { diff --git a/modPrecompiled/src/org/aion/precompiled/contracts/TRS/PrivateTRScontract.java b/modPrecompiled/src/org/aion/precompiled/contracts/TRS/PrivateTRScontract.java index db5e28873d..df6c79ffe5 100644 --- a/modPrecompiled/src/org/aion/precompiled/contracts/TRS/PrivateTRScontract.java +++ b/modPrecompiled/src/org/aion/precompiled/contracts/TRS/PrivateTRScontract.java @@ -1,11 +1,11 @@ package org.aion.precompiled.contracts.TRS; -import org.aion.base.db.IRepositoryCache; +import org.aion.interfaces.db.RepositoryCache; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; import org.aion.precompiled.PrecompiledTransactionResult; import org.aion.precompiled.type.StatefulPrecompiledContract; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; /** * The PrivateTRScontract is a private version of the TRS contract that is used solely by The Aion @@ -30,7 +30,7 @@ public final class PrivateTRScontract extends StatefulPrecompiledContract { * @param caller The calling address. */ public PrivateTRScontract( - IRepositoryCache> repo, Address caller) { + RepositoryCache> repo, Address caller) { super(repo); this.caller = caller; diff --git a/modPrecompiled/src/org/aion/precompiled/contracts/TRS/TRSqueryContract.java b/modPrecompiled/src/org/aion/precompiled/contracts/TRS/TRSqueryContract.java index 095aca79c6..898d30f8ea 100644 --- a/modPrecompiled/src/org/aion/precompiled/contracts/TRS/TRSqueryContract.java +++ b/modPrecompiled/src/org/aion/precompiled/contracts/TRS/TRSqueryContract.java @@ -5,15 +5,15 @@ import java.math.RoundingMode; import java.nio.ByteBuffer; import java.util.Arrays; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.base.type.IBlock; + +import org.aion.interfaces.block.Block; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.types.Address; import org.aion.mcf.core.AccountState; import org.aion.mcf.core.IBlockchain; import org.aion.mcf.db.IBlockStoreBase; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; -import org.aion.vm.api.interfaces.Address; /** * The TRSqueryContract is 1 of 3 inter-dependent but separate contracts that together make up the @@ -48,7 +48,7 @@ public final class TRSqueryContract extends AbstractTRS { * @param caller The calling address. */ public TRSqueryContract( - IRepositoryCache> repo, + RepositoryCache> repo, Address caller, IBlockchain blockchain) { @@ -214,7 +214,7 @@ private PrecompiledTransactionResult isStarted(byte[] input, long nrgLimit) { } byte[] result = new byte[1]; - Address contract = AionAddress.wrap(Arrays.copyOfRange(input, indexAddress, len)); + Address contract = Address.wrap(Arrays.copyOfRange(input, indexAddress, len)); if (!isOpenFunds(contract) && isContractLive(contract)) { result[0] = 0x1; } @@ -247,7 +247,7 @@ private PrecompiledTransactionResult isLocked(byte[] input, long nrgLimit) { } byte[] result = new byte[1]; - Address contract = AionAddress.wrap(Arrays.copyOfRange(input, indexAddress, len)); + Address contract = Address.wrap(Arrays.copyOfRange(input, indexAddress, len)); if (!isOpenFunds(contract) && isContractLocked(contract)) { result[0] = 0x1; } @@ -281,7 +281,7 @@ private PrecompiledTransactionResult isDirectDepositEnabled(byte[] input, long n } byte[] result = new byte[1]; - Address contract = AionAddress.wrap(Arrays.copyOfRange(input, indexAddress, len)); + Address contract = Address.wrap(Arrays.copyOfRange(input, indexAddress, len)); if (!isOpenFunds(contract) && isDirDepositsEnabled(contract)) { result[0] = 0x1; } @@ -322,7 +322,7 @@ private PrecompiledTransactionResult period(byte[] input, long nrgLimit) { } // Grab the contract address and block number and determine the period. - Address contract = AionAddress.wrap(Arrays.copyOfRange(input, indexAddress, len)); + Address contract = Address.wrap(Arrays.copyOfRange(input, indexAddress, len)); return determinePeriod(contract, blockchain.getBestBlock(), nrgLimit); } @@ -360,7 +360,7 @@ private PrecompiledTransactionResult periodAt(byte[] input, long nrgLimit) { } // Grab the contract address and block number and determine the period. - Address contract = AionAddress.wrap(Arrays.copyOfRange(input, indexAddress, indexBlockNum)); + Address contract = Address.wrap(Arrays.copyOfRange(input, indexAddress, indexBlockNum)); ByteBuffer blockBuf = ByteBuffer.allocate(Long.BYTES); blockBuf.put(Arrays.copyOfRange(input, indexBlockNum, len)); @@ -405,7 +405,7 @@ private PrecompiledTransactionResult availableForWithdrawalAt(byte[] input, long } Address contract = - AionAddress.wrap(Arrays.copyOfRange(input, indexContract, indexTimestamp)); + Address.wrap(Arrays.copyOfRange(input, indexContract, indexTimestamp)); byte[] specs = getContractSpecs(contract); if (specs == null) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); @@ -478,7 +478,7 @@ private PrecompiledTransactionResult availableForWithdrawalAt(byte[] input, long * @param nrg The energy. * @return the period the contract is in at time given by block's timestamp. */ - private PrecompiledTransactionResult determinePeriod(Address contract, IBlock block, long nrg) { + private PrecompiledTransactionResult determinePeriod(Address contract, Block block, long nrg) { // If contract doesn't exist, return an error. ByteBuffer output = ByteBuffer.allocate(Integer.BYTES); diff --git a/modPrecompiled/src/org/aion/precompiled/contracts/TRS/TRSstateContract.java b/modPrecompiled/src/org/aion/precompiled/contracts/TRS/TRSstateContract.java index bcbb3c11bc..c9c384fe9e 100644 --- a/modPrecompiled/src/org/aion/precompiled/contracts/TRS/TRSstateContract.java +++ b/modPrecompiled/src/org/aion/precompiled/contracts/TRS/TRSstateContract.java @@ -4,15 +4,14 @@ import java.math.BigInteger; import java.util.Arrays; import java.util.concurrent.TimeUnit; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.types.Address; import org.aion.crypto.HashUtil; import org.aion.mcf.core.AccountState; import org.aion.mcf.core.IBlockchain; import org.aion.mcf.db.IBlockStoreBase; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; -import org.aion.vm.api.interfaces.Address; /** * The TRSstateContract is 1 of 3 inter-dependent but separate contracts that together make up the @@ -45,7 +44,7 @@ public final class TRSstateContract extends AbstractTRS { * @throws NullPointerException if track or caller are null. */ public TRSstateContract( - IRepositoryCache> track, + RepositoryCache> track, Address caller, IBlockchain blockchain) { @@ -239,7 +238,7 @@ private PrecompiledTransactionResult create(byte[] input, long nrgLimit) { System.arraycopy(caller.toBytes(), 0, hashInfo, ownerNonce.length, Address.SIZE); byte[] trsAddr = HashUtil.h256(hashInfo); trsAddr[0] = TRS_PREFIX; - Address contract = new AionAddress(trsAddr); + Address contract = new Address(trsAddr); saveNewContract(contract, isTestContract, isDirectDeposit, periods, percent, precision); return new PrecompiledTransactionResult( @@ -274,7 +273,7 @@ private PrecompiledTransactionResult lock(byte[] input, long nrgLimit) { // The caller must also be the owner of this contract. Address contract = - new AionAddress(Arrays.copyOfRange(input, indexAddr, indexAddr + Address.SIZE)); + new Address(Arrays.copyOfRange(input, indexAddr, indexAddr + Address.SIZE)); if (!caller.equals(getContractOwner(contract))) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); } @@ -329,7 +328,7 @@ private PrecompiledTransactionResult start(byte[] input, long nrgLimit) { // The caller must also be the owner of this contract. Address contract = - new AionAddress(Arrays.copyOfRange(input, indexAddr, indexAddr + Address.SIZE)); + new Address(Arrays.copyOfRange(input, indexAddr, indexAddr + Address.SIZE)); if (!caller.equals(getContractOwner(contract))) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); } @@ -379,7 +378,7 @@ private PrecompiledTransactionResult openFunds(byte[] input, long nrgLimit) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); } - Address contract = AionAddress.wrap(Arrays.copyOfRange(input, indexContract, len)); + Address contract = Address.wrap(Arrays.copyOfRange(input, indexContract, len)); byte[] specs = getContractSpecs(contract); if (specs == null) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); diff --git a/modPrecompiled/src/org/aion/precompiled/contracts/TRS/TRSuseContract.java b/modPrecompiled/src/org/aion/precompiled/contracts/TRS/TRSuseContract.java index 28b2506c11..3d1a78d1da 100644 --- a/modPrecompiled/src/org/aion/precompiled/contracts/TRS/TRSuseContract.java +++ b/modPrecompiled/src/org/aion/precompiled/contracts/TRS/TRSuseContract.java @@ -2,14 +2,13 @@ import java.math.BigInteger; import java.util.Arrays; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.types.Address; import org.aion.mcf.core.AccountState; import org.aion.mcf.core.IBlockchain; import org.aion.mcf.db.IBlockStoreBase; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; -import org.aion.vm.api.interfaces.Address; /** * The TRSuseContract is 1 of 3 inter-dependent but separate contracts that together make up the @@ -45,7 +44,7 @@ public final class TRSuseContract extends AbstractTRS { * @param caller The calling address. */ public TRSuseContract( - IRepositoryCache> repo, + RepositoryCache> repo, Address caller, IBlockchain blockchain) { @@ -253,7 +252,7 @@ private PrecompiledTransactionResult deposit(byte[] input, long nrgLimit) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); } - Address contract = AionAddress.wrap(Arrays.copyOfRange(input, indexAddress, indexAmount)); + Address contract = Address.wrap(Arrays.copyOfRange(input, indexAddress, indexAmount)); byte[] specs = getContractSpecs(contract); if (specs == null) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); @@ -314,7 +313,7 @@ private PrecompiledTransactionResult withdraw(byte[] input, long nrgLimit) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); } - Address contract = AionAddress.wrap(Arrays.copyOfRange(input, indexAddress, len)); + Address contract = Address.wrap(Arrays.copyOfRange(input, indexAddress, len)); byte[] specs = getContractSpecs(contract); if (specs == null) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); @@ -374,7 +373,7 @@ private PrecompiledTransactionResult bulkDepositFor(byte[] input, long nrgLimit) return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); } - Address contract = AionAddress.wrap(Arrays.copyOfRange(input, indexContract, indexEntries)); + Address contract = Address.wrap(Arrays.copyOfRange(input, indexContract, indexEntries)); byte[] specs = getContractSpecs(contract); if (specs == null) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); @@ -397,7 +396,7 @@ private PrecompiledTransactionResult bulkDepositFor(byte[] input, long nrgLimit) int amtLen = entryLen - entryAddrLen; int index = indexEntries; byte[] amountBytes; - Address[] beneficiaries = new AionAddress[numEntries]; + Address[] beneficiaries = new Address[numEntries]; BigInteger[] amounts = new BigInteger[numEntries]; for (int i = 0; i < numEntries; i++) { // Put amount in a byte array one byte larger with an empty initial byte so it is @@ -412,7 +411,7 @@ private PrecompiledTransactionResult bulkDepositFor(byte[] input, long nrgLimit) } beneficiaries[i] = - AionAddress.wrap(Arrays.copyOfRange(input, index, index + entryAddrLen)); + Address.wrap(Arrays.copyOfRange(input, index, index + entryAddrLen)); index += 32 + 128; } @@ -458,7 +457,7 @@ private PrecompiledTransactionResult bulkWithdraw(byte[] input, long nrgLimit) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); } - Address contract = AionAddress.wrap(Arrays.copyOfRange(input, indexAddress, len)); + Address contract = Address.wrap(Arrays.copyOfRange(input, indexAddress, len)); byte[] specs = getContractSpecs(contract); if (specs == null) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); @@ -483,7 +482,7 @@ private PrecompiledTransactionResult bulkWithdraw(byte[] input, long nrgLimit) { while (curr != null) { curr[0] = AION_PREFIX; - Address currAcct = new AionAddress(curr); + Address currAcct = new Address(curr); makeWithdrawal(contract, currAcct); curr = getListNext(contract, currAcct); } @@ -524,7 +523,7 @@ private PrecompiledTransactionResult refund(byte[] input, long nrgLimit) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); } - Address contract = AionAddress.wrap(Arrays.copyOfRange(input, indexContract, indexAccount)); + Address contract = Address.wrap(Arrays.copyOfRange(input, indexContract, indexAccount)); byte[] specs = getContractSpecs(contract); if (specs == null) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); @@ -544,7 +543,7 @@ private PrecompiledTransactionResult refund(byte[] input, long nrgLimit) { } // Ensure the account exists (ie. has a positive deposit balance for the contract). - Address account = AionAddress.wrap(Arrays.copyOfRange(input, indexAccount, indexAmount)); + Address account = Address.wrap(Arrays.copyOfRange(input, indexAccount, indexAmount)); BigInteger accountBalance = getDepositBalance(contract, account); if (accountBalance.equals(BigInteger.ZERO)) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); @@ -611,7 +610,7 @@ private PrecompiledTransactionResult depositFor(byte[] input, long nrgLimit) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); } - Address contract = AionAddress.wrap(Arrays.copyOfRange(input, indexContract, indexAccount)); + Address contract = Address.wrap(Arrays.copyOfRange(input, indexContract, indexAccount)); byte[] specs = getContractSpecs(contract); if (specs == null) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); @@ -645,7 +644,7 @@ private PrecompiledTransactionResult depositFor(byte[] input, long nrgLimit) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); } - Address account = AionAddress.wrap(Arrays.copyOfRange(input, indexAccount, indexAmount)); + Address account = Address.wrap(Arrays.copyOfRange(input, indexAccount, indexAmount)); PrecompiledTransactionResult result = makeDeposit(contract, account, amount, nrgLimit); if (result.getResultCode().equals(PrecompiledResultCode.SUCCESS)) { track.flush(); @@ -679,7 +678,7 @@ private PrecompiledTransactionResult addExtraFunds(byte[] input, long nrgLimit) return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); } - Address contract = AionAddress.wrap(Arrays.copyOfRange(input, indexContract, indexAmount)); + Address contract = Address.wrap(Arrays.copyOfRange(input, indexContract, indexAmount)); byte[] specs = getContractSpecs(contract); if (specs == null) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); @@ -793,7 +792,7 @@ private void listAddToHead(Address contract, Address account) { head[0] = AION_PREFIX; setListPrevious( contract, - AionAddress.wrap(head), + Address.wrap(head), Arrays.copyOf(account.toBytes(), Address.SIZE)); } diff --git a/modPrecompiled/src/org/aion/precompiled/contracts/TotalCurrencyContract.java b/modPrecompiled/src/org/aion/precompiled/contracts/TotalCurrencyContract.java index b281752ca4..3322d0ebf4 100644 --- a/modPrecompiled/src/org/aion/precompiled/contracts/TotalCurrencyContract.java +++ b/modPrecompiled/src/org/aion/precompiled/contracts/TotalCurrencyContract.java @@ -1,19 +1,18 @@ package org.aion.precompiled.contracts; import java.math.BigInteger; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.base.util.BIUtil; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.ed25519.ECKeyEd25519; import org.aion.crypto.ed25519.Ed25519Signature; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; -import org.aion.mcf.vm.types.DataWord; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; import org.aion.precompiled.type.StatefulPrecompiledContract; -import org.aion.vm.api.interfaces.Address; +import org.aion.util.biginteger.BIUtil; /** A pre-compiled contract for retrieving and updating the total amount of currency. */ public class TotalCurrencyContract extends StatefulPrecompiledContract { @@ -31,7 +30,7 @@ public class TotalCurrencyContract extends StatefulPrecompiledContract { * @param ownerAddress */ public TotalCurrencyContract( - IRepositoryCache> track, + RepositoryCache> track, Address address, Address ownerAddress) { super(track); @@ -97,7 +96,7 @@ private PrecompiledTransactionResult queryNetworkBalance(int input, long nrg) { } ByteArrayWrapper balanceData = - this.track.getStorageValue(this.address, new DataWord(input).toWrapper()); + this.track.getStorageValue(this.address, new DataWordImpl(input).toWrapper()); return new PrecompiledTransactionResult( PrecompiledResultCode.SUCCESS, nrg - COST, balanceData.getData()); } @@ -114,7 +113,7 @@ private PrecompiledTransactionResult executeUpdateTotalBalance(byte[] input, lon // process input data int offset = 0; - DataWord chainId = new DataWord(input[0]); + DataWordImpl chainId = new DataWordImpl(input[0]); offset++; byte signum = input[1]; @@ -142,7 +141,7 @@ private PrecompiledTransactionResult executeUpdateTotalBalance(byte[] input, lon } // verify public key matches owner - if (!this.ownerAddress.equals(AionAddress.wrap(sig.getAddress()))) { + if (!this.ownerAddress.equals(Address.wrap(sig.getAddress()))) { return new PrecompiledTransactionResult(PrecompiledResultCode.FAILURE, 0); } @@ -173,11 +172,11 @@ private PrecompiledTransactionResult executeUpdateTotalBalance(byte[] input, lon this.track.addStorageRow( this.address, chainId.toWrapper(), - wrapValueForPut(new DataWord(finalValue.toByteArray()))); + wrapValueForPut(new DataWordImpl(finalValue.toByteArray()))); return new PrecompiledTransactionResult(PrecompiledResultCode.SUCCESS, nrg - COST); } - private static ByteArrayWrapper wrapValueForPut(DataWord value) { + private static ByteArrayWrapper wrapValueForPut(DataWordImpl value) { return (value.isZero()) ? value.toWrapper() : new ByteArrayWrapper(value.getNoLeadZeroesData()); } } diff --git a/modPrecompiled/src/org/aion/precompiled/type/StatefulPrecompiledContract.java b/modPrecompiled/src/org/aion/precompiled/type/StatefulPrecompiledContract.java index 5fc741c7ee..094d2ee111 100644 --- a/modPrecompiled/src/org/aion/precompiled/type/StatefulPrecompiledContract.java +++ b/modPrecompiled/src/org/aion/precompiled/type/StatefulPrecompiledContract.java @@ -1,6 +1,6 @@ package org.aion.precompiled.type; -import org.aion.base.db.IRepositoryCache; +import org.aion.interfaces.db.RepositoryCache; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; @@ -13,7 +13,7 @@ public abstract class StatefulPrecompiledContract implements PrecompiledContract { public static final long TX_NRG_MIN = 20_999; public static final long TX_NRG_MAX = 2_000_001; - protected final IRepositoryCache> track; + protected final RepositoryCache> track; /** * Constructs a new StatefulPrecompiledContract. @@ -21,7 +21,7 @@ public abstract class StatefulPrecompiledContract implements PrecompiledContract * @param track */ public StatefulPrecompiledContract( - IRepositoryCache> track) { + RepositoryCache> track) { if (track == null) { throw new IllegalArgumentException("Null track."); diff --git a/modPrecompiled/test/org/aion/precompiled/TRS/TRShelpers.java b/modPrecompiled/test/org/aion/precompiled/TRS/TRShelpers.java index 935eaedc65..9ebcc9131e 100644 --- a/modPrecompiled/test/org/aion/precompiled/TRS/TRShelpers.java +++ b/modPrecompiled/test/org/aion/precompiled/TRS/TRShelpers.java @@ -15,14 +15,14 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; -import org.aion.mcf.vm.types.DataWord; import org.aion.mcf.vm.types.DoubleDataWord; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; @@ -30,7 +30,7 @@ import org.aion.precompiled.contracts.TRS.TRSqueryContract; import org.aion.precompiled.contracts.TRS.TRSstateContract; import org.aion.precompiled.contracts.TRS.TRSuseContract; -import org.aion.vm.api.interfaces.Address; + import org.aion.zero.impl.StandaloneBlockchain; import org.aion.zero.impl.core.IAionBlockchain; import org.aion.zero.impl.types.AionBlock; @@ -42,15 +42,15 @@ class TRShelpers { static final BigInteger DEFAULT_BALANCE = BigInteger.TEN; private IAionBlockchain blockchain = StandaloneBlockchain.inst(); Address AION = - AionAddress.wrap("0xa0eeaeabdbc92953b072afbd21f3e3fd8a4a4f5e6a6e22200db746ab75e9a99a"); - IRepositoryCache> repo; + Address.wrap("0xa0eeaeabdbc92953b072afbd21f3e3fd8a4a4f5e6a6e22200db746ab75e9a99a"); + RepositoryCache> repo; List
    tempAddrs; ECKey senderKey; long COST = 21000L; // Returns a new account with initial balance balance that exists in the repo. Address getNewExistentAccount(BigInteger balance) { - Address acct = AionAddress.wrap(ECKeyFac.inst().create().getAddress()); + Address acct = Address.wrap(ECKeyFac.inst().create().getAddress()); acct.toBytes()[0] = (byte) 0xA0; repo.createAccount(acct); repo.addBalance(acct, balance); @@ -89,7 +89,7 @@ Address createTRScontract( if (!res.getResultCode().equals(PrecompiledResultCode.SUCCESS)) { fail("Unable to create contract!"); } - Address contract = new AionAddress(res.getReturnData()); + Address contract = new Address(res.getReturnData()); tempAddrs.add(contract); repo.incrementNonce(owner); repo.flush(); @@ -732,7 +732,7 @@ byte[] getMaxDepositInput(Address contract) { // Makes input for numBeneficiaries beneficiaries who each receive a deposit amount deposits. byte[] makeBulkDepositForInput(Address contract, int numBeneficiaries, BigInteger deposits) { - Address[] beneficiaries = new AionAddress[numBeneficiaries]; + Address[] beneficiaries = new Address[numBeneficiaries]; BigInteger[] amounts = new BigInteger[numBeneficiaries]; for (int i = 0; i < numBeneficiaries; i++) { beneficiaries[i] = getNewExistentAccount(BigInteger.ZERO); @@ -745,7 +745,7 @@ byte[] makeBulkDepositForInput(Address contract, int numBeneficiaries, BigIntege byte[] makeBulkDepositForInputwithSelf( Address contract, Address self, int numOthers, BigInteger deposits) { - Address[] beneficiaries = new AionAddress[numOthers + 1]; + Address[] beneficiaries = new Address[numOthers + 1]; BigInteger[] amounts = new BigInteger[numOthers + 1]; for (int i = 0; i < numOthers; i++) { beneficiaries[i] = getNewExistentAccount(BigInteger.ZERO); @@ -781,7 +781,7 @@ Address getLinkedListHead(AbstractTRS trs, Address contract) { return null; } head[0] = (byte) 0xA0; - return new AionAddress(head); + return new Address(head); } // Returns the next account in the linked list after current, or null if no next. @@ -792,7 +792,7 @@ Address getLinkedListNext(AbstractTRS trs, Address contract, Address current) { return null; } next[0] = (byte) 0xA0; - return new AionAddress(next); + return new Address(next); } // Returns the previous account in the linked list prior to current, or null if no previous. @@ -802,7 +802,7 @@ Address getLinkedListPrev(AbstractTRS trs, Address contract, Address current) { return null; } prev[0] = (byte) 0xA0; - return new AionAddress(prev); + return new Address(prev); } // Checks that each account is paid out correctly when they withdraw in a non-final period. @@ -924,8 +924,8 @@ byte[] getTrueContractOutput() { // Returns a new ByteArrayWrapper that wraps data. Here so we can switch types easy if needed. ByteArrayWrapper newDataWordStub(byte[] data) { - if (data.length == DataWord.BYTES) { - return new DataWord(data).toWrapper(); + if (data.length == DataWordImpl.BYTES) { + return new DataWordImpl(data).toWrapper(); } else if (data.length == DoubleDataWord.BYTES) { return new DoubleDataWord(data).toWrapper(); } else { diff --git a/modPrecompiled/test/org/aion/precompiled/TRS/TRSlinkedListTest.java b/modPrecompiled/test/org/aion/precompiled/TRS/TRSlinkedListTest.java index 5e1c78a2ff..80e26e7180 100644 --- a/modPrecompiled/test/org/aion/precompiled/TRS/TRSlinkedListTest.java +++ b/modPrecompiled/test/org/aion/precompiled/TRS/TRSlinkedListTest.java @@ -11,12 +11,12 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.Set; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.contracts.DummyRepo; import org.aion.precompiled.contracts.TRS.AbstractTRS; import org.aion.precompiled.contracts.TRS.TRSuseContract; -import org.aion.vm.api.interfaces.Address; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -482,7 +482,7 @@ private void checkRemoveTailOfLargerList(Address contract, Address owner, int li // unique too. TRSuseContract trs = newTRSuseContract(owner); Address next = getLinkedListHead(trs, contract); - Address head = new AionAddress(next.toBytes()); + Address head = new Address(next.toBytes()); Set
    addressesInList = new HashSet<>(); for (int i = 0; i < listSize; i++) { if (i == listSize - 1) { @@ -542,7 +542,7 @@ private void checkRemoveInteriorOfLargerList(Address contract, Address owner, in // unique too. TRSuseContract trs = newTRSuseContract(owner); Address next = getLinkedListHead(trs, contract); - Address head = new AionAddress(next.toBytes()); + Address head = new Address(next.toBytes()); Address mid = null; Set
    addressesInList = new HashSet<>(); for (int i = 0; i < listSize; i++) { @@ -553,7 +553,7 @@ private void checkRemoveInteriorOfLargerList(Address contract, Address owner, in assertNotNull(next); assertFalse(addressesInList.contains(next)); addressesInList.add(next); - mid = new AionAddress(next.toBytes()); + mid = new Address(next.toBytes()); } else { next = getLinkedListNext(trs, contract, next); assertNotNull(next); diff --git a/modPrecompiled/test/org/aion/precompiled/TRS/TRSqueryContractTest.java b/modPrecompiled/test/org/aion/precompiled/TRS/TRSqueryContractTest.java index 74bb4e8125..e7c35f7893 100644 --- a/modPrecompiled/test/org/aion/precompiled/TRS/TRSqueryContractTest.java +++ b/modPrecompiled/test/org/aion/precompiled/TRS/TRSqueryContractTest.java @@ -10,8 +10,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Set; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; +import org.aion.types.Address; import org.aion.mcf.vm.types.DoubleDataWord; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; @@ -19,7 +18,8 @@ import org.aion.precompiled.contracts.TRS.AbstractTRS; import org.aion.precompiled.contracts.TRS.TRSqueryContract; import org.aion.precompiled.type.StatefulPrecompiledContract; -import org.aion.vm.api.interfaces.Address; + +import org.aion.util.bytes.ByteUtil; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -142,7 +142,7 @@ public void testIsLiveNonExistentContract() { // Test on a contract address that looks real, uses TRS prefix. byte[] phony = acct.toBytes(); phony[0] = (byte) 0xC0; - input = getIsLiveInput(new AionAddress(phony)); + input = getIsLiveInput(new Address(phony)); res = newTRSqueryContract(acct).execute(input, COST); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); @@ -217,7 +217,7 @@ public void testIsLockedNonExistentContract() { // Test on a contract address that looks real, uses TRS prefix. byte[] phony = acct.toBytes(); phony[0] = (byte) 0xC0; - input = getIsLockedInput(new AionAddress(phony)); + input = getIsLockedInput(new Address(phony)); res = newTRSqueryContract(acct).execute(input, COST); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); @@ -292,7 +292,7 @@ public void testIsDepoEnabledNonExistentContract() { // Test on a contract address that looks real, uses TRS prefix. byte[] phony = acct.toBytes(); phony[0] = (byte) 0xC0; - input = getIsDirDepoEnabledInput(new AionAddress(phony)); + input = getIsDirDepoEnabledInput(new Address(phony)); res = newTRSqueryContract(acct).execute(input, COST); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); diff --git a/modPrecompiled/test/org/aion/precompiled/TRS/TRSstateContractTest.java b/modPrecompiled/test/org/aion/precompiled/TRS/TRSstateContractTest.java index 1a89737d97..242caf81e8 100644 --- a/modPrecompiled/test/org/aion/precompiled/TRS/TRSstateContractTest.java +++ b/modPrecompiled/test/org/aion/precompiled/TRS/TRSstateContractTest.java @@ -12,8 +12,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.concurrent.TimeUnit; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; +import org.aion.types.Address; import org.aion.mcf.vm.types.DoubleDataWord; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; @@ -21,7 +20,8 @@ import org.aion.precompiled.contracts.TRS.AbstractTRS; import org.aion.precompiled.contracts.TRS.TRSstateContract; import org.aion.precompiled.type.StatefulPrecompiledContract; -import org.aion.vm.api.interfaces.Address; + +import org.aion.util.bytes.ByteUtil; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -169,13 +169,13 @@ public void testCreateCorrectOwner() { Address caller = getNewExistentAccount(BigInteger.ZERO); TRSstateContract trs = newTRSstateContract(caller); PrecompiledTransactionResult res = trs.execute(input, COST); - Address contract = new AionAddress(res.getReturnData()); + Address contract = new Address(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(caller, getOwner(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); } @Test @@ -183,12 +183,12 @@ public void testCreateTestModeCorrectOwner() { byte[] input = getCreateInput(true, false, 1, BigInteger.ZERO, 0); TRSstateContract trs = newTRSstateContract(AION); PrecompiledTransactionResult res = trs.execute(input, COST); - Address contract = AionAddress.wrap(res.getReturnData()); + Address contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - assertEquals(AION, getOwner(trs, new AionAddress(res.getReturnData()))); + assertEquals(AION, getOwner(trs, new Address(res.getReturnData()))); } @Test @@ -199,13 +199,13 @@ public void testCreateVerifyPeriods() { Address caller = getNewExistentAccount(BigInteger.ZERO); TRSstateContract trs = newTRSstateContract(caller); PrecompiledTransactionResult res = trs.execute(input, COST); - Address contract = AionAddress.wrap(res.getReturnData()); + Address contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(periods, getPeriods(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); repo.incrementNonce(caller); repo.flush(); @@ -214,13 +214,13 @@ public void testCreateVerifyPeriods() { periods = 1200; input = getCreateInput(false, false, periods, BigInteger.ZERO, 0); res = trs.execute(input, COST); - contract = AionAddress.wrap(res.getReturnData()); + contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(periods, getPeriods(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); } @Test @@ -230,13 +230,13 @@ public void testCreateTestModeVerifyPeriods() { byte[] input = getCreateInput(true, false, periods, BigInteger.ZERO, 0); TRSstateContract trs = newTRSstateContract(AION); PrecompiledTransactionResult res = trs.execute(input, COST); - Address contract = AionAddress.wrap(res.getReturnData()); + Address contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(periods, getPeriods(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); repo.incrementNonce(AION); repo.flush(); @@ -245,13 +245,13 @@ public void testCreateTestModeVerifyPeriods() { periods = 1200; input = getCreateInput(true, false, periods, BigInteger.ZERO, 0); res = trs.execute(input, COST); - contract = AionAddress.wrap(res.getReturnData()); + contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(periods, getPeriods(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); } @Test @@ -266,39 +266,39 @@ public void testCreateVerifyPeriodsByteBoundary() { Address caller = getNewExistentAccount(BigInteger.ZERO); TRSstateContract trs = newTRSstateContract(caller); PrecompiledTransactionResult res = trs.execute(input, COST); - Address contract = AionAddress.wrap(res.getReturnData()); + Address contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(periods, getPeriods(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); repo.incrementNonce(caller); repo.flush(); input = getCreateInput(false, false, periods2, BigInteger.ZERO, 0); res = trs.execute(input, COST); - contract = AionAddress.wrap(res.getReturnData()); + contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(periods2, getPeriods(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); repo.incrementNonce(caller); repo.flush(); input = getCreateInput(false, false, periods3, BigInteger.ZERO, 0); res = trs.execute(input, COST); - contract = AionAddress.wrap(res.getReturnData()); + contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(periods3, getPeriods(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); } @Test @@ -308,26 +308,26 @@ public void testCreateVerifyIsTest() { byte[] input = getCreateInput(isTest, false, 1, BigInteger.ZERO, 0); TRSstateContract trs = newTRSstateContract(getNewExistentAccount(BigInteger.ZERO)); PrecompiledTransactionResult res = trs.execute(input, COST); - Address contract = AionAddress.wrap(res.getReturnData()); + Address contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(isTest, isTestContract(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); // When true isTest = true; input = getCreateInput(isTest, false, 1, BigInteger.ZERO, 0); trs = newTRSstateContract(AION); res = trs.execute(input, COST); - contract = AionAddress.wrap(res.getReturnData()); + contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(isTest, isTestContract(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); } @Test @@ -338,13 +338,13 @@ public void testCreateVerifyIsDirectDeposit() { byte[] input = getCreateInput(false, isDirectDeposit, 1, BigInteger.ZERO, 0); TRSstateContract trs = newTRSstateContract(caller); PrecompiledTransactionResult res = trs.execute(input, COST); - Address contract = AionAddress.wrap(res.getReturnData()); + Address contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(isDirectDeposit, isDirectDepositEnabled(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); repo.incrementNonce(caller); repo.flush(); @@ -353,13 +353,13 @@ public void testCreateVerifyIsDirectDeposit() { isDirectDeposit = true; input = getCreateInput(false, isDirectDeposit, 1, BigInteger.ZERO, 0); res = trs.execute(input, COST); - contract = AionAddress.wrap(res.getReturnData()); + contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(isDirectDeposit, isDirectDepositEnabled(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); } @Test @@ -369,13 +369,13 @@ public void testCreateVerifyZeroPercentage() { byte[] input = getCreateInput(false, false, 1, BigInteger.ZERO, 0); TRSstateContract trs = newTRSstateContract(caller); PrecompiledTransactionResult res = trs.execute(input, COST); - Address contract = AionAddress.wrap(res.getReturnData()); + Address contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(BigDecimal.ZERO, getPercentage(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); repo.incrementNonce(caller); repo.flush(); @@ -383,13 +383,13 @@ public void testCreateVerifyZeroPercentage() { // Test 18 shifts. input = getCreateInput(false, false, 1, BigInteger.ZERO, 18); res = trs.execute(input, COST); - contract = AionAddress.wrap(res.getReturnData()); + contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(BigDecimal.ZERO.movePointLeft(18), getPercentage(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); } @Test @@ -400,13 +400,13 @@ public void testCreateVerifyOneHundredPercentage() { byte[] input = getCreateInput(false, false, 1, raw, 0); TRSstateContract trs = newTRSstateContract(caller); PrecompiledTransactionResult res = trs.execute(input, COST); - Address contract = AionAddress.wrap(res.getReturnData()); + Address contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(new BigDecimal(raw), getPercentage(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); repo.incrementNonce(caller); repo.flush(); @@ -415,13 +415,13 @@ public void testCreateVerifyOneHundredPercentage() { raw = new BigInteger("100000000000000000000"); input = getCreateInput(false, false, 1, raw, 18); res = trs.execute(input, COST); - contract = AionAddress.wrap(res.getReturnData()); + contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(new BigDecimal(raw).movePointLeft(18), getPercentage(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); } @Test @@ -477,13 +477,13 @@ public void testCreateVerify18DecimalPercentage() { byte[] input = getCreateInput(false, false, 1, raw, 18); TRSstateContract trs = newTRSstateContract(caller); PrecompiledTransactionResult res = trs.execute(input, COST); - Address contract = AionAddress.wrap(res.getReturnData()); + Address contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(new BigDecimal(raw).movePointLeft(18), getPercentage(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); repo.incrementNonce(caller); repo.flush(); @@ -493,13 +493,13 @@ public void testCreateVerify18DecimalPercentage() { input = getCreateInput(false, false, 1, raw, 18); trs = newTRSstateContract(caller); res = trs.execute(input, COST); - contract = AionAddress.wrap(res.getReturnData()); + contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(new BigDecimal(raw).movePointLeft(18), getPercentage(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); repo.incrementNonce(caller); repo.flush(); @@ -509,13 +509,13 @@ public void testCreateVerify18DecimalPercentage() { input = getCreateInput(false, false, 1, raw, 18); trs = newTRSstateContract(caller); res = trs.execute(input, COST); - contract = AionAddress.wrap(res.getReturnData()); + contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(new BigDecimal(raw).movePointLeft(18), getPercentage(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); } @Test @@ -543,13 +543,13 @@ public void testCreateValidAndInvalidPercentagesByShifting() { input = getCreateInput(false, false, 1, raw, shifts); trs = newTRSstateContract(caller); res = trs.execute(input, COST); - Address contract = AionAddress.wrap(res.getReturnData()); + Address contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(new BigDecimal(raw).movePointLeft(shifts), getPercentage(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); repo.incrementNonce(caller); repo.flush(); @@ -559,13 +559,13 @@ public void testCreateValidAndInvalidPercentagesByShifting() { input = getCreateInput(false, false, 1, raw, shifts); trs = newTRSstateContract(caller); res = trs.execute(input, COST); - contract = AionAddress.wrap(res.getReturnData()); + contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(new BigDecimal(raw).movePointLeft(shifts), getPercentage(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); repo.incrementNonce(caller); repo.flush(); @@ -575,13 +575,13 @@ public void testCreateValidAndInvalidPercentagesByShifting() { input = getCreateInput(false, false, 1, raw, shifts); trs = newTRSstateContract(caller); res = trs.execute(input, COST); - contract = AionAddress.wrap(res.getReturnData()); + contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); assertEquals(new BigDecimal(raw).movePointLeft(shifts), getPercentage(trs, contract)); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); } @Test @@ -591,7 +591,7 @@ public void testCreateTRSaddressDeterministic() { byte[] input = getCreateInput(false, false, 1, BigInteger.ZERO, 0); TRSstateContract trs = newTRSstateContract(caller); PrecompiledTransactionResult res = trs.execute(input, COST); - Address contract = AionAddress.wrap(res.getReturnData()); + Address contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); tempAddrs.add(contract); @@ -605,9 +605,9 @@ public void testCreateTRSaddressDeterministic() { assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); - assertNotEquals(contract, AionAddress.wrap(res.getReturnData())); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); - contract = AionAddress.wrap(res.getReturnData()); + assertNotEquals(contract, Address.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); + contract = Address.wrap(res.getReturnData()); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); @@ -615,10 +615,10 @@ public void testCreateTRSaddressDeterministic() { // Same caller as original & nonce hasn't changed, should be same contract addr returned. trs = newTRSstateContract(caller); res = trs.execute(input, COST); - contract = AionAddress.wrap(res.getReturnData()); + contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); - assertEquals(contract, AionAddress.wrap(res.getReturnData())); + assertEquals(contract, Address.wrap(res.getReturnData())); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); @@ -630,10 +630,10 @@ public void testCreateTRSaddressDeterministic() { res = trs.execute(input, COST); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); - assertNotEquals(contract, AionAddress.wrap(res.getReturnData())); - tempAddrs.add(AionAddress.wrap(res.getReturnData())); + assertNotEquals(contract, Address.wrap(res.getReturnData())); + tempAddrs.add(Address.wrap(res.getReturnData())); - contract = AionAddress.wrap(res.getReturnData()); + contract = Address.wrap(res.getReturnData()); assertFalse(isContractLocked(trs, contract)); assertFalse(isContractLive(trs, contract)); } @@ -645,7 +645,7 @@ public void testCreateSuccessNrgLeft() { byte[] input = getCreateInput(false, false, 1, BigInteger.ZERO, 0); TRSstateContract trs = newTRSstateContract(caller); PrecompiledTransactionResult res = trs.execute(input, COST + diff); - Address contract = AionAddress.wrap(res.getReturnData()); + Address contract = Address.wrap(res.getReturnData()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(diff, res.getEnergyRemaining()); tempAddrs.add(contract); @@ -665,7 +665,7 @@ public void testCreateContractHasTimestamp() { long after = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); - Address contract = AionAddress.wrap(res.getReturnData()); + Address contract = Address.wrap(res.getReturnData()); long timestamp = getContractTimestamp(trs, contract); assertTrue(timestamp >= before); diff --git a/modPrecompiled/test/org/aion/precompiled/TRS/TRSuseContractTest.java b/modPrecompiled/test/org/aion/precompiled/TRS/TRSuseContractTest.java index 6ee288676a..1cfcd06908 100644 --- a/modPrecompiled/test/org/aion/precompiled/TRS/TRSuseContractTest.java +++ b/modPrecompiled/test/org/aion/precompiled/TRS/TRSuseContractTest.java @@ -11,8 +11,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Set; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; +import org.aion.types.Address; import org.aion.crypto.ECKeyFac; import org.aion.mcf.vm.types.DoubleDataWord; import org.aion.precompiled.PrecompiledResultCode; @@ -21,7 +20,8 @@ import org.aion.precompiled.contracts.TRS.AbstractTRS; import org.aion.precompiled.contracts.TRS.TRSuseContract; import org.aion.precompiled.type.StatefulPrecompiledContract; -import org.aion.vm.api.interfaces.Address; + +import org.aion.util.bytes.ByteUtil; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -152,7 +152,7 @@ public void testDepositToNonExistentContract() { System.arraycopy(acct.toBytes(), 0, addr, 0, Address.SIZE); addr[0] = (byte) 0xC0; - input = getDepositInput(AionAddress.wrap(addr), BigInteger.TWO); + input = getDepositInput(Address.wrap(addr), BigInteger.TWO); res = trs.execute(input, COST); assertEquals(PrecompiledResultCode.FAILURE, res.getResultCode()); assertEquals(0, res.getEnergyRemaining()); @@ -1985,7 +1985,7 @@ public void testRefundBadTRScontract() { // Test TRS address with TRS prefix, so it looks legit. byte[] addr = ECKeyFac.inst().create().getAddress(); addr[0] = (byte) 0xC0; - contract = new AionAddress(addr); + contract = new Address(addr); tempAddrs.add(contract); input = getRefundInput(contract, acct, BigInteger.ZERO); res = newTRSuseContract(acct).execute(input, COST); @@ -2469,7 +2469,7 @@ public void testDepositForContractAddressIsInvalid() { Address other = getNewExistentAccount(DEFAULT_BALANCE); byte[] addr = Arrays.copyOf(other.toBytes(), other.toBytes().length); addr[0] = (byte) 0xC0; - Address contract = new AionAddress(addr); + Address contract = new Address(addr); byte[] input = getDepositForInput(contract, other, BigInteger.ONE); PrecompiledTransactionResult res = newTRSuseContract(owner).execute(input, COST); diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeControllerOwnerTest.java b/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeControllerOwnerTest.java index cabc1f57da..30b1c9a7f7 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeControllerOwnerTest.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeControllerOwnerTest.java @@ -4,12 +4,12 @@ import static org.aion.precompiled.contracts.ATB.BridgeTestUtils.dummyContext; import java.util.List; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; +import org.aion.types.Address; import org.aion.crypto.HashUtil; import org.aion.fastvm.ExecutionContext; import org.aion.precompiled.contracts.DummyRepo; -import org.aion.vm.api.interfaces.Address; + +import org.aion.util.bytes.ByteUtil; import org.aion.vm.api.interfaces.IExecutionLog; import org.aion.vm.api.interfaces.TransactionSideEffects; import org.junit.Before; @@ -22,9 +22,9 @@ public class BridgeControllerOwnerTest { private TransactionSideEffects result; private static final Address CONTRACT_ADDR = - new AionAddress(HashUtil.h256("contractAddress".getBytes())); + new Address(HashUtil.h256("contractAddress".getBytes())); private static final Address OWNER_ADDR = - new AionAddress(HashUtil.h256("ownerAddress".getBytes())); + new Address(HashUtil.h256("ownerAddress".getBytes())); @Before public void beforeEach() { diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeControllerRingTest.java b/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeControllerRingTest.java index e77e987b3d..562c4867b7 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeControllerRingTest.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeControllerRingTest.java @@ -3,12 +3,12 @@ import static com.google.common.truth.Truth.assertThat; import static org.aion.precompiled.contracts.ATB.BridgeTestUtils.dummyContext; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.crypto.HashUtil; import org.aion.precompiled.contracts.DummyRepo; -import org.aion.vm.api.interfaces.Address; + import org.junit.Before; import org.junit.Test; @@ -17,9 +17,9 @@ public class BridgeControllerRingTest { private BridgeStorageConnector connector; private BridgeController controller; private static final Address CONTRACT_ADDR = - new AionAddress(HashUtil.h256("contractAddress".getBytes())); + new Address(HashUtil.h256("contractAddress".getBytes())); private static final Address OWNER_ADDR = - new AionAddress(HashUtil.h256("ownerAddress".getBytes())); + new Address(HashUtil.h256("ownerAddress".getBytes())); private static final ECKey members[] = new ECKey[] { diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeRingInitializationTest.java b/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeRingInitializationTest.java index 6b014b31ff..cfe5260655 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeRingInitializationTest.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeRingInitializationTest.java @@ -3,10 +3,10 @@ import static com.google.common.truth.Truth.assertThat; import static org.aion.precompiled.contracts.ATB.BridgeTestUtils.dummyContext; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.crypto.HashUtil; import org.aion.precompiled.contracts.DummyRepo; -import org.aion.vm.api.interfaces.Address; + import org.junit.Before; import org.junit.Test; @@ -15,9 +15,9 @@ public class BridgeRingInitializationTest { private BridgeStorageConnector connector; private BridgeController controller; private static final Address CONTRACT_ADDR = - new AionAddress(HashUtil.h256("contractAddress".getBytes())); + new Address(HashUtil.h256("contractAddress".getBytes())); private static final Address OWNER_ADDR = - new AionAddress(HashUtil.h256("ownerAddress".getBytes())); + new Address(HashUtil.h256("ownerAddress".getBytes())); @Before public void beforeEach() { diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeStorageConnectorTest.java b/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeStorageConnectorTest.java index 6a7bb6bc35..1049706d38 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeStorageConnectorTest.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeStorageConnectorTest.java @@ -2,23 +2,22 @@ import static com.google.common.truth.Truth.assertThat; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteUtil; +import org.aion.types.Address; import org.aion.crypto.HashUtil; import org.aion.precompiled.contracts.DummyRepo; -import org.aion.vm.api.interfaces.Address; + +import org.aion.util.bytes.ByteUtil; import org.junit.Before; import org.junit.Test; public class BridgeStorageConnectorTest { private BridgeStorageConnector connector; - private static final Address contractAddress = AionAddress.ZERO_ADDRESS(); + private static final Address contractAddress = Address.ZERO_ADDRESS(); @Before public void beforeEach() { DummyRepo repo = new DummyRepo(); - this.connector = new BridgeStorageConnector((IRepositoryCache) repo, contractAddress); + this.connector = new BridgeStorageConnector(repo, contractAddress); } // should be null diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeTestUtils.java b/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeTestUtils.java index 76905b2105..73a07bc4d6 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeTestUtils.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeTestUtils.java @@ -1,15 +1,15 @@ package org.aion.precompiled.contracts.ATB; -import org.aion.base.type.AionAddress; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; import org.aion.crypto.AddressSpecs; import org.aion.crypto.HashUtil; import org.aion.fastvm.ExecutionContext; -import org.aion.mcf.vm.types.DataWord; -import org.aion.vm.api.interfaces.Address; + public class BridgeTestUtils { static ExecutionContext dummyContext() { - return context(AionAddress.ZERO_ADDRESS(), AionAddress.ZERO_ADDRESS(), new byte[0]); + return context(Address.ZERO_ADDRESS(), Address.ZERO_ADDRESS(), new byte[0]); } static ExecutionContext context(Address from, Address to, byte[] txData) { @@ -17,20 +17,20 @@ static ExecutionContext context(Address from, Address to, byte[] txData) { final Address address = to; final Address origin = from; final Address caller = origin; - final DataWord nrgPrice = DataWord.ONE; + final DataWordImpl nrgPrice = DataWordImpl.ONE; final long nrgLimit = 21000L; - final DataWord callValue = DataWord.ZERO; + final DataWordImpl callValue = DataWordImpl.ZERO; final byte[] callData = txData; final int callDepth = 1; final int flag = 0; final int kind = 0; final Address blockCoinbase = - new AionAddress( + new Address( AddressSpecs.computeA0Address(HashUtil.h256("coinbase".getBytes()))); long blockNumber = 0; long blockTimestamp = 0; long blockNrgLimit = 0; - DataWord blockDifficulty = DataWord.ZERO; + DataWordImpl blockDifficulty = DataWordImpl.ZERO; return new ExecutionContext( null, diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeTransferTest.java b/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeTransferTest.java index f6b32acff9..ab57029616 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeTransferTest.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/ATB/BridgeTransferTest.java @@ -6,14 +6,14 @@ import java.math.BigInteger; import java.security.SecureRandom; import java.util.List; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.crypto.HashUtil; import org.aion.fastvm.ExecutionContext; import org.aion.precompiled.PrecompiledUtilities; import org.aion.precompiled.contracts.DummyRepo; -import org.aion.vm.api.interfaces.Address; + import org.aion.vm.api.interfaces.IExecutionLog; import org.junit.Before; import org.junit.Test; @@ -27,9 +27,9 @@ public class BridgeTransferTest { private ExecutionContext context; private static final Address CONTRACT_ADDR = - new AionAddress(HashUtil.h256("contractAddress".getBytes())); + new Address(HashUtil.h256("contractAddress".getBytes())); private static final Address OWNER_ADDR = - new AionAddress(HashUtil.h256("ownerAddress".getBytes())); + new Address(HashUtil.h256("ownerAddress".getBytes())); private static final ECKey members[] = new ECKey[] { @@ -143,7 +143,7 @@ public void testBridgeNotEnoughSignatures() { assertThat(results).isNotNull(); assertThat(results.controllerResult).isEqualTo(ErrCode.INVALID_SIGNATURE_BOUNDS); assertThat(this.repo.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.ONE); - assertThat(this.repo.getBalance(new AionAddress(recipient))).isEqualTo(BigInteger.ZERO); + assertThat(this.repo.getBalance(new Address(recipient))).isEqualTo(BigInteger.ZERO); } @Test @@ -181,7 +181,7 @@ public void testLowerBoundSignature() { assertThat(results).isNotNull(); assertThat(results.controllerResult).isEqualTo(ErrCode.NO_ERROR); assertThat(this.repo.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.ZERO); - assertThat(this.repo.getBalance(new AionAddress(recipient))).isEqualTo(BigInteger.ONE); + assertThat(this.repo.getBalance(new Address(recipient))).isEqualTo(BigInteger.ONE); } @Test @@ -219,7 +219,7 @@ public void testBeyondUpperBoundSignatures() { assertThat(results).isNotNull(); assertThat(results.controllerResult).isEqualTo(ErrCode.INVALID_SIGNATURE_BOUNDS); assertThat(this.repo.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.ONE); - assertThat(this.repo.getBalance(new AionAddress(recipient))).isEqualTo(BigInteger.ZERO); + assertThat(this.repo.getBalance(new Address(recipient))).isEqualTo(BigInteger.ZERO); } @Test @@ -255,7 +255,7 @@ public void testTransferZeroBundle() { assertThat(results).isNotNull(); assertThat(results.controllerResult).isEqualTo(ErrCode.INVALID_TRANSFER); assertThat(this.repo.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.ONE); - assertThat(this.repo.getBalance(new AionAddress(recipient))).isEqualTo(BigInteger.ZERO); + assertThat(this.repo.getBalance(new Address(recipient))).isEqualTo(BigInteger.ZERO); } static class ResultHashTuple { @@ -325,7 +325,7 @@ public void testDoubleBundleSend() { // one transfer should have gone through, second shouldn't assertThat(this.repo.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.ONE); - assertThat(this.repo.getBalance(new AionAddress(recipient))).isEqualTo(BigInteger.ONE); + assertThat(this.repo.getBalance(new Address(recipient))).isEqualTo(BigInteger.ONE); } // Transfer 511 times, ONE per transfer @@ -354,7 +354,7 @@ public void testBundleMultipleTransferSameRecipient() { assertThat(tuple.results.controllerResult).isEqualTo(ErrCode.NO_ERROR); assertThat(this.repo.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.ZERO); - assertThat(this.repo.getBalance(AionAddress.wrap(recipient))) + assertThat(this.repo.getBalance(Address.wrap(recipient))) .isEqualTo(transferTotalBigInteger); // 511 transfer events + 1 distributed event diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/ATB/TokenBridgeContractTest.java b/modPrecompiled/test/org/aion/precompiled/contracts/ATB/TokenBridgeContractTest.java index d2e7ada5a5..474520cc81 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/ATB/TokenBridgeContractTest.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/ATB/TokenBridgeContractTest.java @@ -6,15 +6,14 @@ import java.math.BigInteger; import java.util.Arrays; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.AddressSpecs; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.crypto.HashUtil; import org.aion.fastvm.ExecutionContext; -import org.aion.mcf.vm.types.DataWord; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; import org.aion.precompiled.PrecompiledUtilities; @@ -23,7 +22,8 @@ import org.aion.precompiled.encoding.AddressFVM; import org.aion.precompiled.encoding.ListFVM; import org.aion.precompiled.encoding.Uint128FVM; -import org.aion.vm.api.interfaces.Address; + +import org.aion.util.bytes.ByteUtil; import org.aion.vm.api.interfaces.IExecutionLog; import org.aion.vm.api.interfaces.InternalTransactionInterface; import org.junit.Before; @@ -49,9 +49,9 @@ public class TokenBridgeContractTest { }; private static final Address CONTRACT_ADDR = - new AionAddress(HashUtil.h256("contractAddress".getBytes())); + new Address(HashUtil.h256("contractAddress".getBytes())); private static final Address OWNER_ADDR = - new AionAddress(HashUtil.h256("ownerAddress".getBytes())); + new Address(HashUtil.h256("ownerAddress".getBytes())); private static final long DEFAULT_NRG = 21000L; @@ -120,7 +120,7 @@ public void testGetNewOwnerNotOwnerAddress() { this.contract = new TokenBridgeContract( context( - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY), this.repository, @@ -176,7 +176,7 @@ public void testInitializeRingNotOwner() { this.contract = new TokenBridgeContract( context( - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY), this.repository, @@ -235,7 +235,7 @@ public void testTransfer() { // need to change the execution context ExecutionContext submitBundleContext = context( - new AionAddress(members[0].getAddress()), + new Address(members[0].getAddress()), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY); this.contract = @@ -333,7 +333,7 @@ public void testTransfer() { assertThat(transferResult.getResultCode()).isEqualTo(PrecompiledResultCode.SUCCESS); for (BridgeTransfer b : transfers) { - assertThat(this.repository.getBalance(new AionAddress(b.getRecipient()))) + assertThat(this.repository.getBalance(new Address(b.getRecipient()))) .isEqualTo(BigInteger.ONE); } assertThat(this.repository.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.ZERO); @@ -360,7 +360,7 @@ public void testTransfer() { // verify that the recipient is what we intended (in the order we submitted) assertThat(tx.getDestinationAddress()) - .isEqualTo(new AionAddress(transfers[i].getRecipient())); + .isEqualTo(new Address(transfers[i].getRecipient())); i++; } @@ -429,7 +429,7 @@ public void testNonA0AddressTransfer() { // need to change the execution context ExecutionContext submitBundleContext = context( - new AionAddress(members[0].getAddress()), + new Address(members[0].getAddress()), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY); this.contract = @@ -526,7 +526,7 @@ public void testNonA0AddressTransfer() { assertThat(transferResult.getResultCode()).isEqualTo(PrecompiledResultCode.SUCCESS); for (BridgeTransfer b : transfers) { - assertThat(this.repository.getBalance(new AionAddress(b.getRecipient()))) + assertThat(this.repository.getBalance(new Address(b.getRecipient()))) .isEqualTo(BigInteger.ONE); } assertThat(this.repository.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.ZERO); @@ -553,7 +553,7 @@ public void testNonA0AddressTransfer() { // verify that the recipient is what we intended (in the order we submitted) assertThat(tx.getDestinationAddress()) - .isEqualTo(new AionAddress(transfers[i].getRecipient())); + .isEqualTo(new Address(transfers[i].getRecipient())); i++; } @@ -622,7 +622,7 @@ public void testTransferNotRelayer() { // need to change the execution context ExecutionContext submitBundleContext = context( - new AionAddress(members[0].getAddress()), + new Address(members[0].getAddress()), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY); this.contract = @@ -692,7 +692,7 @@ public void testTransferNotRelayer() { // we create a new token bridge contract here because we // need to change the execution context ExecutionContext incorrectRelaySubmitBundleContext = - context(AionAddress.ZERO_ADDRESS(), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY); + context(Address.ZERO_ADDRESS(), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY); this.contract = new TokenBridgeContract( incorrectRelaySubmitBundleContext, @@ -753,7 +753,7 @@ public void testTransfersGreaterThanMaxListSize() { // override defaults ExecutionContext submitBundleContext = context( - new AionAddress(members[0].getAddress()), + new Address(members[0].getAddress()), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY); this.repository.addBalance(CONTRACT_ADDR, BigInteger.valueOf(1024)); @@ -828,7 +828,7 @@ public void testTransfersGreaterThanMaxListSize() { assertThat(transferResult.getResultCode()).isEqualTo(PrecompiledResultCode.FAILURE); for (BridgeTransfer b : transfers) { - assertThat(this.repository.getBalance(new AionAddress(b.getRecipient()))) + assertThat(this.repository.getBalance(new Address(b.getRecipient()))) .isEqualTo(BigInteger.ZERO); } assertThat(this.repository.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.valueOf(1024)); @@ -876,7 +876,7 @@ public void testAlreadySubmittedBundle() { // need to change the execution context ExecutionContext submitBundleContext = context( - new AionAddress(members[0].getAddress()), + new Address(members[0].getAddress()), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY); this.contract = @@ -1010,7 +1010,7 @@ public void testTransferRingLocked() { // need to change the execution context ExecutionContext submitBundleContext = context( - new AionAddress(members[0].getAddress()), + new Address(members[0].getAddress()), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY); this.contract = @@ -1106,7 +1106,7 @@ public void testTransferRingLocked() { // check that nothing has been modified from the failed transfer for (BridgeTransfer b : transfers) { - assertThat(this.repository.getBalance(new AionAddress(b.getRecipient()))) + assertThat(this.repository.getBalance(new Address(b.getRecipient()))) .isEqualTo(BigInteger.ZERO); } assertThat(this.repository.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.valueOf(10)); @@ -1145,7 +1145,7 @@ public void testTransferInvalidReLayer() { // need to change the execution context ExecutionContext submitBundleContext = context( - new AionAddress(members[0].getAddress()), + new Address(members[0].getAddress()), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY); this.contract = @@ -1241,7 +1241,7 @@ public void testTransferInvalidReLayer() { // check that nothing has been modified from the failed transfer for (BridgeTransfer b : transfers) { - assertThat(this.repository.getBalance(new AionAddress(b.getRecipient()))) + assertThat(this.repository.getBalance(new Address(b.getRecipient()))) .isEqualTo(BigInteger.ZERO); } assertThat(this.repository.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.valueOf(10)); @@ -1289,7 +1289,7 @@ public void testTransferLessThanMinimumRequiredValidators() { // need to change the execution context ExecutionContext submitBundleContext = context( - new AionAddress(members[0].getAddress()), + new Address(members[0].getAddress()), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY); this.contract = @@ -1384,7 +1384,7 @@ public void testTransferLessThanMinimumRequiredValidators() { // check that nothing has been modified from the failed transfer for (BridgeTransfer b : transfers) { - assertThat(this.repository.getBalance(new AionAddress(b.getRecipient()))) + assertThat(this.repository.getBalance(new Address(b.getRecipient()))) .isEqualTo(BigInteger.ZERO); } assertThat(this.repository.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.valueOf(10)); @@ -1432,7 +1432,7 @@ public void testTransferInsufficientValidatorSignatures() { // need to change the execution context ExecutionContext submitBundleContext = context( - new AionAddress(members[0].getAddress()), + new Address(members[0].getAddress()), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY); this.contract = @@ -1529,7 +1529,7 @@ public void testTransferInsufficientValidatorSignatures() { // check that nothing has been changed from the failed transfer for (BridgeTransfer b : transfers) { - assertThat(this.repository.getBalance(new AionAddress(b.getRecipient()))) + assertThat(this.repository.getBalance(new Address(b.getRecipient()))) .isEqualTo(BigInteger.ZERO); } assertThat(this.repository.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.valueOf(10)); @@ -1578,7 +1578,7 @@ public void testTransferOutOfBoundsListMeta() { // need to change the execution context ExecutionContext submitBundleContext = context( - new AionAddress(members[0].getAddress()), + new Address(members[0].getAddress()), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY); this.contract = @@ -1678,7 +1678,7 @@ public void testTransferOutOfBoundsListMeta() { // check that nothing has been changed from the failed transfer for (BridgeTransfer b : transfers) { - assertThat(this.repository.getBalance(new AionAddress(b.getRecipient()))) + assertThat(this.repository.getBalance(new Address(b.getRecipient()))) .isEqualTo(BigInteger.ZERO); } assertThat(this.repository.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.valueOf(10)); @@ -1731,10 +1731,10 @@ public void testTransferToSameAddressTwiceInOneBundle() { int i = 0; for (BridgeTransfer b : transfers) { if (i == 2 || i == 3) { - assertThat(this.repository.getBalance(new AionAddress(b.getRecipient()))) + assertThat(this.repository.getBalance(new Address(b.getRecipient()))) .isEqualTo(BigInteger.TWO); } else { - assertThat(this.repository.getBalance(new AionAddress(b.getRecipient()))) + assertThat(this.repository.getBalance(new Address(b.getRecipient()))) .isEqualTo(BigInteger.ONE); } i++; @@ -1763,7 +1763,7 @@ public void testTransferToSameAddressTwiceInOneBundle() { // verify that the recipient is what we intended (in the order we submitted) assertThat(tx.getDestinationAddress()) - .isEqualTo(new AionAddress(transfers[i].getRecipient())); + .isEqualTo(new Address(transfers[i].getRecipient())); i++; } @@ -1835,7 +1835,7 @@ public void testTransferHugeListOffset() { // check that nothing has been changed from the failed transfer for (BridgeTransfer b : transfers) { - assertThat(this.repository.getBalance(new AionAddress(b.getRecipient()))) + assertThat(this.repository.getBalance(new Address(b.getRecipient()))) .isEqualTo(BigInteger.ZERO); } assertThat(this.repository.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.valueOf(10)); @@ -1885,7 +1885,7 @@ public void testTransferHugeListLength() { // check that nothing has been changed from the failed transfer for (BridgeTransfer b : transfers) { - assertThat(this.repository.getBalance(new AionAddress(b.getRecipient()))) + assertThat(this.repository.getBalance(new Address(b.getRecipient()))) .isEqualTo(BigInteger.ZERO); } assertThat(this.repository.getBalance(CONTRACT_ADDR)).isEqualTo(BigInteger.valueOf(10)); @@ -2013,7 +2013,7 @@ private ReturnDataFromSetup setupForTest(BridgeTransfer[] transfers, ECKey[] mem // need to change the execution context ExecutionContext submitBundleContext = context( - new AionAddress(members[0].getAddress()), + new Address(members[0].getAddress()), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY); this.contract = @@ -2121,7 +2121,7 @@ public void testRingLocked() { PrecompiledTransactionResult transferResult = this.contract.execute(callPayload, DEFAULT_NRG); assertThat(transferResult.getResultCode()).isEqualTo(PrecompiledResultCode.SUCCESS); - assertThat(transferResult.getReturnData()).isEqualTo(DataWord.ONE.getData()); + assertThat(transferResult.getReturnData()).isEqualTo(DataWordImpl.ONE.getData()); // lock the ring this.connector.setRingLocked(false); @@ -2133,7 +2133,7 @@ public void testRingLocked() { PrecompiledTransactionResult transferResult2 = this.contract.execute(callPayload2, DEFAULT_NRG); assertThat(transferResult2.getResultCode()).isEqualTo(PrecompiledResultCode.SUCCESS); - assertThat(transferResult2.getReturnData()).isEqualTo(DataWord.ZERO.getData()); + assertThat(transferResult2.getReturnData()).isEqualTo(DataWordImpl.ZERO.getData()); } @Test @@ -2167,7 +2167,7 @@ public void testMinThreshold() { this.contract.execute(callPayload, DEFAULT_NRG); assertThat(transferResult.getResultCode()).isEqualTo(PrecompiledResultCode.SUCCESS); assertThat(transferResult.getReturnData()) - .isEqualTo(new DataWord(new BigInteger("3")).getData()); + .isEqualTo(new DataWordImpl(new BigInteger("3")).getData()); // explicitly set the min threshold to 5 this.connector.setMinThresh(5); @@ -2180,7 +2180,7 @@ public void testMinThreshold() { this.contract.execute(callPayload2, DEFAULT_NRG); assertThat(transferResult2.getResultCode()).isEqualTo(PrecompiledResultCode.SUCCESS); assertThat(transferResult2.getReturnData()) - .isEqualTo(new DataWord(new BigInteger("5")).getData()); + .isEqualTo(new DataWordImpl(new BigInteger("5")).getData()); // try setting threshold greater than number of validator members this.connector.setMinThresh(10); @@ -2193,7 +2193,7 @@ public void testMinThreshold() { this.contract.execute(callPayload3, DEFAULT_NRG); assertThat(transferResult3.getResultCode()).isEqualTo(PrecompiledResultCode.SUCCESS); assertThat(transferResult3.getReturnData()) - .isEqualTo(new DataWord(new BigInteger("10")).getData()); + .isEqualTo(new DataWordImpl(new BigInteger("10")).getData()); } @Test @@ -2227,7 +2227,7 @@ public void testMemberCount() { this.contract.execute(callPayload, DEFAULT_NRG); assertThat(transferResult.getResultCode()).isEqualTo(PrecompiledResultCode.SUCCESS); assertThat(transferResult.getReturnData()) - .isEqualTo(new DataWord(new BigInteger("5")).getData()); + .isEqualTo(new DataWordImpl(new BigInteger("5")).getData()); // explicitly set the member count to 10 this.connector.setMemberCount(10); @@ -2240,7 +2240,7 @@ public void testMemberCount() { this.contract.execute(callPayload2, DEFAULT_NRG); assertThat(transferResult2.getResultCode()).isEqualTo(PrecompiledResultCode.SUCCESS); assertThat(transferResult2.getReturnData()) - .isEqualTo(new DataWord(new BigInteger("10")).getData()); + .isEqualTo(new DataWordImpl(new BigInteger("10")).getData()); } @Test @@ -2376,7 +2376,7 @@ public void testAddRingMemberNotOwner() { this.contract = new TokenBridgeContract( context( - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY), this.repository, @@ -2528,7 +2528,7 @@ public void testRemoveRingMemberNotOwner() { this.contract = new TokenBridgeContract( context( - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY), this.repository, @@ -2583,7 +2583,7 @@ public void testSetReplayer() { assertThat(result.getResultCode()).isEqualTo(PrecompiledResultCode.SUCCESS); // caller not owner - fail - Address address1 = AionAddress.wrap(ECKeyFac.inst().create().getAddress()); + Address address1 = Address.wrap(ECKeyFac.inst().create().getAddress()); this.contract = new TokenBridgeContract( context(address1, CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY), @@ -2609,7 +2609,7 @@ public void testFallbackTransaction() { this.contract = new TokenBridgeContract( context( - AionAddress.ZERO_ADDRESS(), + Address.ZERO_ADDRESS(), CONTRACT_ADDR, ByteUtil.EMPTY_BYTE_ARRAY), this.repository, diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/AionAuctionContractTest.java b/modPrecompiled/test/org/aion/precompiled/contracts/AionAuctionContractTest.java index 888d2da35f..7429b754d0 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/AionAuctionContractTest.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/AionAuctionContractTest.java @@ -6,8 +6,8 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.crypto.HashUtil; @@ -18,7 +18,7 @@ import org.aion.mcf.db.IBlockStoreBase; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; -import org.aion.vm.api.interfaces.Address; + import org.aion.zero.impl.StandaloneBlockchain; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.types.AionTransaction; @@ -33,12 +33,12 @@ public class AionAuctionContractTest { // use this addr for test to trigger test time periods private static final Address AION = - AionAddress.wrap("0xa0eeaeabdbc92953b072afbd21f3e3fd8a4a4f5e6a6e22200db746ab75e9a99a"); + Address.wrap("0xa0eeaeabdbc92953b072afbd21f3e3fd8a4a4f5e6a6e22200db746ab75e9a99a"); private Address domainAddress1 = - AionAddress.wrap("a011111111111111111111111111111101010101010101010101010101010101"); + Address.wrap("a011111111111111111111111111111101010101010101010101010101010101"); private String domainName1 = "bion.aion"; private String domainName2 = "cion.aion.aion"; - private IRepositoryCache> repo; + private RepositoryCache> repo; private AionAuctionContract testAAC; private ECKey defaultKey; @@ -62,21 +62,21 @@ public void setup() { repo = new DummyRepo(); defaultKey = ECKeyFac.inst().create(); testAAC = new AionAuctionContract(repo, AION, blockchain); - repo.createAccount(AionAddress.wrap(defaultKey.getAddress())); - repo.addBalance(AionAddress.wrap(defaultKey.getAddress()), new BigInteger("4000000")); + repo.createAccount(Address.wrap(defaultKey.getAddress())); + repo.addBalance(Address.wrap(defaultKey.getAddress()), new BigInteger("4000000")); k = ECKeyFac.inst().create(); k2 = ECKeyFac.inst().create(); k3 = ECKeyFac.inst().create(); k4 = ECKeyFac.inst().create(); - repo.createAccount(AionAddress.wrap(k.getAddress())); - repo.createAccount(AionAddress.wrap(k2.getAddress())); - repo.createAccount(AionAddress.wrap(k3.getAddress())); - repo.createAccount(AionAddress.wrap(k4.getAddress())); - repo.addBalance(AionAddress.wrap(k.getAddress()), new BigInteger("10000")); - repo.addBalance(AionAddress.wrap(k2.getAddress()), new BigInteger("10000")); - repo.addBalance(AionAddress.wrap(k3.getAddress()), new BigInteger("10000")); - repo.addBalance(AionAddress.wrap(k4.getAddress()), new BigInteger("10000")); + repo.createAccount(Address.wrap(k.getAddress())); + repo.createAccount(Address.wrap(k2.getAddress())); + repo.createAccount(Address.wrap(k3.getAddress())); + repo.createAccount(Address.wrap(k4.getAddress())); + repo.addBalance(Address.wrap(k.getAddress()), new BigInteger("10000")); + repo.addBalance(Address.wrap(k2.getAddress()), new BigInteger("10000")); + repo.addBalance(Address.wrap(k3.getAddress()), new BigInteger("10000")); + repo.addBalance(Address.wrap(k4.getAddress()), new BigInteger("10000")); } @Test() @@ -87,7 +87,7 @@ public void newTest() { byte[] combined = setupInputs( "12312421412.41dsfsdgsdg.aion", - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), amount.toByteArray(), defaultKey); AionAuctionContract aac = new AionAuctionContract(repo, AION, blockchain); @@ -108,36 +108,36 @@ public void testWithANS() { BigInteger amount = new BigInteger("1000"); byte[] combined = - setupInputs(domainName2, AionAddress.wrap(k.getAddress()), amount.toByteArray(), k); + setupInputs(domainName2, Address.wrap(k.getAddress()), amount.toByteArray(), k); AionAuctionContract aac = new AionAuctionContract(repo, AION, blockchain); PrecompiledTransactionResult result = aac.execute(combined, inputEnergy); BigInteger amount4 = new BigInteger("6000"); byte[] combined4 = setupInputs( - domainName2, AionAddress.wrap(k4.getAddress()), amount4.toByteArray(), k4); + domainName2, Address.wrap(k4.getAddress()), amount4.toByteArray(), k4); AionAuctionContract aac4 = new AionAuctionContract(repo, AION, blockchain); aac4.execute(combined4, inputEnergy); BigInteger amount2 = new BigInteger("5000"); byte[] combined2 = setupInputs( - domainName2, AionAddress.wrap(k2.getAddress()), amount2.toByteArray(), k2); + domainName2, Address.wrap(k2.getAddress()), amount2.toByteArray(), k2); AionAuctionContract aac2 = new AionAuctionContract(repo, AION, blockchain); aac2.execute(combined2, inputEnergy); BigInteger amount3 = new BigInteger("2000"); byte[] combined3 = setupInputs( - domainName2, AionAddress.wrap(k3.getAddress()), amount3.toByteArray(), k3); + domainName2, Address.wrap(k3.getAddress()), amount3.toByteArray(), k3); AionAuctionContract aac3 = new AionAuctionContract(repo, AION, blockchain); aac3.execute(combined3, inputEnergy); // check balances after bidding - assertEquals(9000, repo.getBalance(AionAddress.wrap(k.getAddress())).intValue()); - assertEquals(5000, repo.getBalance(AionAddress.wrap(k2.getAddress())).intValue()); - assertEquals(8000, repo.getBalance(AionAddress.wrap(k3.getAddress())).intValue()); - assertEquals(4000, repo.getBalance(AionAddress.wrap(k4.getAddress())).intValue()); // winner + assertEquals(9000, repo.getBalance(Address.wrap(k.getAddress())).intValue()); + assertEquals(5000, repo.getBalance(Address.wrap(k2.getAddress())).intValue()); + assertEquals(8000, repo.getBalance(Address.wrap(k3.getAddress())).intValue()); + assertEquals(4000, repo.getBalance(Address.wrap(k4.getAddress())).intValue()); // winner try { Thread.sleep(3 * 1000L); @@ -146,18 +146,18 @@ public void testWithANS() { } // check balances after auction, balances should be returned - assertEquals(10000, repo.getBalance(AionAddress.wrap(k.getAddress())).intValue()); - assertEquals(10000, repo.getBalance(AionAddress.wrap(k2.getAddress())).intValue()); - assertEquals(10000, repo.getBalance(AionAddress.wrap(k3.getAddress())).intValue()); + assertEquals(10000, repo.getBalance(Address.wrap(k.getAddress())).intValue()); + assertEquals(10000, repo.getBalance(Address.wrap(k2.getAddress())).intValue()); + assertEquals(10000, repo.getBalance(Address.wrap(k3.getAddress())).intValue()); assertEquals( 5000, - repo.getBalance(AionAddress.wrap(k4.getAddress())).intValue()); // deposits 5000 + repo.getBalance(Address.wrap(k4.getAddress())).intValue()); // deposits 5000 AionNameServiceContract ansc2 = new AionNameServiceContract( repo, - AionAddress.wrap(result.getReturnData()), - AionAddress.wrap(k4.getAddress())); + Address.wrap(result.getReturnData()), + Address.wrap(k4.getAddress())); assertEquals(PrecompiledResultCode.SUCCESS, result.getResultCode()); } @@ -166,28 +166,28 @@ public void testCheckBidBalances() { final long inputEnergy = 24000L; BigInteger amount = new BigInteger("1000"); byte[] combined = - setupInputs(domainName1, AionAddress.wrap(k.getAddress()), amount.toByteArray(), k); + setupInputs(domainName1, Address.wrap(k.getAddress()), amount.toByteArray(), k); AionAuctionContract aac = new AionAuctionContract(repo, AION, blockchain); aac.execute(combined, inputEnergy); BigInteger amount2 = new BigInteger("3000"); byte[] combined2 = setupInputs( - domainName1, AionAddress.wrap(k2.getAddress()), amount2.toByteArray(), k2); + domainName1, Address.wrap(k2.getAddress()), amount2.toByteArray(), k2); AionAuctionContract aac2 = new AionAuctionContract(repo, AION, blockchain); aac2.execute(combined2, inputEnergy); BigInteger amount3 = new BigInteger("2000"); byte[] combined3 = setupInputs( - domainName1, AionAddress.wrap(k3.getAddress()), amount3.toByteArray(), k3); + domainName1, Address.wrap(k3.getAddress()), amount3.toByteArray(), k3); AionAuctionContract aac3 = new AionAuctionContract(repo, AION, blockchain); aac3.execute(combined3, inputEnergy); BigInteger amount4 = new BigInteger("5000"); byte[] combined4 = setupInputs( - domainName1, AionAddress.wrap(k4.getAddress()), amount4.toByteArray(), k4); + domainName1, Address.wrap(k4.getAddress()), amount4.toByteArray(), k4); AionAuctionContract aac4 = new AionAuctionContract(repo, AION, blockchain); aac4.execute(combined4, inputEnergy); @@ -198,31 +198,31 @@ public void testCheckBidBalances() { } // check balances after bidding - assertEquals(9000, repo.getBalance(AionAddress.wrap(k.getAddress())).intValue()); - assertEquals(7000, repo.getBalance(AionAddress.wrap(k2.getAddress())).intValue()); - assertEquals(8000, repo.getBalance(AionAddress.wrap(k3.getAddress())).intValue()); - assertEquals(5000, repo.getBalance(AionAddress.wrap(k4.getAddress())).intValue()); + assertEquals(9000, repo.getBalance(Address.wrap(k.getAddress())).intValue()); + assertEquals(7000, repo.getBalance(Address.wrap(k2.getAddress())).intValue()); + assertEquals(8000, repo.getBalance(Address.wrap(k3.getAddress())).intValue()); + assertEquals(5000, repo.getBalance(Address.wrap(k4.getAddress())).intValue()); BigInteger amount6 = new BigInteger("2000"); byte[] combined6 = setupInputs( - domainName2, AionAddress.wrap(k.getAddress()), amount6.toByteArray(), k); + domainName2, Address.wrap(k.getAddress()), amount6.toByteArray(), k); AionAuctionContract aac6 = new AionAuctionContract(repo, AION, blockchain); aac6.execute(combined6, inputEnergy); BigInteger amount7 = new BigInteger("4000"); byte[] combined7 = setupInputs( - domainName2, AionAddress.wrap(k2.getAddress()), amount7.toByteArray(), k2); + domainName2, Address.wrap(k2.getAddress()), amount7.toByteArray(), k2); AionAuctionContract aac7 = new AionAuctionContract(repo, AION, blockchain); aac7.execute(combined7, inputEnergy); // check balances after bidding both domains - assertEquals(7000, repo.getBalance(AionAddress.wrap(k.getAddress())).intValue()); - assertEquals(3000, repo.getBalance(AionAddress.wrap(k2.getAddress())).intValue()); - assertEquals(8000, repo.getBalance(AionAddress.wrap(k3.getAddress())).intValue()); - assertEquals(5000, repo.getBalance(AionAddress.wrap(k4.getAddress())).intValue()); + assertEquals(7000, repo.getBalance(Address.wrap(k.getAddress())).intValue()); + assertEquals(3000, repo.getBalance(Address.wrap(k2.getAddress())).intValue()); + assertEquals(8000, repo.getBalance(Address.wrap(k3.getAddress())).intValue()); + assertEquals(5000, repo.getBalance(Address.wrap(k4.getAddress())).intValue()); try { Thread.sleep(2500L); @@ -231,10 +231,10 @@ public void testCheckBidBalances() { } // check balances after both auctions are complete, winners should have their deposits gone - assertEquals(10000, repo.getBalance(AionAddress.wrap(k.getAddress())).intValue()); - assertEquals(8000, repo.getBalance(AionAddress.wrap(k2.getAddress())).intValue()); - assertEquals(10000, repo.getBalance(AionAddress.wrap(k3.getAddress())).intValue()); - assertEquals(7000, repo.getBalance(AionAddress.wrap(k4.getAddress())).intValue()); + assertEquals(10000, repo.getBalance(Address.wrap(k.getAddress())).intValue()); + assertEquals(8000, repo.getBalance(Address.wrap(k2.getAddress())).intValue()); + assertEquals(10000, repo.getBalance(Address.wrap(k3.getAddress())).intValue()); + assertEquals(7000, repo.getBalance(Address.wrap(k4.getAddress())).intValue()); try { Thread.sleep(2 * 1000L); @@ -244,10 +244,10 @@ public void testCheckBidBalances() { // check balances after both domains become inactive, all accounts should have their // original balance - assertEquals(10000, repo.getBalance(AionAddress.wrap(k.getAddress())).intValue()); - assertEquals(10000, repo.getBalance(AionAddress.wrap(k2.getAddress())).intValue()); - assertEquals(10000, repo.getBalance(AionAddress.wrap(k3.getAddress())).intValue()); - assertEquals(10000, repo.getBalance(AionAddress.wrap(k4.getAddress())).intValue()); + assertEquals(10000, repo.getBalance(Address.wrap(k.getAddress())).intValue()); + assertEquals(10000, repo.getBalance(Address.wrap(k2.getAddress())).intValue()); + assertEquals(10000, repo.getBalance(Address.wrap(k3.getAddress())).intValue()); + assertEquals(10000, repo.getBalance(Address.wrap(k4.getAddress())).intValue()); } @Test() @@ -261,20 +261,20 @@ public void testQuery() { BigInteger amount4 = new BigInteger("4000"); byte[] combined = - setupInputs("aion.aion", AionAddress.wrap(k.getAddress()), amount.toByteArray(), k); + setupInputs("aion.aion", Address.wrap(k.getAddress()), amount.toByteArray(), k); AionAuctionContract aac = new AionAuctionContract(repo, AION, blockchain); aac.execute(combined, DEFAULT_INPUT_NRG); byte[] combined2 = setupInputs( - "aaaa.aion", AionAddress.wrap(k.getAddress()), amount2.toByteArray(), k); + "aaaa.aion", Address.wrap(k.getAddress()), amount2.toByteArray(), k); AionAuctionContract aac2 = new AionAuctionContract(repo, AION, blockchain); aac.execute(combined2, DEFAULT_INPUT_NRG); byte[] combined3 = setupInputs( "bbbb.aaaa.aion", - AionAddress.wrap(k2.getAddress()), + Address.wrap(k2.getAddress()), amount3.toByteArray(), k2); AionAuctionContract aac3 = new AionAuctionContract(repo, AION, blockchain); @@ -282,7 +282,7 @@ public void testQuery() { byte[] combined8 = setupInputs( - "aion.aion", AionAddress.wrap(k.getAddress()), amount2.toByteArray(), k); + "aion.aion", Address.wrap(k.getAddress()), amount2.toByteArray(), k); AionAuctionContract aac8 = new AionAuctionContract(repo, AION, blockchain); aac.execute(combined8, DEFAULT_INPUT_NRG); @@ -291,22 +291,22 @@ public void testQuery() { // displayAuctionDomainLRU Tests, show with debug aac.execute( - setupInputs("111.aion", AionAddress.wrap(k.getAddress()), amount.toByteArray(), k), + setupInputs("111.aion", Address.wrap(k.getAddress()), amount.toByteArray(), k), DEFAULT_INPUT_NRG); aac.execute( - setupInputs("222.aion", AionAddress.wrap(k.getAddress()), amount.toByteArray(), k), + setupInputs("222.aion", Address.wrap(k.getAddress()), amount.toByteArray(), k), DEFAULT_INPUT_NRG); aac.execute( - setupInputs("333.aion", AionAddress.wrap(k.getAddress()), amount.toByteArray(), k), + setupInputs("333.aion", Address.wrap(k.getAddress()), amount.toByteArray(), k), DEFAULT_INPUT_NRG); aac.execute( - setupInputs("444.aion", AionAddress.wrap(k.getAddress()), amount.toByteArray(), k), + setupInputs("444.aion", Address.wrap(k.getAddress()), amount.toByteArray(), k), DEFAULT_INPUT_NRG); aac.execute( - setupInputs("555.aion", AionAddress.wrap(k.getAddress()), amount.toByteArray(), k), + setupInputs("555.aion", Address.wrap(k.getAddress()), amount.toByteArray(), k), DEFAULT_INPUT_NRG); aac.execute( - setupInputs("666.aion", AionAddress.wrap(k.getAddress()), amount.toByteArray(), k), + setupInputs("666.aion", Address.wrap(k.getAddress()), amount.toByteArray(), k), DEFAULT_INPUT_NRG); aac.displayAuctionDomainLRU("111.aion"); // 1 aac.displayAuctionDomainLRU("222.aion"); // 1 2 @@ -334,7 +334,7 @@ public void testQuery() { byte[] combined4 = setupInputs( "cccc.aaaa.aion", - AionAddress.wrap(k.getAddress()), + Address.wrap(k.getAddress()), amount3.toByteArray(), k); AionAuctionContract aac4 = new AionAuctionContract(repo, AION, blockchain); @@ -343,7 +343,7 @@ public void testQuery() { byte[] combined6 = setupInputs( "cccc.aaaa.aion", - AionAddress.wrap(k2.getAddress()), + Address.wrap(k2.getAddress()), amount.toByteArray(), k2); AionAuctionContract aac6 = new AionAuctionContract(repo, AION, blockchain); @@ -352,7 +352,7 @@ public void testQuery() { byte[] combined7 = setupInputs( "cccc.aaaa.aion", - AionAddress.wrap(k2.getAddress()), + Address.wrap(k2.getAddress()), amount4.toByteArray(), k2); AionAuctionContract aac7 = new AionAuctionContract(repo, AION, blockchain); @@ -384,7 +384,7 @@ public void testActiveDomainTimeExtensionRequestPass() { BigInteger amount = new BigInteger("1000"); byte[] combined = - setupInputs(domainName1, AionAddress.wrap(k.getAddress()), amount.toByteArray(), k); + setupInputs(domainName1, Address.wrap(k.getAddress()), amount.toByteArray(), k); AionAuctionContract aac = new AionAuctionContract(repo, AION, blockchain); aac.execute(combined, inputEnergy); @@ -395,11 +395,11 @@ public void testActiveDomainTimeExtensionRequestPass() { } // try to extend - should work - byte[] combined2 = setupForExtension(domainName1, AionAddress.wrap(k.getAddress())); + byte[] combined2 = setupForExtension(domainName1, Address.wrap(k.getAddress())); PrecompiledTransactionResult res = aac.execute(combined2, inputEnergy); // try to extend 2nd time in a row - should be denied - byte[] combined3 = setupForExtension(domainName1, AionAddress.wrap(k.getAddress())); + byte[] combined3 = setupForExtension(domainName1, Address.wrap(k.getAddress())); PrecompiledTransactionResult res2 = aac.execute(combined3, inputEnergy); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); @@ -421,7 +421,7 @@ public void testActiveDomainTimeExtensionRequestFailure() { BigInteger amount = new BigInteger("1000"); byte[] combined = - setupInputs(domainName1, AionAddress.wrap(k.getAddress()), amount.toByteArray(), k); + setupInputs(domainName1, Address.wrap(k.getAddress()), amount.toByteArray(), k); AionAuctionContract aac = new AionAuctionContract(repo, AION, blockchain); aac.execute(combined, inputEnergy); @@ -432,7 +432,7 @@ public void testActiveDomainTimeExtensionRequestFailure() { } // try to extend - should not work since owner is incorrect - byte[] combined2 = setupForExtension(domainName1, AionAddress.wrap(k2.getAddress())); + byte[] combined2 = setupForExtension(domainName1, Address.wrap(k2.getAddress())); PrecompiledTransactionResult res = aac.execute(combined2, inputEnergy); assertEquals(PrecompiledResultCode.FAILURE, res.getResultCode()); @@ -445,7 +445,7 @@ public void testHasActiveParentDomain() { byte[] combined = setupInputs( - "parent.aion", AionAddress.wrap(k.getAddress()), amount.toByteArray(), k); + "parent.aion", Address.wrap(k.getAddress()), amount.toByteArray(), k); AionAuctionContract aac = new AionAuctionContract(repo, AION, blockchain); aac.execute(combined, inputEnergy); @@ -459,7 +459,7 @@ public void testHasActiveParentDomain() { byte[] combined2 = setupInputs( "child.parent.aion", - AionAddress.wrap(k.getAddress()), + Address.wrap(k.getAddress()), amount.toByteArray(), k); AionAuctionContract aac2 = new AionAuctionContract(repo, AION, blockchain); @@ -472,7 +472,7 @@ public void testHasActiveParentDomain() { public void testUnregisteredDomain() { ECKey k = ECKeyFac.inst().create(); AionNameServiceContract ansc = - new AionNameServiceContract(repo, domainAddress1, AionAddress.wrap(k.getAddress())); + new AionNameServiceContract(repo, domainAddress1, Address.wrap(k.getAddress())); } @Test() @@ -480,7 +480,7 @@ public void testInvalidDomainNames() { byte[] combined = setupInputs( "aa.aion", - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), defaultBidAmount.toByteArray(), defaultKey); AionAuctionContract aac = new AionAuctionContract(repo, AION, blockchain); @@ -490,7 +490,7 @@ public void testInvalidDomainNames() { byte[] combined2 = setupInputs( "#$%aion.aion", - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), defaultBidAmount.toByteArray(), defaultKey); AionAuctionContract aac2 = new AionAuctionContract(repo, AION, blockchain); @@ -500,7 +500,7 @@ public void testInvalidDomainNames() { byte[] combined3 = setupInputs( "withoutdotaion", - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), defaultBidAmount.toByteArray(), defaultKey); AionAuctionContract aac3 = new AionAuctionContract(repo, AION, blockchain); @@ -510,7 +510,7 @@ public void testInvalidDomainNames() { byte[] combined4 = setupInputs( "ai.ai.ai.ai.aion", - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), defaultBidAmount.toByteArray(), defaultKey); AionAuctionContract aac4 = new AionAuctionContract(repo, AION, blockchain); @@ -520,7 +520,7 @@ public void testInvalidDomainNames() { byte[] combined5 = setupInputs( "network.aion", - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), defaultBidAmount.toByteArray(), defaultKey); AionAuctionContract aac5 = new AionAuctionContract(repo, AION, blockchain); @@ -534,7 +534,7 @@ public void testBidderAddressDoesNotExist() { byte[] combined = setupInputs( "bion.bion.aion", - AionAddress.wrap(notExistKey.getAddress()), + Address.wrap(notExistKey.getAddress()), defaultBidAmount.toByteArray(), notExistKey); AionAuctionContract aac = new AionAuctionContract(repo, AION, blockchain); @@ -546,13 +546,13 @@ public void testBidderAddressDoesNotExist() { @Test public void testInsufficientBalance() { ECKey poorKey = ECKeyFac.inst().create(); - repo.createAccount(AionAddress.wrap(poorKey.getAddress())); - repo.addBalance(AionAddress.wrap(poorKey.getAddress()), new BigInteger("100")); + repo.createAccount(Address.wrap(poorKey.getAddress())); + repo.addBalance(Address.wrap(poorKey.getAddress()), new BigInteger("100")); byte[] combined3 = setupInputs( domainName1, - AionAddress.wrap(poorKey.getAddress()), + Address.wrap(poorKey.getAddress()), defaultBidAmount.toByteArray(), poorKey); PrecompiledTransactionResult result = testAAC.execute(combined3, DEFAULT_INPUT_NRG); @@ -565,13 +565,13 @@ public void testIncorrectInputLength() { byte[] input = setupInputs( domainName1, - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), defaultBidAmount.toByteArray(), defaultKey); byte[] wrongInput = new byte[130]; byte[] wrongInput2 = new byte[131]; byte[] wrongInput3 = - setupForExtension(domainName1, AionAddress.wrap(defaultKey.getAddress())); + setupForExtension(domainName1, Address.wrap(defaultKey.getAddress())); byte[] wrongInput5 = new byte[wrongInput3.length]; byte[] wrongInput4 = new byte[input.length - 2]; @@ -595,7 +595,7 @@ public void testIncorrectSignature() { byte[] input = setupInputs( domainName1, - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), defaultBidAmount.toByteArray(), defaultKey); // modify the signature in the 65th byte (arbitrarily) @@ -614,7 +614,7 @@ public void testIncorrectPublicKey() { byte[] input = setupInputs( domainName1, - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), defaultBidAmount.toByteArray(), anotherKey); PrecompiledTransactionResult result = testAAC.execute(input, DEFAULT_INPUT_NRG); @@ -629,7 +629,7 @@ public void testInsufficientEnergy() { byte[] input = setupInputs( domainName1, - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), defaultBidAmount.toByteArray(), defaultKey); PrecompiledTransactionResult result = testAAC.execute(input, 18000); @@ -645,7 +645,7 @@ public void testNegativeBidValue() { byte[] input = setupInputs( domainName1, - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), negativeBidAmount.toByteArray(), defaultKey); PrecompiledTransactionResult result = testAAC.execute(input, DEFAULT_INPUT_NRG); @@ -660,7 +660,7 @@ public void testRequestedDomainIsAlreadyActive() { byte[] input = setupInputs( domainName1, - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), defaultBidAmount.toByteArray(), defaultKey); testAAC.execute(input, DEFAULT_INPUT_NRG); @@ -679,7 +679,7 @@ public void testRequestedDomainIsAlreadyActive() { byte[] input2 = setupInputs( domainName1, - AionAddress.wrap(k2.getAddress()), + Address.wrap(k2.getAddress()), bidAmount2.toByteArray(), k2); PrecompiledTransactionResult result2 = aac2.execute(input2, DEFAULT_INPUT_NRG); @@ -695,7 +695,7 @@ public void testOverwritingBidsWithSmallerValue() { byte[] input = setupInputs( domainName1, - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), defaultBidAmount.toByteArray(), defaultKey); PrecompiledTransactionResult result = testAAC.execute(input, DEFAULT_INPUT_NRG); @@ -704,7 +704,7 @@ public void testOverwritingBidsWithSmallerValue() { byte[] input2 = setupInputs( domainName1, - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newBidAmount.toByteArray(), defaultKey); PrecompiledTransactionResult result2 = testAAC.execute(input2, DEFAULT_INPUT_NRG); @@ -713,7 +713,7 @@ public void testOverwritingBidsWithSmallerValue() { byte[] input3 = setupInputs( domainName1, - AionAddress.wrap(k2.getAddress()), + Address.wrap(k2.getAddress()), anotherBid.toByteArray(), k2); PrecompiledTransactionResult result3 = testAAC.execute(input3, DEFAULT_INPUT_NRG); @@ -731,7 +731,7 @@ public void testOverwritingBidsWithLargerValue() { byte[] input3 = setupInputs( domainName1, - AionAddress.wrap(k2.getAddress()), + Address.wrap(k2.getAddress()), anotherBid.toByteArray(), k2); PrecompiledTransactionResult result3 = testAAC.execute(input3, DEFAULT_INPUT_NRG); @@ -739,7 +739,7 @@ public void testOverwritingBidsWithLargerValue() { byte[] input = setupInputs( domainName1, - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), defaultBidAmount.toByteArray(), defaultKey); PrecompiledTransactionResult result = testAAC.execute(input, DEFAULT_INPUT_NRG); @@ -748,7 +748,7 @@ public void testOverwritingBidsWithLargerValue() { byte[] input2 = setupInputs( domainName1, - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newBidAmount.toByteArray(), defaultKey); PrecompiledTransactionResult result2 = testAAC.execute(input2, DEFAULT_INPUT_NRG); @@ -765,7 +765,7 @@ public void testRequestInactiveDomain() { byte[] input = setupInputs( domainName1, - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), defaultBidAmount.toByteArray(), defaultKey); testAAC.execute(input, DEFAULT_INPUT_NRG); @@ -775,7 +775,7 @@ public void testRequestInactiveDomain() { byte[] input3 = setupInputs( domainName1, - AionAddress.wrap(k3.getAddress()), + Address.wrap(k3.getAddress()), anotherAmount.toByteArray(), k3); aac3.execute(input3, DEFAULT_INPUT_NRG); @@ -791,7 +791,7 @@ public void testRequestInactiveDomain() { byte[] input2 = setupInputs( domainName1, - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), defaultBidAmount.toByteArray(), defaultKey); PrecompiledTransactionResult result2 = testAAC.execute(input2, DEFAULT_INPUT_NRG); @@ -877,12 +877,12 @@ private static AionBlock createBundleAndCheck( StandaloneBlockchain bc, ECKey key, AionBlock parentBlock) { byte[] ZERO_BYTE = new byte[0]; - BigInteger accountNonce = bc.getRepository().getNonce(new AionAddress(key.getAddress())); + BigInteger accountNonce = bc.getRepository().getNonce(new Address(key.getAddress())); List transactions = new ArrayList<>(); // create 100 transactions per bundle for (int i = 0; i < 100; i++) { - Address destAddr = new AionAddress(HashUtil.h256(accountNonce.toByteArray())); + Address destAddr = new Address(HashUtil.h256(accountNonce.toByteArray())); AionTransaction sendTransaction = new AionTransaction( accountNonce.toByteArray(), diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/AionNameServiceContractTest.java b/modPrecompiled/test/org/aion/precompiled/contracts/AionNameServiceContractTest.java index 6ac6f0467c..26f192ff07 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/AionNameServiceContractTest.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/AionNameServiceContractTest.java @@ -10,8 +10,9 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.crypto.HashUtil; @@ -21,10 +22,9 @@ import org.aion.mcf.core.IBlockchain; import org.aion.mcf.core.ImportResult; import org.aion.mcf.db.IBlockStoreBase; -import org.aion.mcf.vm.types.DataWord; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; -import org.aion.vm.api.interfaces.Address; + import org.aion.zero.impl.StandaloneBlockchain; import org.aion.zero.impl.types.AionBlock; import org.aion.zero.types.AionTransaction; @@ -50,42 +50,42 @@ public class AionNameServiceContractTest { private String notSubdomain = "aion.bion"; // not a subdomain of domainName1 private static final Address AION = - AionAddress.wrap("0xa0eeaeabdbc92953b072afbd21f3e3fd8a4a4f5e6a6e22200db746ab75e9a99a"); + Address.wrap("0xa0eeaeabdbc92953b072afbd21f3e3fd8a4a4f5e6a6e22200db746ab75e9a99a"); private Address emptyAddress = - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000000"); + Address.wrap("0000000000000000000000000000000000000000000000000000000000000000"); private Address domainAddress1 = - AionAddress.wrap("a011111111111111111111111111111101010101010101010101010101010101"); + Address.wrap("a011111111111111111111111111111101010101010101010101010101010101"); private Address domainAddress2 = - AionAddress.wrap("a022222222222222222222222222222202020202020202020202020202020202"); + Address.wrap("a022222222222222222222222222222202020202020202020202020202020202"); private Address domainAddress3 = - AionAddress.wrap("a033333333333333333333333333333303030303030303030303030303030303"); + Address.wrap("a033333333333333333333333333333303030303030303030303030303030303"); private Address domainAddress4 = - AionAddress.wrap("a044444444444444444444444444444404040404040404040404040404040404"); + Address.wrap("a044444444444444444444444444444404040404040404040404040404040404"); private Address domainAddress5 = - AionAddress.wrap("a055555555555555555555555555555505050505050050505050505050505050"); + Address.wrap("a055555555555555555555555555555505050505050050505050505050505050"); private Address domainAddress6 = - AionAddress.wrap("a066666666666666666666666666666606060606060606060606060606060060"); + Address.wrap("a066666666666666666666666666666606060606060606060606060606060060"); private Address invalidDomainAddress = - AionAddress.wrap("b066666666666666666666666666666606060606060606060606060606060606"); + Address.wrap("b066666666666666666666666666666606060606060606060606060606060606"); private Address newAddress1 = - AionAddress.wrap("1000000000000000000000000000000000000000000000000000000000000001"); + Address.wrap("1000000000000000000000000000000000000000000000000000000000000001"); private Address newAddress2 = - AionAddress.wrap("0100000000000000000000000000000000000000000000000000000000000010"); + Address.wrap("0100000000000000000000000000000000000000000000000000000000000010"); private Address newAddress3 = - AionAddress.wrap("0010000000000000000000000000000000000000000000000000000000000100"); + Address.wrap("0010000000000000000000000000000000000000000000000000000000000100"); private Address newAddress4 = - AionAddress.wrap("0001000000000000000000000000000000000000000000000000000000001000"); + Address.wrap("0001000000000000000000000000000000000000000000000000000000001000"); private Address newAddress5 = - AionAddress.wrap("0000100000000000000000000000000000000000000000000000000000010000"); + Address.wrap("0000100000000000000000000000000000000000000000000000000000010000"); private Address newAddress6 = - AionAddress.wrap("0000010000000000000000000000000000000000000000000000000000100000"); + Address.wrap("0000010000000000000000000000000000000000000000000000000000100000"); private Address newAddress7 = - AionAddress.wrap("0000001000000000000000000000000000000000000000000000000001000000"); + Address.wrap("0000001000000000000000000000000000000000000000000000000001000000"); private Address newAddress8 = - AionAddress.wrap("0000000100000000000000000000000000000000000000000000000010000000"); + Address.wrap("0000000100000000000000000000000000000000000000000000000010000000"); - private IRepositoryCache> repo; + private RepositoryCache> repo; private ECKey defaultKey; private ECKey defaultKey2; private ECKey k; @@ -109,31 +109,31 @@ public void setup() { repo = populateRepo(); defaultKey = ECKeyFac.inst().create(); defaultKey2 = ECKeyFac.inst().create(); - repo.createAccount(AionAddress.wrap(defaultKey.getAddress())); - repo.createAccount(AionAddress.wrap(defaultKey2.getAddress())); - repo.addBalance(AionAddress.wrap(defaultKey.getAddress()), new BigInteger("10000")); - repo.addBalance(AionAddress.wrap(defaultKey2.getAddress()), new BigInteger("10000")); + repo.createAccount(Address.wrap(defaultKey.getAddress())); + repo.createAccount(Address.wrap(defaultKey2.getAddress())); + repo.addBalance(Address.wrap(defaultKey.getAddress()), new BigInteger("10000")); + repo.addBalance(Address.wrap(defaultKey2.getAddress()), new BigInteger("10000")); k = ECKeyFac.inst().create(); k2 = ECKeyFac.inst().create(); k3 = ECKeyFac.inst().create(); k4 = ECKeyFac.inst().create(); k5 = ECKeyFac.inst().create(); - repo.createAccount(AionAddress.wrap(k.getAddress())); - repo.createAccount(AionAddress.wrap(k2.getAddress())); - repo.createAccount(AionAddress.wrap(k3.getAddress())); - repo.createAccount(AionAddress.wrap(k4.getAddress())); - repo.createAccount(AionAddress.wrap(k5.getAddress())); - repo.addBalance(AionAddress.wrap(k.getAddress()), new BigInteger("10000")); - repo.addBalance(AionAddress.wrap(k2.getAddress()), new BigInteger("10000")); - repo.addBalance(AionAddress.wrap(k3.getAddress()), new BigInteger("10000")); - repo.addBalance(AionAddress.wrap(k4.getAddress()), new BigInteger("10000")); + repo.createAccount(Address.wrap(k.getAddress())); + repo.createAccount(Address.wrap(k2.getAddress())); + repo.createAccount(Address.wrap(k3.getAddress())); + repo.createAccount(Address.wrap(k4.getAddress())); + repo.createAccount(Address.wrap(k5.getAddress())); + repo.addBalance(Address.wrap(k.getAddress()), new BigInteger("10000")); + repo.addBalance(Address.wrap(k2.getAddress()), new BigInteger("10000")); + repo.addBalance(Address.wrap(k3.getAddress()), new BigInteger("10000")); + repo.addBalance(Address.wrap(k4.getAddress()), new BigInteger("10000")); BigInteger amount = new BigInteger("1000"); byte[] combined = setupInputs( domainName2, - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), amount.toByteArray(), defaultKey); AionAuctionContract aac = new AionAuctionContract(repo, AION, blockchain); @@ -149,7 +149,7 @@ public void setup() { byte[] combined2 = setupInputs( domainName3, - AionAddress.wrap(defaultKey2.getAddress()), + Address.wrap(defaultKey2.getAddress()), amount2.toByteArray(), defaultKey2); AionAuctionContract aac2 = new AionAuctionContract(repo, AION, blockchain); @@ -162,8 +162,8 @@ public void setup() { e.printStackTrace(); } - defaultAddress = AionAddress.wrap(result.getReturnData()); - defaultAddress2 = AionAddress.wrap(result2.getReturnData()); + defaultAddress = Address.wrap(result.getReturnData()); + defaultAddress2 = Address.wrap(result2.getReturnData()); } @After @@ -179,14 +179,14 @@ public void testInvalidValues() { AionNameServiceContract ansc = new AionNameServiceContract( - repo, defaultAddress, AionAddress.wrap(defaultKey.getAddress())); + repo, defaultAddress, Address.wrap(defaultKey.getAddress())); AionNameServiceContract ansc2 = new AionNameServiceContract( - repo, defaultAddress2, AionAddress.wrap(defaultKey2.getAddress())); + repo, defaultAddress2, Address.wrap(defaultKey2.getAddress())); byte[] combined = setupInputs( - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newAddress1, (byte) 0x0, (byte) 0x4, @@ -196,7 +196,7 @@ public void testInvalidValues() { "aion.aion"); byte[] combined2 = setupInputs( - AionAddress.wrap(defaultKey2.getAddress()), + Address.wrap(defaultKey2.getAddress()), newAddress2, (byte) 0x0, (byte) 0x4, @@ -226,7 +226,7 @@ public void testConstructorInvalidDomainAddress() { // domain addresses must have aion prefix: 0xa0(66char) or a0(64char) AionNameServiceContract ansc = new AionNameServiceContract( - repo, invalidDomainAddress, AionAddress.wrap(k.getAddress())); + repo, invalidDomainAddress, Address.wrap(k.getAddress())); assertNull(ansc); } @@ -250,7 +250,7 @@ public void testConflictOwnerAddress() { // check that the given owner address is the same as the owner address in the repository. AionNameServiceContract ansc = - new AionNameServiceContract(repo, domainAddress2, AionAddress.wrap(k.getAddress())); + new AionNameServiceContract(repo, domainAddress2, Address.wrap(k.getAddress())); assertNull(ansc); } @@ -258,7 +258,7 @@ public void testConflictOwnerAddress() { public void testUnavailableDomain() { AionNameServiceContract ansc = new AionNameServiceContract( - repo, domainAddress6, AionAddress.wrap(defaultKey.getAddress())); + repo, domainAddress6, Address.wrap(defaultKey.getAddress())); assertNull(ansc); } @@ -266,10 +266,10 @@ public void testUnavailableDomain() { public void testGetNameAndAddress() { AionNameServiceContract ansc = new AionNameServiceContract( - repo, defaultAddress, AionAddress.wrap(defaultKey.getAddress())); + repo, defaultAddress, Address.wrap(defaultKey.getAddress())); AionNameServiceContract ansc2 = new AionNameServiceContract( - repo, defaultAddress2, AionAddress.wrap(defaultKey2.getAddress())); + repo, defaultAddress2, Address.wrap(defaultKey2.getAddress())); assertEquals(domainName2, ansc.getRegisteredDomainName(defaultAddress)); assertEquals(domainName3, ansc.getRegisteredDomainName(defaultAddress2)); @@ -291,11 +291,11 @@ public void testTransferSubdomainOwnership() { AionNameServiceContract ansc = new AionNameServiceContract( - repo, defaultAddress, AionAddress.wrap(defaultKey.getAddress())); + repo, defaultAddress, Address.wrap(defaultKey.getAddress())); byte[] combined = setupInputs( - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newAddress5, (byte) 0x0, (byte) 0x4, @@ -321,11 +321,11 @@ public void testSetResolver() { // create ANS contract AionNameServiceContract ansc = new AionNameServiceContract( - repo, defaultAddress, AionAddress.wrap(defaultKey.getAddress())); + repo, defaultAddress, Address.wrap(defaultKey.getAddress())); byte[] combined = setupInputs( - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newAddress1, (byte) 0x0, (byte) 0x1, @@ -351,11 +351,11 @@ public void testSetTTL() { // create ANS contract AionNameServiceContract ansc = new AionNameServiceContract( - repo, defaultAddress, AionAddress.wrap(defaultKey.getAddress())); + repo, defaultAddress, Address.wrap(defaultKey.getAddress())); byte[] combined = setupInputs( - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newAddress1, (byte) 0x0, (byte) 0x2, @@ -381,7 +381,7 @@ public void testNotASubdomain() { AionNameServiceContract ansc = new AionNameServiceContract( - repo, defaultAddress, AionAddress.wrap(defaultKey.getAddress())); + repo, defaultAddress, Address.wrap(defaultKey.getAddress())); byte[] combined = setupInputs( @@ -408,11 +408,11 @@ public void incorrectInputLength() { // create ans contracts AionNameServiceContract ansc = new AionNameServiceContract( - repo, defaultAddress, AionAddress.wrap(defaultKey.getAddress())); + repo, defaultAddress, Address.wrap(defaultKey.getAddress())); byte[] combined = setupInputs( - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newAddress1, (byte) 0x0, (byte) 0x1, @@ -440,11 +440,11 @@ public void testIncorrectSignature() { // create ANS contract AionNameServiceContract ansc = new AionNameServiceContract( - repo, defaultAddress, AionAddress.wrap(defaultKey.getAddress())); + repo, defaultAddress, Address.wrap(defaultKey.getAddress())); byte[] combined = setupInputs( - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newAddress1, (byte) 0x0, (byte) 0x1, @@ -476,11 +476,11 @@ public void testUnsupportedOperation() { // create ANS contract AionNameServiceContract ansc = new AionNameServiceContract( - repo, defaultAddress, AionAddress.wrap(defaultKey.getAddress())); + repo, defaultAddress, Address.wrap(defaultKey.getAddress())); byte[] combined = setupInputs( - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newAddress1, (byte) 0x0, (byte) 0x6, @@ -506,16 +506,16 @@ public void testIncorrectPublicKey() { // ECKey k = ECKeyFac.inst().create(); ECKey notk = ECKeyFac.inst().create(); - repo.createAccount(AionAddress.wrap(notk.getAddress())); + repo.createAccount(Address.wrap(notk.getAddress())); // create ANS contract AionNameServiceContract ansc = new AionNameServiceContract( - repo, defaultAddress, AionAddress.wrap(defaultKey.getAddress())); + repo, defaultAddress, Address.wrap(defaultKey.getAddress())); byte[] combined = setupInputs( - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newAddress1, (byte) 0x0, (byte) 0x1, @@ -543,18 +543,18 @@ public void testTransferOwnership() { // create ANS contract AionNameServiceContract ansc = new AionNameServiceContract( - repo, defaultAddress, AionAddress.wrap(defaultKey.getAddress())); + repo, defaultAddress, Address.wrap(defaultKey.getAddress())); byte[] combined = setupInputs( - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newAddress1, (byte) 0x0, (byte) 0x3, defaultKey); byte[] combined2 = setupInputs( - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newAddress2, (byte) 0x0, (byte) 0x3, @@ -587,32 +587,32 @@ public void testInsufficientEnergy() { // create ANS contract AionNameServiceContract ansc = new AionNameServiceContract( - repo, defaultAddress, AionAddress.wrap(defaultKey.getAddress())); + repo, defaultAddress, Address.wrap(defaultKey.getAddress())); byte[] combined = setupInputs( - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newAddress1, (byte) 0x0, (byte) 0x1, defaultKey); byte[] combined2 = setupInputs( - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newAddress2, (byte) 0x0, (byte) 0x2, defaultKey); byte[] combined3 = setupInputs( - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newAddress3, (byte) 0x0, (byte) 0x3, defaultKey); byte[] combined4 = setupInputs( - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newAddress3, (byte) 0x0, (byte) 0x4, @@ -677,18 +677,18 @@ public void testSubdomainDoesNotExist() { // create ANS contract AionNameServiceContract ansc = new AionNameServiceContract( - repo, defaultAddress, AionAddress.wrap(defaultKey.getAddress())); + repo, defaultAddress, Address.wrap(defaultKey.getAddress())); byte[] combined = setupInputs( - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newAddress1, (byte) 0x0, (byte) 0x3, defaultKey); byte[] combined2 = setupInputs( - AionAddress.wrap(defaultKey.getAddress()), + Address.wrap(defaultKey.getAddress()), newAddress2, (byte) 0x0, (byte) 0x4, @@ -726,23 +726,23 @@ public void testANSQuery() { byte[] combined = setupInputs( "cion.bion.aion", - AionAddress.wrap(k.getAddress()), + Address.wrap(k.getAddress()), amount.toByteArray(), k); AionAuctionContract aac = new AionAuctionContract(repo, AION, blockchain); PrecompiledTransactionResult result = aac.execute(combined, DEFAULT_INPUT_NRG); - Address addr = AionAddress.wrap(result.getReturnData()); + Address addr = Address.wrap(result.getReturnData()); byte[] combined2 = setupInputs( - "aaaa.aion", AionAddress.wrap(k.getAddress()), amount2.toByteArray(), k); + "aaaa.aion", Address.wrap(k.getAddress()), amount2.toByteArray(), k); AionAuctionContract aac2 = new AionAuctionContract(repo, AION, blockchain); aac2.execute(combined2, DEFAULT_INPUT_NRG); byte[] combined3 = setupInputs( "bbbb.aaaa.aion", - AionAddress.wrap(k2.getAddress()), + Address.wrap(k2.getAddress()), amount3.toByteArray(), k2); AionAuctionContract aac3 = new AionAuctionContract(repo, AION, blockchain); @@ -756,7 +756,7 @@ public void testANSQuery() { // register domain for name service AionNameServiceContract ansc = - new AionNameServiceContract(repo, addr, AionAddress.wrap(k.getAddress())); + new AionNameServiceContract(repo, addr, Address.wrap(k.getAddress())); System.out.print(""); @@ -774,7 +774,7 @@ public void testANSQuery() { byte[] combined4 = setupInputs( "cccc.aaaa.aion", - AionAddress.wrap(k.getAddress()), + Address.wrap(k.getAddress()), amount3.toByteArray(), k); AionAuctionContract aac4 = new AionAuctionContract(repo, AION, blockchain); @@ -783,7 +783,7 @@ public void testANSQuery() { byte[] combined5 = setupInputs( "cccc.aaaa.aion", - AionAddress.wrap(k2.getAddress()), + Address.wrap(k2.getAddress()), amount2.toByteArray(), k2); AionAuctionContract aac5 = new AionAuctionContract(repo, AION, blockchain); @@ -934,13 +934,13 @@ private void storeValueToRepo( byte[] value1, byte[] value2) { repo.addStorageRow( - domainAddress, new DataWord(hash1).toWrapper(), new DataWord(value1).toWrapper()); + domainAddress, new DataWordImpl(hash1).toWrapper(), new DataWordImpl(value1).toWrapper()); repo.addStorageRow( - domainAddress, new DataWord(hash2).toWrapper(), new DataWord(value2).toWrapper()); + domainAddress, new DataWordImpl(hash2).toWrapper(), new DataWordImpl(value2).toWrapper()); } private void createAccounts(DummyRepo repository, ECKey[] accountList) { - for (ECKey key : accountList) repository.createAccount(AionAddress.wrap(key.getAddress())); + for (ECKey key : accountList) repository.createAccount(Address.wrap(key.getAddress())); } private byte[] setupInputs(String domainName, Address ownerAddress, byte[] amount, ECKey k) { @@ -993,12 +993,12 @@ private static AionBlock createBundleAndCheck( StandaloneBlockchain bc, ECKey key, AionBlock parentBlock) { byte[] ZERO_BYTE = new byte[0]; - BigInteger accountNonce = bc.getRepository().getNonce(new AionAddress(key.getAddress())); + BigInteger accountNonce = bc.getRepository().getNonce(new Address(key.getAddress())); List transactions = new ArrayList<>(); // create 100 transactions per bundle for (int i = 0; i < 100; i++) { - Address destAddr = new AionAddress(HashUtil.h256(accountNonce.toByteArray())); + Address destAddr = new Address(HashUtil.h256(accountNonce.toByteArray())); AionTransaction sendTransaction = new AionTransaction( accountNonce.toByteArray(), diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/BenchmarkTest.java b/modPrecompiled/test/org/aion/precompiled/contracts/BenchmarkTest.java index af79f2be07..71453da989 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/BenchmarkTest.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/BenchmarkTest.java @@ -4,13 +4,13 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; -import org.aion.base.type.AionAddress; +import org.aion.types.Address; import org.aion.fastvm.ExecutionContext; import org.aion.mcf.config.CfgFork; -import org.aion.mcf.vm.types.DataWord; +import org.aion.mcf.vm.types.DataWordImpl; import org.aion.precompiled.ContractFactory; import org.aion.precompiled.type.PrecompiledContract; -import org.aion.vm.api.interfaces.Address; + import org.aion.zero.impl.config.CfgAion; import org.apache.commons.lang3.RandomUtils; import org.junit.After; @@ -25,7 +25,7 @@ public class BenchmarkTest { private byte[] txHash, callData; private Address origin, caller, blockCoinbase; private long blockNumber, blockTimestamp, blockNrgLimit, nrgLimit; - private DataWord blockDifficulty, nrgPrice, callValue; + private DataWordImpl blockDifficulty, nrgPrice, callValue; private int depth, kind, flags; private static int WARMUP = 2000; @@ -51,17 +51,17 @@ public void setup() throws IOException { cf = new ContractFactory(); CfgAion.inst(); txHash = RandomUtils.nextBytes(32); - origin = AionAddress.wrap(RandomUtils.nextBytes(32)); + origin = Address.wrap(RandomUtils.nextBytes(32)); caller = origin; - blockCoinbase = AionAddress.wrap(RandomUtils.nextBytes(32)); + blockCoinbase = Address.wrap(RandomUtils.nextBytes(32)); blockNumber = 2000001; blockTimestamp = System.currentTimeMillis() / 1000; blockNrgLimit = 5000000; - blockDifficulty = new DataWord(0x100000000L); + blockDifficulty = new DataWordImpl(0x100000000L); - nrgPrice = DataWord.ONE; + nrgPrice = DataWordImpl.ONE; nrgLimit = 20000; - callValue = DataWord.ZERO; + callValue = DataWordImpl.ZERO; callData = new byte[0]; depth = 0; diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/DummyRepo.java b/modPrecompiled/test/org/aion/precompiled/contracts/DummyRepo.java index a2e20fec50..ccca2148c5 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/DummyRepo.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/DummyRepo.java @@ -6,18 +6,19 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.aion.base.db.IContractDetails; -import org.aion.base.db.IRepository; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; +import org.aion.interfaces.db.ContractDetails; +import org.aion.interfaces.db.Repository; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; -import org.aion.mcf.vm.types.DataWord; import org.aion.mcf.vm.types.DoubleDataWord; -import org.aion.vm.api.interfaces.Address; +import org.aion.util.bytes.ByteUtil; -public class DummyRepo implements IRepositoryCache> { + +public class DummyRepo implements RepositoryCache> { private Map accounts = new HashMap<>(); private Map contracts = new HashMap<>(); private Map> storage = new HashMap<>(); @@ -85,7 +86,7 @@ public BigInteger getNonce(Address addr) { } @Override - public IContractDetails getContractDetails(Address addr) { + public ContractDetails getContractDetails(Address addr) { throw new UnsupportedOperationException(); } @@ -131,8 +132,8 @@ public ByteArrayWrapper getStorageValue(Address addr, ByteArrayWrapper key) { if (res == null) { return null; } - if (res.length <= DataWord.BYTES) { - return new DataWord(res).toWrapper(); + if (res.length <= DataWordImpl.BYTES) { + return new DataWordImpl(res).toWrapper(); } else if (res.length == DoubleDataWord.BYTES) { return new DoubleDataWord(res).toWrapper(); } @@ -161,7 +162,7 @@ public BigInteger addBalance(Address addr, BigInteger value) { } @Override - public IRepositoryCache> startTracking() { + public RepositoryCache> startTracking() { return new DummyRepo(this); } @@ -169,7 +170,10 @@ public BigInteger addBalance(Address addr, BigInteger value) { public void flush() {} @Override - public void flushTo(IRepository repo, boolean clearStateAfterFlush) {} + public void flushTo(Repository repo, boolean clearStateAfterFlush) {} + + @Override + public void flushCopiesTo(Repository repo, boolean clearStateAfterFlush) {} @Override public void rollback() {} @@ -193,7 +197,7 @@ public boolean isValidRoot(byte[] root) { @Override public void updateBatch( Map accountStates, - Map contractDetailes) { + Map contractDetailes) { throw new UnsupportedOperationException(); } @@ -206,12 +210,12 @@ public byte[] getRoot() { public void loadAccountState( Address addr, Map cacheAccounts, - Map cacheDetails) { + Map cacheDetails) { throw new UnsupportedOperationException(); } @Override - public IRepository> getSnapshotTo(byte[] root) { + public Repository> getSnapshotTo(byte[] root) { throw new UnsupportedOperationException(); } @@ -226,6 +230,11 @@ public void addTxBatch(Map pendingTx, boolean isPool) {} @Override public void removeTxBatch(Set pendingTx, boolean isPool) {} + @Override + public byte getVMUsed(Address contract) { + return 0x01; + } + @Override public void compact() { throw new UnsupportedOperationException( diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/EDVerifyContractTest.java b/modPrecompiled/test/org/aion/precompiled/contracts/EDVerifyContractTest.java index dee9fbcb32..c02b9722ee 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/EDVerifyContractTest.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/EDVerifyContractTest.java @@ -11,18 +11,18 @@ import java.io.FileWriter; import java.io.IOException; import java.util.Arrays; -import org.aion.base.type.AionAddress; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.crypto.HashUtil; import org.aion.crypto.ISignature; import org.aion.fastvm.ExecutionContext; import org.aion.mcf.config.CfgFork; -import org.aion.mcf.vm.types.DataWord; import org.aion.precompiled.ContractFactory; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.type.PrecompiledContract; -import org.aion.vm.api.interfaces.Address; + import org.aion.vm.api.interfaces.TransactionResult; import org.aion.zero.impl.config.CfgAion; import org.apache.commons.lang3.RandomUtils; @@ -34,18 +34,18 @@ public class EDVerifyContractTest { private byte[] txHash = RandomUtils.nextBytes(32); - private Address origin = AionAddress.wrap(RandomUtils.nextBytes(32)); + private Address origin = Address.wrap(RandomUtils.nextBytes(32)); private Address caller = origin; - private Address blockCoinbase = AionAddress.wrap(RandomUtils.nextBytes(32)); + private Address blockCoinbase = Address.wrap(RandomUtils.nextBytes(32)); private long blockNumber = 2000001; private long blockTimestamp = System.currentTimeMillis() / 1000; private long blockNrgLimit = 5000000; - private DataWord blockDifficulty = new DataWord(0x100000000L); + private DataWordImpl blockDifficulty = new DataWordImpl(0x100000000L); - private DataWord nrgPrice; + private DataWordImpl nrgPrice; private long nrgLimit; - private DataWord callValue; + private DataWordImpl callValue; private byte[] callData; private byte[] pubKey; @@ -57,9 +57,9 @@ public class EDVerifyContractTest { @Before public void setup() throws IOException { - nrgPrice = DataWord.ONE; + nrgPrice = DataWordImpl.ONE; nrgLimit = 20000; - callValue = DataWord.ZERO; + callValue = DataWordImpl.ZERO; callData = new byte[0]; new File(System.getProperty("user.dir") + "/mainnet/config").mkdirs(); @@ -178,12 +178,12 @@ public void incorrectInputTest() { assertNotNull(contract); TransactionResult result = contract.execute(input, 21000L); assertThat(result.getResultCode().isSuccess()); - assertThat(Arrays.equals(result.getReturnData(), AionAddress.ZERO_ADDRESS().toBytes())); + assertThat(Arrays.equals(result.getReturnData(), Address.ZERO_ADDRESS().toBytes())); } @Test public void shouldFailIfNotEnoughEnergy() { - nrgPrice = DataWord.ONE; + nrgPrice = DataWordImpl.ONE; byte[] input = setupInput(); ExecutionContext ctx = diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/MultiSignatureContractTest.java b/modPrecompiled/test/org/aion/precompiled/contracts/MultiSignatureContractTest.java index 9d50ebb654..4e58621b73 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/MultiSignatureContractTest.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/MultiSignatureContractTest.java @@ -12,18 +12,18 @@ import java.util.List; import java.util.Set; import java.util.concurrent.ThreadLocalRandom; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.ByteUtil; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.crypto.ECKeyFac; import org.aion.crypto.ISignature; import org.aion.crypto.ed25519.ECKeyEd25519; -import org.aion.mcf.vm.types.DataWord; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; import org.aion.precompiled.type.StatefulPrecompiledContract; -import org.aion.vm.api.interfaces.Address; + +import org.aion.util.bytes.ByteUtil; import org.junit.After; import org.junit.Before; import org.junit.Ignore; @@ -40,7 +40,7 @@ public class MultiSignatureContractTest { private static final long NRG_LIMIT = 100000L; private static final long NRG_PRICE = 10000000000L; private Address to; - private IRepositoryCache repo; + private RepositoryCache repo; private List
    addrsToClean; @Before @@ -77,7 +77,7 @@ private PrecompiledTransactionResult execute( // Creates a new account with initial balance balance that will be deleted at test end. private Address getExistentAddress(BigInteger balance) { - Address addr = AionAddress.wrap(ECKeyFac.inst().create().getAddress()); + Address addr = Address.wrap(ECKeyFac.inst().create().getAddress()); repo.createAccount(addr); repo.addBalance(addr, balance); addrsToClean.add(addr); @@ -107,7 +107,7 @@ private List
    getExistentAddresses( // This is the constructMsg method provided by MSC class but here you can specify your nonce. private static byte[] customMsg( - IRepositoryCache repo, + RepositoryCache repo, BigInteger nonce, Address walletId, Address to, @@ -188,10 +188,10 @@ private byte[] toValidSendInput( // If walletId is not a multi-sig wallet this method fails. private List getWalletThresholdAndNumOwners(Address walletId) { List values = new ArrayList<>(); - byte[] metaKey = new byte[DataWord.BYTES]; + byte[] metaKey = new byte[DataWordImpl.BYTES]; metaKey[0] = (byte) 0x80; ByteArrayWrapper metaData = - repo.getStorageValue(walletId, new DataWord(metaKey).toWrapper()); + repo.getStorageValue(walletId, new DataWordImpl(metaKey).toWrapper()); if (metaData == null) { fail(); } @@ -201,7 +201,7 @@ private List getWalletThresholdAndNumOwners(Address walletId) { buffer.flip(); values.add(buffer.getLong()); buffer.flip(); - buffer.put(Arrays.copyOfRange(rawData, Long.BYTES, DataWord.BYTES)); + buffer.put(Arrays.copyOfRange(rawData, Long.BYTES, DataWordImpl.BYTES)); buffer.flip(); values.add(buffer.getLong()); return values; @@ -218,22 +218,22 @@ private Set
    getWalletOwners(Address walletId, long numOwners) { byte[] account = new byte[Address.SIZE]; buffer.putLong(i); buffer.flip(); - byte[] request = new byte[DataWord.BYTES]; - buffer.get(request, DataWord.BYTES - Long.BYTES, Long.BYTES); - portion = repo.getStorageValue(walletId, new DataWord(request).toWrapper()); + byte[] request = new byte[DataWordImpl.BYTES]; + buffer.get(request, DataWordImpl.BYTES - Long.BYTES, Long.BYTES); + portion = repo.getStorageValue(walletId, new DataWordImpl(request).toWrapper()); if (portion == null) { fail(); } - System.arraycopy(portion.getData(), 0, account, 0, DataWord.BYTES); + System.arraycopy(portion.getData(), 0, account, 0, DataWordImpl.BYTES); request[0] = (byte) 0x40; - portion = repo.getStorageValue(walletId, new DataWord(request).toWrapper()); + portion = repo.getStorageValue(walletId, new DataWordImpl(request).toWrapper()); if (portion == null) { fail(); } - System.arraycopy(portion.getData(), 0, account, DataWord.BYTES, DataWord.BYTES); + System.arraycopy(portion.getData(), 0, account, DataWordImpl.BYTES, DataWordImpl.BYTES); - Address address = new AionAddress(account); + Address address = new Address(account); if (owners.contains(address)) { fail(); } @@ -263,7 +263,7 @@ private Address createMultiSigWallet( List
    ownerAddrs = new ArrayList<>(); Address addr; for (ECKeyEd25519 key : owners) { - addr = new AionAddress(key.getAddress()); + addr = new Address(key.getAddress()); repo.createAccount(addr); addrsToClean.add(addr); ownerAddrs.add(addr); @@ -273,7 +273,7 @@ private Address createMultiSigWallet( MultiSignatureContract msc = new MultiSignatureContract(repo, ownerAddrs.get(0)); PrecompiledTransactionResult res = msc.execute(input, COST); assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); - Address wallet = new AionAddress(res.getReturnData()); + Address wallet = new Address(res.getReturnData()); repo.addBalance(wallet, balance); addrsToClean.add(wallet); repo.flush(); @@ -301,7 +301,7 @@ private List produceSignatures(List owners, int numSig // threshold and consists of all the owners in owners and no more. private void checkCreateResult( PrecompiledTransactionResult res, long threshold, List
    owners) { - Address walletId = new AionAddress(res.getReturnData()); + Address walletId = new Address(res.getReturnData()); addrsToClean.add(walletId); assertEquals(BigInteger.ZERO, repo.getBalance(walletId)); assertEquals(BigInteger.ZERO, repo.getNonce(walletId)); @@ -327,7 +327,7 @@ private void checkAccountState(Address account, BigInteger nonce, BigInteger bal @Test(expected = IllegalArgumentException.class) public void testConstructWithNullTrack() { - new MultiSignatureContract(null, AionAddress.wrap(ECKeyFac.inst().create().getAddress())); + new MultiSignatureContract(null, Address.wrap(ECKeyFac.inst().create().getAddress())); } @Test(expected = IllegalArgumentException.class) @@ -353,7 +353,7 @@ public void testNrgBelowLegalLimit() { // Second test send-tx logic. // Test with min illegal cost. List sendOwners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address sendCaller = new AionAddress(sendOwners.get(0).getAddress()); + Address sendCaller = new Address(sendOwners.get(0).getAddress()); Address wallet = createMultiSigWallet( sendOwners, MultiSignatureContract.MIN_OWNERS - 1, DEFAULT_BALANCE); @@ -409,7 +409,7 @@ public void testNrgAboveThanCost() { // Second test send-tx logic. // Test with min illegal cost. List sendOwners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address sendCaller = new AionAddress(sendOwners.get(0).getAddress()); + Address sendCaller = new Address(sendOwners.get(0).getAddress()); Address wallet = createMultiSigWallet( sendOwners, MultiSignatureContract.MIN_OWNERS - 1, DEFAULT_BALANCE); @@ -631,7 +631,7 @@ public void testCreateWalletWithMultiSigWalletCaller() { PrecompiledTransactionResult res = execute(caller, input, NRG_LIMIT, PrecompiledResultCode.SUCCESS, NRG_LIMIT - COST); - Address walletCaller = new AionAddress(res.getReturnData()); + Address walletCaller = new Address(res.getReturnData()); addrsToClean.add(walletCaller); checkAccountState(walletCaller, BigInteger.ZERO, BigInteger.ZERO); @@ -659,7 +659,7 @@ public void testCreateWalletWithOwnerAsAMultiSigWallet() { PrecompiledTransactionResult res = execute(caller, input, NRG_LIMIT, PrecompiledResultCode.SUCCESS, NRG_LIMIT - COST); - Address wallet = new AionAddress(res.getReturnData()); + Address wallet = new Address(res.getReturnData()); addrsToClean.add(wallet); checkAccountState(wallet, BigInteger.ZERO, BigInteger.ZERO); @@ -689,7 +689,7 @@ public void testCreateWalletWithThresholdEqualToLegalNumOwners() { PrecompiledTransactionResult res = execute(caller, input, NRG_LIMIT, PrecompiledResultCode.SUCCESS, NRG_LIMIT - COST); checkCreateResult(res, threshold, owners); - checkAccountState(new AionAddress(res.getReturnData()), BigInteger.ZERO, BigInteger.ZERO); + checkAccountState(new Address(res.getReturnData()), BigInteger.ZERO, BigInteger.ZERO); // Test using max legal number of owners. owners = @@ -700,7 +700,7 @@ public void testCreateWalletWithThresholdEqualToLegalNumOwners() { res = execute(caller, input, NRG_LIMIT, PrecompiledResultCode.SUCCESS, NRG_LIMIT - COST); checkCreateResult(res, threshold, owners); - checkAccountState(new AionAddress(res.getReturnData()), BigInteger.ZERO, BigInteger.ZERO); + checkAccountState(new Address(res.getReturnData()), BigInteger.ZERO, BigInteger.ZERO); } @Test @@ -714,10 +714,10 @@ public void testCreateWalletAddressIsDeterministic() { PrecompiledTransactionResult res = execute(caller, input, NRG_LIMIT, PrecompiledResultCode.SUCCESS, NRG_LIMIT - COST); - Address wallet1 = new AionAddress(res.getReturnData()); + Address wallet1 = new Address(res.getReturnData()); res = execute(caller, input, NRG_LIMIT, PrecompiledResultCode.SUCCESS, NRG_LIMIT - COST); - Address wallet2 = new AionAddress(res.getReturnData()); + Address wallet2 = new Address(res.getReturnData()); assertEquals(wallet1, wallet2); } @@ -733,7 +733,7 @@ public void testWalletAddressStartsWithAionPrefix() { PrecompiledTransactionResult res = execute(caller, input, NRG_LIMIT, PrecompiledResultCode.SUCCESS, NRG_LIMIT - COST); - Address wallet = new AionAddress(res.getReturnData()); + Address wallet = new Address(res.getReturnData()); assertTrue(wallet.toString().startsWith("a0")); } @@ -750,7 +750,7 @@ public void testCreateWalletWithMinimumLegalThreshold() { PrecompiledTransactionResult res = execute(caller, input, NRG_LIMIT, PrecompiledResultCode.SUCCESS, NRG_LIMIT - COST); checkCreateResult(res, threshold, owners); - checkAccountState(new AionAddress(res.getReturnData()), BigInteger.ZERO, BigInteger.ZERO); + checkAccountState(new Address(res.getReturnData()), BigInteger.ZERO, BigInteger.ZERO); // Test using max legal number of owners. owners = @@ -761,7 +761,7 @@ public void testCreateWalletWithMinimumLegalThreshold() { res = execute(caller, input, NRG_LIMIT, PrecompiledResultCode.SUCCESS, NRG_LIMIT - COST); checkCreateResult(res, threshold, owners); - checkAccountState(new AionAddress(res.getReturnData()), BigInteger.ZERO, BigInteger.ZERO); + checkAccountState(new Address(res.getReturnData()), BigInteger.ZERO, BigInteger.ZERO); } // <----------------------------------SEND TRANSACTION TESTS-----------------------------------> @@ -769,7 +769,7 @@ public void testCreateWalletWithMinimumLegalThreshold() { @Test public void testSendTxWithZeroSignatures() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_THRESH, DEFAULT_BALANCE); @@ -791,7 +791,7 @@ public void testSendTxWithZeroSignatures() { public void testSendTxWithMoreThanMaxOwnersSignatures() { List owners = produceKeys(MultiSignatureContract.MAX_OWNERS + 1); ECKeyEd25519 extra = owners.remove(0); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MAX_OWNERS, DEFAULT_BALANCE); @@ -817,7 +817,7 @@ public void testSendTxWithMoreThanMaxOwnersSignatures() { public void testSendTxValidSignaturesMeetsThresholdPlusPhonySig() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS + 1); ECKeyEd25519 phony = owners.remove(0); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); @@ -842,7 +842,7 @@ public void testSendTxValidSignaturesMeetsThresholdPlusPhonySig() { @Test public void testSendTxNegativeAmountWithZeroBalance() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_THRESH, BigInteger.ZERO); BigInteger amt = AMOUNT.negate(); @@ -865,7 +865,7 @@ public void testSendTxNegativeAmountWithZeroBalance() { @Test public void testSendTxNegativeAmountWithActualBalance() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_THRESH, DEFAULT_BALANCE); BigInteger amt = AMOUNT.negate(); @@ -889,7 +889,7 @@ public void testSendTxNegativeAmountWithActualBalance() { public void testSendTxFromRegularAddress() { // Our wallet is not a wallet... List phonies = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address phonyWallet = new AionAddress(phonies.get(0).getAddress()); + Address phonyWallet = new Address(phonies.get(0).getAddress()); repo.addBalance(phonyWallet, DEFAULT_BALANCE); BigInteger amt = BigInteger.ONE; @@ -912,7 +912,7 @@ public void testSendTxFromRegularAddress() { @Test public void testSendTxNoSenderInInput() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); @@ -934,7 +934,7 @@ public void testSendTxNoSenderInInput() { @Test public void testSendTxNoRecipient() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); @@ -956,7 +956,7 @@ public void testSendTxNoRecipient() { @Test public void testSendTxNoAmount() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); @@ -978,7 +978,7 @@ public void testSendTxNoAmount() { @Test public void testSendTxNoNrgPrice() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); @@ -1010,7 +1010,7 @@ public void testSendTxNoNrgPrice() { @Test public void testSendTxWithSignatureUsingPreviousNonce() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); @@ -1041,7 +1041,7 @@ public void testSendTxWithSignatureUsingPreviousNonce() { @Test public void testSendTxWhereSignedMessagesDifferInNonce() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); @@ -1076,7 +1076,7 @@ public void testSendTxWhereSignedMessagesDifferInNonce() { @Test public void testSendTxWhereSignedMessagesDifferInRecipient() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); @@ -1106,7 +1106,7 @@ public void testSendTxWhereSignedMessagesDifferInRecipient() { @Test public void testSendTxWhereSignedMessagesDifferInAmount() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); @@ -1139,7 +1139,7 @@ public void testSendTxWhereSignedMessagesDifferInAmount() { @Test public void testSendTxWhereSignedMessagesDifferInNrgPrice() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); @@ -1169,7 +1169,7 @@ public void testSendTxWhereSignedMessagesDifferInNrgPrice() { @Test public void testSendTxAllSignWrongRecipient() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); Address stranger = getExistentAddress(BigInteger.ZERO); @@ -1196,7 +1196,7 @@ public void testSendTxAllSignWrongRecipient() { @Test public void testSendTxAllSignWrongAmount() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); @@ -1222,7 +1222,7 @@ public void testSendTxAllSignWrongAmount() { @Test public void testSendTxAllSignWrongNonce() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); Address stranger = getExistentAddress(BigInteger.ZERO); @@ -1249,7 +1249,7 @@ public void testSendTxAllSignWrongNonce() { @Test public void testSendTxAllSignWrongNrgPrice() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); @@ -1276,7 +1276,7 @@ public void testSendTxAllSignWrongNrgPrice() { public void testSendTxInsufficientBalance() { // Create account with zero balance. List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_THRESH, BigInteger.ZERO); @@ -1300,7 +1300,7 @@ public void testSendTxInsufficientBalance() { public void testWalletAbleToSendTxToDiffWallet() { List owners1 = produceKeys(MultiSignatureContract.MIN_OWNERS); List owners2 = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners1.get(0).getAddress()); + Address caller = new Address(owners1.get(0).getAddress()); Address wallet1 = createMultiSigWallet(owners1, MultiSignatureContract.MIN_THRESH, DEFAULT_BALANCE); Address wallet2 = @@ -1327,7 +1327,7 @@ public void testWalletAbleToSendTxToDiffWallet() { @Test public void testSendTxLessSignaturesThanThresholdMinOwners() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); @@ -1352,7 +1352,7 @@ public void testSendTxLessSignaturesThanThresholdMinOwners() { @Test public void testSendTxLessSignaturesThanThresholdMaxOwners() { List owners = produceKeys(MultiSignatureContract.MAX_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MAX_OWNERS, DEFAULT_BALANCE); @@ -1377,7 +1377,7 @@ public void testSendTxLessSignaturesThanThresholdMaxOwners() { @Test public void testSendTxSameSignaturesAsThresholdMinOwners() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_THRESH, DEFAULT_BALANCE); @@ -1401,7 +1401,7 @@ public void testSendTxSameSignaturesAsThresholdMinOwners() { @Test public void testSendTxSameSignaturesAsThresholdMaxOwners() { List owners = produceKeys(MultiSignatureContract.MAX_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MAX_OWNERS, DEFAULT_BALANCE); @@ -1425,7 +1425,7 @@ public void testSendTxSameSignaturesAsThresholdMaxOwners() { @Test public void testSendTxMoreSignaturesThanThresholdMinOwners() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet( owners, MultiSignatureContract.MIN_OWNERS - 1, DEFAULT_BALANCE); @@ -1450,7 +1450,7 @@ public void testSendTxMoreSignaturesThanThresholdMinOwners() { @Test public void testSendTxMoreSignaturesThanThresholdMaxOwners() { List owners = produceKeys(MultiSignatureContract.MAX_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_THRESH, DEFAULT_BALANCE); @@ -1474,7 +1474,7 @@ public void testSendTxMoreSignaturesThanThresholdMaxOwners() { @Test public void testSendTxDuplicateSignee() { List owners = produceKeys(MultiSignatureContract.MAX_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MAX_OWNERS, DEFAULT_BALANCE); @@ -1501,7 +1501,7 @@ public void testSendTxDuplicateSignee() { public void testSendTxSignatureOneSigneeIsNonOwner() { List owners = produceKeys(MultiSignatureContract.MAX_OWNERS); ECKeyEd25519 phony = produceKeys(1).get(0); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MAX_OWNERS, DEFAULT_BALANCE); @@ -1528,7 +1528,7 @@ public void testSendTxSignatureOneSigneeIsNonOwner() { @Test public void testSendTxSignedProperlyButNotSignedByOwnerCaller() { List owners = produceKeys(MultiSignatureContract.MAX_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_THRESH, DEFAULT_BALANCE); @@ -1574,7 +1574,7 @@ public void testSendTxSignedProperlyButCallerIsNotOwner() { checkAccountState(wallet, BigInteger.ZERO, DEFAULT_BALANCE); checkAccountState(to, BigInteger.ZERO, BigInteger.ZERO); execute( - new AionAddress(phony.getAddress()), + new Address(phony.getAddress()), input, NRG_LIMIT, PrecompiledResultCode.FAILURE, @@ -1586,7 +1586,7 @@ public void testSendTxSignedProperlyButCallerIsNotOwner() { @Test public void testPartialSignature() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); @@ -1614,7 +1614,7 @@ public void testPartialSignature() { @Test public void testPartialWalletAddress() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); @@ -1642,7 +1642,7 @@ public void testPartialWalletAddress() { @Test public void testPartialRecipientAddress() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); @@ -1670,7 +1670,7 @@ public void testPartialRecipientAddress() { @Test public void testPartialAmount() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); @@ -1698,7 +1698,7 @@ public void testPartialAmount() { @Test public void testPartialNrgPrice() { List owners = produceKeys(MultiSignatureContract.MIN_OWNERS); - Address caller = new AionAddress(owners.get(0).getAddress()); + Address caller = new Address(owners.get(0).getAddress()); Address wallet = createMultiSigWallet(owners, MultiSignatureContract.MIN_OWNERS, DEFAULT_BALANCE); diff --git a/modPrecompiled/test/org/aion/precompiled/contracts/TotalCurrencyContractTest.java b/modPrecompiled/test/org/aion/precompiled/contracts/TotalCurrencyContractTest.java index 2f73848d83..9d1258336e 100644 --- a/modPrecompiled/test/org/aion/precompiled/contracts/TotalCurrencyContractTest.java +++ b/modPrecompiled/test/org/aion/precompiled/contracts/TotalCurrencyContractTest.java @@ -5,15 +5,15 @@ import java.math.BigInteger; import java.nio.ByteBuffer; import java.util.Arrays; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.AionAddress; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; -import org.aion.mcf.vm.types.DataWord; import org.aion.precompiled.ContractFactory; import org.aion.precompiled.PrecompiledResultCode; import org.aion.precompiled.PrecompiledTransactionResult; -import org.aion.vm.api.interfaces.Address; + import org.junit.After; import org.junit.Before; import org.junit.Ignore; @@ -25,14 +25,14 @@ public class TotalCurrencyContractTest { private static final long COST = 21000L; private static final BigInteger AMT = BigInteger.valueOf(1000); private TotalCurrencyContract tcc; - private IRepositoryCache repo; + private RepositoryCache repo; private ECKey ownerKey; @Before public void setup() { repo = new DummyRepo(); ownerKey = ECKeyFac.inst().create(); - tcc = new TotalCurrencyContract(repo, ADDR, AionAddress.wrap(ownerKey.getAddress())); + tcc = new TotalCurrencyContract(repo, ADDR, Address.wrap(ownerKey.getAddress())); } @After @@ -52,7 +52,7 @@ public void tearDown() { */ private byte[] constructUpdateInput(byte chainID, byte signum) { ByteBuffer buffer = ByteBuffer.allocate(18); - buffer.put(chainID).put(signum).put(new DataWord(AMT.toByteArray()).getData()); + buffer.put(chainID).put(signum).put(new DataWordImpl(AMT.toByteArray()).getData()); byte[] payload = buffer.array(); buffer = ByteBuffer.allocate(18 + 96); @@ -117,7 +117,7 @@ public void TestUpdateAndGetTotalAmount() { assertEquals(PrecompiledResultCode.SUCCESS, res.getResultCode()); assertEquals(0L, res.getEnergyRemaining()); - tcc = new TotalCurrencyContract(repo, ADDR, AionAddress.wrap(ownerKey.getAddress())); + tcc = new TotalCurrencyContract(repo, ADDR, Address.wrap(ownerKey.getAddress())); input = new byte[] {(byte) 0x0}; res = tcc.execute(input, COST); @@ -186,7 +186,7 @@ public void TestUpdateTotalNotOwner() { new TotalCurrencyContract( repo, ADDR, - AionAddress.wrap(ECKeyFac.inst().create().getAddress())); // diff owner. + Address.wrap(ECKeyFac.inst().create().getAddress())); // diff owner. byte[] input = constructUpdateInput((byte) 0x0, (byte) 0x0); PrecompiledTransactionResult res = contract.execute(input, COST); diff --git a/modPrecompiled/test/org/aion/precompiled/encoding/AbiEncoder.java b/modPrecompiled/test/org/aion/precompiled/encoding/AbiEncoder.java index 9d2dbf89c4..fc2d91db95 100644 --- a/modPrecompiled/test/org/aion/precompiled/encoding/AbiEncoder.java +++ b/modPrecompiled/test/org/aion/precompiled/encoding/AbiEncoder.java @@ -6,9 +6,9 @@ import java.util.List; import javax.annotation.Nonnull; import javax.annotation.concurrent.ThreadSafe; -import org.aion.base.util.ByteUtil; import org.aion.crypto.HashUtil; import org.aion.precompiled.PrecompiledUtilities; +import org.aion.util.bytes.ByteUtil; @ThreadSafe public class AbiEncoder { diff --git a/modPrecompiled/test/org/aion/precompiled/encoding/AddressFVM.java b/modPrecompiled/test/org/aion/precompiled/encoding/AddressFVM.java index 03f7919e6f..a120400f8d 100644 --- a/modPrecompiled/test/org/aion/precompiled/encoding/AddressFVM.java +++ b/modPrecompiled/test/org/aion/precompiled/encoding/AddressFVM.java @@ -3,7 +3,7 @@ import java.util.List; import java.util.Optional; import javax.annotation.Nonnull; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; public class AddressFVM extends BaseTypeFVM { diff --git a/modPrecompiled/test/org/aion/precompiled/encoding/Bytes32FVM.java b/modPrecompiled/test/org/aion/precompiled/encoding/Bytes32FVM.java index 9aa9a24786..3d382be695 100644 --- a/modPrecompiled/test/org/aion/precompiled/encoding/Bytes32FVM.java +++ b/modPrecompiled/test/org/aion/precompiled/encoding/Bytes32FVM.java @@ -3,7 +3,7 @@ import java.util.List; import java.util.Optional; import javax.annotation.Nonnull; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; public class Bytes32FVM extends BaseTypeFVM { private ByteArrayWrapper word; diff --git a/modPrecompiled/test/org/aion/precompiled/encoding/Uint128FVM.java b/modPrecompiled/test/org/aion/precompiled/encoding/Uint128FVM.java index 51fc56b82f..718875bd36 100644 --- a/modPrecompiled/test/org/aion/precompiled/encoding/Uint128FVM.java +++ b/modPrecompiled/test/org/aion/precompiled/encoding/Uint128FVM.java @@ -3,7 +3,7 @@ import java.util.List; import java.util.Optional; import javax.annotation.Nonnull; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; public class Uint128FVM extends BaseTypeFVM { diff --git a/modRlp/build.gradle b/modRlp/build.gradle index b0b0c5dee4..410c48a2c6 100644 --- a/modRlp/build.gradle +++ b/modRlp/build.gradle @@ -1,11 +1,26 @@ ext.moduleName = 'aion.rlp' +// set the publish to true when the code ready to push the lib to the maven repo +def publish = false; + +apply plugin: 'maven' +apply plugin: 'signing' + +group = "network.aion" +archivesBaseName = "rlp4j" + +def getCommitHash = { -> + def hashStdOut = new ByteArrayOutputStream() + exec { + commandLine "sh", "-c", "git log --pretty=format:%h | head -1" + standardOutput = hashStdOut + } + + return hashStdOut.toString().trim() +} + dependencies { - compile project(':modUtil') - //compile files('../lib/libnsc.jar') - compile 'com.madgag.spongycastle:prov:1.58.0.0' - compile 'com.madgag.spongycastle:core:1.58.0.0' - compile 'com.google.guava:guava:25.1-jre' + compile 'network.aion:util4j:0.4.0' testCompile 'junit:junit:4.12' testCompile 'pl.pragmatists:JUnitParams:1.1.1' @@ -18,3 +33,92 @@ tasks.withType(JavaCompile) { println "Args for for $name are $options.allCompilerArgs" } } + +sourceSets { + if (publish) { + version = "0.4.0" + } else { + jar.baseName = 'rlp4j-' + getCommitHash() + } + + main { + java.srcDirs = ['src/main/java'] + } + test { + java.srcDirs = ['src/test/java'] + } +} + +signing { + sign configurations.archives +} +signArchives.enabled = publish + + +task sourcesJar(type: Jar) { + classifier = 'sources' + from sourceSets.main.allSource +} +sourcesJar.enabled = publish + +javadoc { + inputs.property("moduleName", moduleName) + doFirst { + options.addStringOption('-module-path', classpath.asPath) + options.tags = [ "implNote" ] + } +} + +task javadocJar(type: Jar) { + classifier = 'javadoc' + from javadoc +} +javadocJar.enabled = publish + +artifacts { + archives sourcesJar, javadocJar +} + +uploadArchives { + repositories { + mavenDeployer { + + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } + + repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { + authentication(userName: ossrhUsername, password: ossrhPassword) + } + + pom.project { + name 'rlp4j' + packaging 'jar' + // optionally artifactId can be defined here + description 'a rlp module for the aion java kernel.' + url 'https://github.com/aionnetwork/aion/tree/master-pre-merge/modRlp' + + scm { + connection 'scm:git:https://github.com/aionnetwork/aion.git' + developerConnection 'git:https://github.com/aionnetwork/aion.git' + url 'https://github.com/aionnetwork/aion/tree/master' + } + + licenses { + license { + name 'MIT' + url 'https://opensource.org/licenses/MIT' + } + } + + developers { + developer { + id 'aion foundation dev' + name 'aion foundation dev' + email 'toengineering@aion.network' + } + } + } + } + } +} +uploadArchives.enabled = publish + diff --git a/modRlp/src/module-info.java b/modRlp/src/main/java/module-info.java similarity index 100% rename from modRlp/src/module-info.java rename to modRlp/src/main/java/module-info.java diff --git a/modRlp/src/org/aion/rlp/CompactEncoder.java b/modRlp/src/main/java/org/aion/rlp/CompactEncoder.java similarity index 100% rename from modRlp/src/org/aion/rlp/CompactEncoder.java rename to modRlp/src/main/java/org/aion/rlp/CompactEncoder.java diff --git a/modRlp/src/org/aion/rlp/DecodeResult.java b/modRlp/src/main/java/org/aion/rlp/DecodeResult.java similarity index 100% rename from modRlp/src/org/aion/rlp/DecodeResult.java rename to modRlp/src/main/java/org/aion/rlp/DecodeResult.java diff --git a/modRlp/src/org/aion/rlp/RLP.java b/modRlp/src/main/java/org/aion/rlp/RLP.java similarity index 96% rename from modRlp/src/org/aion/rlp/RLP.java rename to modRlp/src/main/java/org/aion/rlp/RLP.java index 169e74a4e1..806b7f9dbc 100644 --- a/modRlp/src/org/aion/rlp/RLP.java +++ b/modRlp/src/main/java/org/aion/rlp/RLP.java @@ -67,6 +67,9 @@ public class RLP { */ private static final int OFFSET_LONG_LIST = 0xf7; + private static final byte[] BYTES_SHORT_ITEM = new byte[] {(byte) OFFSET_SHORT_ITEM}; + private static final byte[] BYTES_SHORT_LIST = new byte[] {(byte) OFFSET_SHORT_LIST}; + // DECODING public static int decodeInt(byte[] data, int index) { @@ -259,27 +262,18 @@ private static void fullTraverse( } } } catch (Exception e) { - - // Only shown first 4K data - int length = endPos - startPos; - if (length > 4096) { - length = 4096; - } - throw new RuntimeException( "RLP wrong encoding (" - + Hex.toHexString(msgData, startPos, endPos - startPos > 1024 ? 1024 : endPos - startPos) + + Hex.toHexString( + msgData, + startPos, + endPos - startPos > 1024 ? 1024 : endPos - startPos) + ")", e); } catch (OutOfMemoryError e) { - // Only shown first 4K data - int length = endPos - startPos; - if (length > 4096) { - length = 4096; - } throw new RuntimeException( "Invalid RLP (excessive mem allocation while parsing) (" - + Hex.toHexString(msgData, startPos, length) + + Hex.toHexString(msgData, startPos, endPos - startPos) + ")", e); } @@ -353,7 +347,7 @@ private static DecodeResult decodeList(byte[] data, int pos, int len) { /** * Turn Object into its RLP encoded equivalent of a byte-array Support for String, Integer, - * BigInteger and Lists of any of these types. + * BigInteger and Lists of any of these type. * * @param input as object or List of objects * @return byte[] RLP encoded @@ -416,7 +410,7 @@ public static byte[] encodeLength(int length, int offset) { public static byte[] encodeByte(byte singleByte) { if ((singleByte & 0xFF) == 0) { - return new byte[] {(byte) OFFSET_SHORT_ITEM}; + return BYTES_SHORT_ITEM; } else if ((singleByte & 0xFF) <= 0x7F) { return new byte[] {singleByte}; } else { @@ -484,7 +478,7 @@ public static byte[] encodeBigInteger(BigInteger srcBigInteger) { public static byte[] encodeElement(byte[] srcData) { if (isNullOrZeroArray(srcData)) { - return new byte[] {(byte) OFFSET_SHORT_ITEM}; + return BYTES_SHORT_ITEM; } else if (isSingleZero(srcData)) { return srcData; } else if (srcData.length == 1 && (srcData[0] & 0xFF) < 0x80) { @@ -554,14 +548,12 @@ public static int calcElementPrefixSize(byte[] srcData) { public static byte[] encodeListHeader(int size) { if (size == 0) { - return new byte[] {(byte) OFFSET_SHORT_LIST}; + return BYTES_SHORT_LIST; } byte[] header; if (size < SIZE_THRESHOLD) { - - header = new byte[1]; - header[0] = (byte) (OFFSET_SHORT_LIST + size); + header = new byte[] {(byte) (OFFSET_SHORT_LIST + size)}; } else { // length of length = BX // prefix = [BX, [length]] @@ -592,7 +584,7 @@ public static byte[] encodeLongElementHeader(int length) { if (length < SIZE_THRESHOLD) { if (length == 0) { - return new byte[] {(byte) 0x80}; + return BYTES_SHORT_ITEM; } else { return new byte[] {(byte) (0x80 + length)}; } @@ -621,7 +613,7 @@ public static byte[] encodeLongElementHeader(int length) { public static byte[] encodeList(byte[]... elements) { if (elements == null) { - return new byte[] {(byte) OFFSET_SHORT_LIST}; + return BYTES_SHORT_LIST; } int totalLength = 0; diff --git a/modRlp/src/org/aion/rlp/RLPElement.java b/modRlp/src/main/java/org/aion/rlp/RLPElement.java similarity index 100% rename from modRlp/src/org/aion/rlp/RLPElement.java rename to modRlp/src/main/java/org/aion/rlp/RLPElement.java diff --git a/modRlp/src/org/aion/rlp/RLPItem.java b/modRlp/src/main/java/org/aion/rlp/RLPItem.java similarity index 83% rename from modRlp/src/org/aion/rlp/RLPItem.java rename to modRlp/src/main/java/org/aion/rlp/RLPItem.java index 8f0f24d701..96b6559d4d 100644 --- a/modRlp/src/org/aion/rlp/RLPItem.java +++ b/modRlp/src/main/java/org/aion/rlp/RLPItem.java @@ -13,10 +13,10 @@ public class RLPItem implements RLPElement { private final byte[] rlpData; /** - * @Jay inside the RLP encode/decode logic, there is no difference between null obj and + * @implNote Inside the RLP encode/decode logic, there is no difference between null obj and * zero-byte array Therefore, put empty array when we see the input data is null * - * @param rlpData + * @param rlpData byte array represent the encoded rlp data */ public RLPItem(byte[] rlpData) { this.rlpData = (rlpData == null) ? ByteUtil.EMPTY_BYTE_ARRAY : rlpData; diff --git a/modRlp/src/org/aion/rlp/RLPList.java b/modRlp/src/main/java/org/aion/rlp/RLPList.java similarity index 100% rename from modRlp/src/org/aion/rlp/RLPList.java rename to modRlp/src/main/java/org/aion/rlp/RLPList.java diff --git a/modRlp/src/org/aion/rlp/Utils.java b/modRlp/src/main/java/org/aion/rlp/Utils.java similarity index 100% rename from modRlp/src/org/aion/rlp/Utils.java rename to modRlp/src/main/java/org/aion/rlp/Utils.java diff --git a/modRlp/src/org/aion/rlp/Value.java b/modRlp/src/main/java/org/aion/rlp/Value.java similarity index 98% rename from modRlp/src/org/aion/rlp/Value.java rename to modRlp/src/main/java/org/aion/rlp/Value.java index 4adeb07ea5..8fb5a5a0d4 100644 --- a/modRlp/src/org/aion/rlp/Value.java +++ b/modRlp/src/main/java/org/aion/rlp/Value.java @@ -147,13 +147,14 @@ public byte[] getData() { public Value get(int index) { if (isList()) { // Guard for OutOfBounds - if (asList().size() <= index) { + List list = asList(); + if (list.size() <= index) { return new Value(null); } if (index < 0) { throw new RuntimeException("Negative index not allowed"); } - return new Value(asList().get(index)); + return new Value(list.get(index)); } // If this wasn't a slice you probably shouldn't be using this function return new Value(null); diff --git a/modRlp/test/org/aion/rlp/CompactEncoderTest.java b/modRlp/src/test/java/org/aion/rlp/CompactEncoderTest.java similarity index 100% rename from modRlp/test/org/aion/rlp/CompactEncoderTest.java rename to modRlp/src/test/java/org/aion/rlp/CompactEncoderTest.java diff --git a/modRlp/test/org/aion/rlp/DecodeResultTest.java b/modRlp/src/test/java/org/aion/rlp/DecodeResultTest.java similarity index 100% rename from modRlp/test/org/aion/rlp/DecodeResultTest.java rename to modRlp/src/test/java/org/aion/rlp/DecodeResultTest.java diff --git a/modRlp/test/org/aion/rlp/RLPDump.java b/modRlp/src/test/java/org/aion/rlp/RLPDump.java similarity index 100% rename from modRlp/test/org/aion/rlp/RLPDump.java rename to modRlp/src/test/java/org/aion/rlp/RLPDump.java diff --git a/modRlp/test/org/aion/rlp/RLPElementTest.java b/modRlp/src/test/java/org/aion/rlp/RLPElementTest.java similarity index 100% rename from modRlp/test/org/aion/rlp/RLPElementTest.java rename to modRlp/src/test/java/org/aion/rlp/RLPElementTest.java diff --git a/modRlp/test/org/aion/rlp/RLPSpecExtraTest.java b/modRlp/src/test/java/org/aion/rlp/RLPSpecExtraTest.java similarity index 100% rename from modRlp/test/org/aion/rlp/RLPSpecExtraTest.java rename to modRlp/src/test/java/org/aion/rlp/RLPSpecExtraTest.java diff --git a/modRlp/test/org/aion/rlp/RLPSpecTest.java b/modRlp/src/test/java/org/aion/rlp/RLPSpecTest.java similarity index 100% rename from modRlp/test/org/aion/rlp/RLPSpecTest.java rename to modRlp/src/test/java/org/aion/rlp/RLPSpecTest.java diff --git a/modRlp/test/org/aion/rlp/RLPTest.java b/modRlp/src/test/java/org/aion/rlp/RLPTest.java similarity index 99% rename from modRlp/test/org/aion/rlp/RLPTest.java rename to modRlp/src/test/java/org/aion/rlp/RLPTest.java index 6026016edd..cbba08c101 100644 --- a/modRlp/test/org/aion/rlp/RLPTest.java +++ b/modRlp/src/test/java/org/aion/rlp/RLPTest.java @@ -40,13 +40,13 @@ import static org.aion.rlp.RlpTestData.test13; import static org.aion.rlp.RlpTestData.test16; import static org.aion.util.bytes.ByteUtil.byteArrayToInt; +import static org.aion.util.conversions.Hex.encode; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; -import static org.spongycastle.util.encoders.Hex.encode; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -981,14 +981,14 @@ public void testRlpDecode() { decodedData = (byte[]) decode(Hex.decode(result13), pos).getDecoded(); assertTrue(test13.compareTo(new BigInteger(1, decodedData)) == 0); - // Need to test with different expected value, because decoding doesn't recognize types + // Need to test with different expected value, because decoding doesn't recognize type Object testObject1 = decode(Hex.decode(result14), pos).getDecoded(); assertTrue(Objects.deepEquals(expected14, testObject1)); // Object testObject2 = decode(Hex.decode(result15), pos).getDecoded(); // assertTrue(DeepEquals.deepEquals(test15, testObject2)); - // Need to test with different expected value, because decoding doesn't recognize types + // Need to test with different expected value, because decoding doesn't recognize type Object testObject3 = decode(Hex.decode(result16), pos).getDecoded(); assertTrue(Objects.deepEquals(expected16, testObject3)); } diff --git a/modRlp/test/org/aion/rlp/RlpTestData.java b/modRlp/src/test/java/org/aion/rlp/RlpTestData.java similarity index 100% rename from modRlp/test/org/aion/rlp/RlpTestData.java rename to modRlp/src/test/java/org/aion/rlp/RlpTestData.java diff --git a/modRlp/test/org/aion/rlp/UtilsTest.java b/modRlp/src/test/java/org/aion/rlp/UtilsTest.java similarity index 100% rename from modRlp/test/org/aion/rlp/UtilsTest.java rename to modRlp/src/test/java/org/aion/rlp/UtilsTest.java diff --git a/modRlp/test/org/aion/rlp/ValueTest.java b/modRlp/src/test/java/org/aion/rlp/ValueTest.java similarity index 98% rename from modRlp/test/org/aion/rlp/ValueTest.java rename to modRlp/src/test/java/org/aion/rlp/ValueTest.java index 77b068e26a..e1bba8f4ea 100644 --- a/modRlp/test/org/aion/rlp/ValueTest.java +++ b/modRlp/src/test/java/org/aion/rlp/ValueTest.java @@ -7,8 +7,8 @@ import java.math.BigInteger; import java.util.Arrays; +import org.aion.util.conversions.Hex; import org.junit.Test; -import org.spongycastle.util.encoders.Hex; public class ValueTest { diff --git a/modTxPool/build.gradle b/modTxPool/build.gradle index db8e6579fd..3845c55bd8 100644 --- a/modTxPool/build.gradle +++ b/modTxPool/build.gradle @@ -1,6 +1,5 @@ ext.moduleName = 'aion.txpool' dependencies { - compile project(':modAionBase') -// runtime project(':modTxPoolImpl') + compile project(':aion_vm_api') } diff --git a/modTxPool/src/module-info.java b/modTxPool/src/module-info.java index 974e1fcddb..bb47c23c84 100644 --- a/modTxPool/src/module-info.java +++ b/modTxPool/src/module-info.java @@ -1,5 +1,4 @@ module aion.txpool { - requires aion.base; requires aion.vm.api; exports org.aion.txpool; diff --git a/modTxPool/src/org/aion/txpool/ITxPool.java b/modTxPool/src/org/aion/txpool/ITxPool.java index 02a7b30008..ffad7a66b7 100644 --- a/modTxPool/src/org/aion/txpool/ITxPool.java +++ b/modTxPool/src/org/aion/txpool/ITxPool.java @@ -3,15 +3,15 @@ import java.math.BigInteger; import java.util.List; import java.util.Map; -import org.aion.base.type.ITransaction; -import org.aion.vm.api.interfaces.Address; +import org.aion.interfaces.tx.Transaction; +import org.aion.types.Address; /** * Aion pending state should be the only user of transaction pool. * * @param */ -public interface ITxPool { +public interface ITxPool { String PROP_TX_TIMEOUT = "tx-timeout"; String PROP_BLOCK_SIZE_LIMIT = "blk-size-limit"; diff --git a/modTxPool/src/org/aion/txpool/TxPoolModule.java b/modTxPool/src/org/aion/txpool/TxPoolModule.java index 48d1b3296c..6902ef6643 100644 --- a/modTxPool/src/org/aion/txpool/TxPoolModule.java +++ b/modTxPool/src/org/aion/txpool/TxPoolModule.java @@ -1,20 +1,20 @@ package org.aion.txpool; import java.util.Properties; -import org.aion.base.type.ITransaction; +import org.aion.interfaces.tx.Transaction; public final class TxPoolModule { private static TxPoolModule singleton = null; public static final String MODULENAME = "module_name"; - private static ITxPool TXPOOL; + private static ITxPool TXPOOL; @SuppressWarnings("unchecked") private TxPoolModule(Properties config) throws Exception { String moduleName = (String) config.get(MODULENAME); if (moduleName != null) { TXPOOL = - (ITxPool) + (ITxPool) getClass() .getClassLoader() .loadClass(moduleName) diff --git a/modTxPoolImpl/build.gradle b/modTxPoolImpl/build.gradle index 3c9a90466f..8ade53f69b 100644 --- a/modTxPoolImpl/build.gradle +++ b/modTxPoolImpl/build.gradle @@ -3,18 +3,21 @@ test.dependsOn copyNativeLibsForModuleTests clean.dependsOn deleteNativeLibs dependencies { - compile project(':modAionBase') - compile project(':modTxPool') - compile project(':modLogger') + compile project(':aion_vm_api') + compile 'network.aion:util4j:0.4.0' + compile 'network.aion:log4j:0.4.0' compile 'com.madgag.spongycastle:prov:1.58.0.0' compile 'com.madgag.spongycastle:core:1.58.0.0' - testCompile project(':modCrypto') - testCompile project(':modRlp') - testCompile project(':modMcf') - testCompile project(':modAion') + compile project(':modTxPool') + + testCompile 'network.aion:crypto4j:0.4.0' + testCompile 'network.aion:rlp4j:0.4.0' testCompile 'junit:junit:4.12' testCompile 'org.hamcrest:hamcrest-core:1.3' + + testCompile project(':modMcf') + testCompile project(':modAion') } // Skip unit tests when doing build task; unit tests are all mixed up with diff --git a/modTxPoolImpl/src/module-info.java b/modTxPoolImpl/src/module-info.java index e586f36175..7053f7db3e 100644 --- a/modTxPoolImpl/src/module-info.java +++ b/modTxPoolImpl/src/module-info.java @@ -1,7 +1,7 @@ module aion.txpool.impl { requires aion.log; requires slf4j.api; - requires aion.base; + requires aion.util; requires aion.txpool; requires aion.vm.api; diff --git a/modTxPoolImpl/src/org/aion/txpool/common/AbstractTxPool.java b/modTxPoolImpl/src/org/aion/txpool/common/AbstractTxPool.java index 29f2db5d34..b1b8da86a2 100644 --- a/modTxPoolImpl/src/org/aion/txpool/common/AbstractTxPool.java +++ b/modTxPoolImpl/src/org/aion/txpool/common/AbstractTxPool.java @@ -17,16 +17,17 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.ReentrantReadWriteLock; -import org.aion.base.Constant; -import org.aion.base.type.ITransaction; -import org.aion.base.util.ByteArrayWrapper; + +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; +import org.aion.util.bytes.ByteUtil; import org.slf4j.Logger; -import org.spongycastle.pqc.math.linearalgebra.ByteUtils; -import org.aion.vm.api.interfaces.Address; +import org.aion.interfaces.tx.Transaction; +import org.aion.interfaces.block.Constant; -public abstract class AbstractTxPool { +public abstract class AbstractTxPool { protected static final Logger LOG = AionLoggerFactory.getLogger(LogEnum.TXPOOL.toString()); @@ -146,7 +147,7 @@ protected void sortTxn() { SortedMap> timeMap = Collections.synchronizedSortedMap(new TreeMap<>()); - Map updatedTx = new HashMap<>(); + Map updatedTx = new HashMap<>(); this.mainMap .entrySet() .parallelStream() @@ -157,13 +158,13 @@ protected void sortTxn() { return; } - ITransaction tx = ts.getTx(); + Transaction tx = ts.getTx(); // Gen temp timeMap long timestamp = tx.getTimeStampBI().longValue() / multiplyM; Map> nonceMap; - ITransaction replacedTx = null; + Transaction replacedTx = null; synchronized (accMap) { if (accMap.get(tx.getSenderAddress()) != null) { nonceMap = accMap.get(tx.getSenderAddress()); @@ -182,7 +183,7 @@ protected void sortTxn() { LOG.trace( "AbstractTxPool.sortTxn Put tx into nonceMap: nonce:[{}] ts:[{}] nrgCharge:[{}]", nonce, - ByteUtils.toHexString(e.getKey().getData()), + ByteUtil.toHexString(e.getKey().getData()), nrgCharge.toString()); } @@ -258,7 +259,7 @@ protected void sortTxn() { }); if (!updatedTx.isEmpty()) { - for (Map.Entry en : updatedTx.entrySet()) { + for (Map.Entry en : updatedTx.entrySet()) { ByteArrayWrapper bw = ByteArrayWrapper.wrap(en.getKey().getTransactionHash()); if (this.timeView.get(en.getValue()) != null) { this.timeView.get(en.getValue()).remove(bw); diff --git a/modTxPoolImpl/src/org/aion/txpool/common/AccountState.java b/modTxPoolImpl/src/org/aion/txpool/common/AccountState.java index 298c325f86..74ad34db2f 100644 --- a/modTxPoolImpl/src/org/aion/txpool/common/AccountState.java +++ b/modTxPoolImpl/src/org/aion/txpool/common/AccountState.java @@ -7,7 +7,7 @@ import java.util.SortedMap; import java.util.TreeMap; import java.util.concurrent.atomic.AtomicBoolean; -import org.aion.base.util.ByteArrayWrapper; +import org.aion.types.ByteArrayWrapper; public class AccountState { private final SortedMap> diff --git a/modTxPoolImpl/src/org/aion/txpool/common/TxDependList.java b/modTxPoolImpl/src/org/aion/txpool/common/TxDependList.java index 28b342132b..2c0823cf38 100644 --- a/modTxPoolImpl/src/org/aion/txpool/common/TxDependList.java +++ b/modTxPoolImpl/src/org/aion/txpool/common/TxDependList.java @@ -3,7 +3,8 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.List; -import org.aion.vm.api.interfaces.Address; + +import org.aion.types.Address; public class TxDependList { private final List txList; diff --git a/modTxPoolImpl/src/org/aion/txpool/zero/TxPoolA0.java b/modTxPoolImpl/src/org/aion/txpool/zero/TxPoolA0.java index 4e71de9712..f4ee0061b0 100644 --- a/modTxPoolImpl/src/org/aion/txpool/zero/TxPoolA0.java +++ b/modTxPoolImpl/src/org/aion/txpool/zero/TxPoolA0.java @@ -16,18 +16,18 @@ import java.util.SortedMap; import java.util.TreeMap; import java.util.stream.Collectors; -import org.aion.base.type.ITransaction; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.util.TimeInstant; +import org.aion.interfaces.tx.Transaction; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.txpool.ITxPool; import org.aion.txpool.common.AbstractTxPool; import org.aion.txpool.common.AccountState; import org.aion.txpool.common.TxDependList; -import org.spongycastle.pqc.math.linearalgebra.ByteUtils; -import org.aion.vm.api.interfaces.Address; +import org.aion.util.bytes.ByteUtil; +import org.aion.util.time.TimeInstant; @SuppressWarnings("unchecked") -public class TxPoolA0 extends AbstractTxPool implements ITxPool { +public class TxPoolA0 extends AbstractTxPool implements ITxPool { public TxPoolA0() { super(); @@ -120,7 +120,7 @@ public List add(List txl) { if (LOG.isWarnEnabled()) { LOG.warn( "The tx hash existed in the pool! [{}]", - ByteUtils.toHexString(bw.getData())); + ByteUtil.toHexString(bw.getData())); } continue; } @@ -128,7 +128,7 @@ public List add(List txl) { if (LOG.isTraceEnabled()) { LOG.trace( "Put tx into mainMap: hash:[{}] tx:[{}]", - ByteUtils.toHexString(bw.getData()), + ByteUtil.toHexString(bw.getData()), tx.toString()); } @@ -242,7 +242,7 @@ public List remove(Map accNonce) { .forEach( bw -> { if (this.getMainMap().get(bw) != null) { - ITransaction tx = this.getMainMap().get(bw).getTx().clone(); + Transaction tx = this.getMainMap().get(bw).getTx().clone(); removedTxl.add((TX) tx); long timestamp = tx.getTimeStampBI().longValue() / multiplyM; @@ -300,7 +300,7 @@ public List remove(List txs) { if (LOG.isTraceEnabled()) { LOG.trace( "TxPoolA0.remove:[{}] nonce:[{}]", - ByteUtils.toHexString(tx.getTransactionHash()), + ByteUtil.toHexString(tx.getTransactionHash()), tx.getNonceBI().toString()); } @@ -477,7 +477,7 @@ public List snapshot() { if (dependTx == null || snapshotSet.contains(dependTx)) { boolean firstTx = true; for (ByteArrayWrapper bw : pair.getValue().getTxList()) { - ITransaction itx = this.getMainMap().get(bw).getTx(); + Transaction itx = this.getMainMap().get(bw).getTx(); cnt_txSz += itx.getEncoded().length; cnt_nrg += itx.getNrgConsume(); @@ -524,7 +524,7 @@ public List snapshot() { firstTx = true; for (ByteArrayWrapper bw : nonPickedTx.get(ancestor).getValue().getTxList()) { - ITransaction itx = this.getMainMap().get(bw).getTx(); + Transaction itx = this.getMainMap().get(bw).getTx(); cnt_txSz += itx.getEncoded().length; cnt_nrg += itx.getNrgConsume(); diff --git a/modTxPoolImpl/test/org/aion/txpool/test/TxnPoolTest.java b/modTxPoolImpl/test/org/aion/txpool/test/TxnPoolTest.java index 7bccb76400..aec6a7d886 100644 --- a/modTxPoolImpl/test/org/aion/txpool/test/TxnPoolTest.java +++ b/modTxPoolImpl/test/org/aion/txpool/test/TxnPoolTest.java @@ -12,19 +12,20 @@ import java.util.Map; import java.util.Properties; import java.util.Random; -import org.aion.base.type.AionAddress; -import org.aion.base.type.Hash256; -import org.aion.base.type.ITransaction; + +import org.aion.interfaces.tx.Transaction; +import org.aion.types.Address; import org.aion.crypto.ECKey; import org.aion.crypto.ECKeyFac; import org.aion.txpool.ITxPool; import org.aion.txpool.zero.TxPoolA0; +import org.aion.types.Hash256; import org.aion.zero.types.AionTransaction; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.spongycastle.pqc.math.linearalgebra.ByteUtils; -import org.aion.vm.api.interfaces.Address; + public class TxnPoolTest { @@ -67,8 +68,8 @@ public void add1() { Properties config = new Properties(); config.put("tx-timeout", "100"); - ITxPool tp = new TxPoolA0<>(config); - List txnl = getMockTransaction(); + ITxPool tp = new TxPoolA0<>(config); + List txnl = getMockTransaction(); ((AionTransaction) txnl.get(0)).sign(key.get(0)); tp.add(txnl); @@ -76,12 +77,12 @@ public void add1() { assertTrue(tp.size() == 1); } - private List getMockTransaction() { + private List getMockTransaction() { return Collections.singletonList( new AionTransaction( ByteUtils.fromHexString("0000000000000001"), - AionAddress.wrap(key.get(0).getAddress()), - AionAddress.wrap( + Address.wrap(key.get(0).getAddress()), + Address.wrap( "0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), @@ -94,8 +95,8 @@ public void remove() { Properties config = new Properties(); config.put("tx-timeout", "100"); - ITxPool tp = new TxPoolA0<>(config); - List txnl = getMockTransaction(); + ITxPool tp = new TxPoolA0<>(config); + List txnl = getMockTransaction(); ((AionTransaction) txnl.get(0)).sign(key.get(0)); tp.add(txnl); assertTrue(tp.size() == 1); @@ -112,9 +113,9 @@ public void remove2() { Properties config = new Properties(); config.put("tx-timeout", "100"); // 100 sec - ITxPool tp = new TxPoolA0<>(config); - List txl = new ArrayList<>(); - List txlrm = new ArrayList<>(); + ITxPool tp = new TxPoolA0<>(config); + List txl = new ArrayList<>(); + List txlrm = new ArrayList<>(); int cnt = 20; for (int i = 0; i < cnt; i++) { AionTransaction tx = @@ -143,9 +144,9 @@ public void remove3() { Properties config = new Properties(); config.put("tx-timeout", "100"); // 100 sec - ITxPool tp = new TxPoolA0<>(config); - List txl = new ArrayList<>(); - List txlrm = new ArrayList<>(); + ITxPool tp = new TxPoolA0<>(config); + List txl = new ArrayList<>(); + List txlrm = new ArrayList<>(); int cnt = 20; for (int i = 0; i < cnt; i++) { AionTransaction tx = @@ -171,33 +172,33 @@ public void remove3() { assertTrue(tp.size() == 10); } - private ITransaction genTransaction(byte[] nonce) { + private Transaction genTransaction(byte[] nonce) { return new AionTransaction( nonce, - AionAddress.wrap(key.get(0).getAddress()), - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000001"), + Address.wrap(key.get(0).getAddress()), + Address.wrap("0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), 10000L, 1L); } - private ITransaction genTransaction(byte[] nonce, int _index) { + private Transaction genTransaction(byte[] nonce, int _index) { return new AionTransaction( nonce, - AionAddress.wrap(key.get(_index).getAddress()), - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000001"), + Address.wrap(key.get(_index).getAddress()), + Address.wrap("0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), 10000L, 1L); } - private ITransaction genTransactionRandomPrice(byte[] nonce, long price) { + private Transaction genTransactionRandomPrice(byte[] nonce, long price) { return new AionTransaction( nonce, - AionAddress.wrap(key.get(0).getAddress()), - AionAddress.wrap("0000000000000000000000000000000000000000000000000000000000000001"), + Address.wrap(key.get(0).getAddress()), + Address.wrap("0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), 10000L, @@ -209,8 +210,8 @@ public void timeout1() throws Exception { Properties config = new Properties(); config.put("tx-timeout", "10"); // 10 sec - ITxPool tp = new TxPoolA0<>(config); - List txnl = getMockTransaction(); + ITxPool tp = new TxPoolA0<>(config); + List txnl = getMockTransaction(); ((AionTransaction) txnl.get(0)).sign(key.get(0)); txnl.get(0).setNrgConsume(30000L); tp.add(txnl); @@ -226,8 +227,8 @@ public void timeout2() throws Exception { Properties config = new Properties(); config.put("tx-timeout", "1"); // 10 sec - ITxPool tp = new TxPoolA0<>(config); - List txnl = getMockTransaction(); + ITxPool tp = new TxPoolA0<>(config); + List txnl = getMockTransaction(); ((AionTransaction) txnl.get(0)).sign(key.get(0)); txnl.get(0).setNrgConsume(30000L); tp.add(txnl); @@ -243,8 +244,8 @@ public void snapshot() { Properties config = new Properties(); config.put("tx-timeout", "10"); // 10 sec - ITxPool tp = new TxPoolA0<>(config); - List txnl = getMockTransaction(); + ITxPool tp = new TxPoolA0<>(config); + List txnl = getMockTransaction(); ((AionTransaction) txnl.get(0)).sign(key.get(0)); tp.add(txnl); @@ -257,8 +258,8 @@ public void snapshot2() { Properties config = new Properties(); config.put("tx-timeout", "100"); // 100 sec - ITxPool tp = new TxPoolA0<>(config); - List txl = new ArrayList<>(); + ITxPool tp = new TxPoolA0<>(config); + List txl = new ArrayList<>(); int cnt = 26; for (int i = 0; i < cnt; i++) { AionTransaction txe = @@ -281,15 +282,15 @@ public void snapshot3() { Properties config = new Properties(); config.put("tx-timeout", "100"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 26; for (int i = 0; i < cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) i; - ITransaction txn = genTransaction(nonce); + Transaction txn = genTransaction(nonce); ((AionTransaction) txn).sign(key.get(0)); txn.setNrgConsume(i + 1); txnl.add(txn); @@ -298,10 +299,10 @@ public void snapshot3() { assertTrue(tp.size() == cnt); // sort the inserted txs - List txl = tp.snapshot(); + List txl = tp.snapshot(); long nonce = 0; - for (ITransaction tx : txl) { + for (Transaction tx : txl) { assertTrue((new BigInteger(tx.getNonce())).longValue() == nonce++); } } @@ -311,15 +312,15 @@ public void snapshot4() { Properties config = new Properties(); config.put("tx-timeout", "100"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 26; for (int i = 0; i < cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) i; - ITransaction txn = genTransaction(nonce); + Transaction txn = genTransaction(nonce); ((AionTransaction) txn).sign(key.get(0)); txn.setNrgConsume(50 - i); txnl.add(txn); @@ -328,10 +329,10 @@ public void snapshot4() { assertTrue(tp.size() == cnt); // sort the inserted txs - List txl = tp.snapshot(); + List txl = tp.snapshot(); long nonce = 0; - for (ITransaction tx : txl) { + for (Transaction tx : txl) { assertTrue((new BigInteger(tx.getNonce())).longValue() == nonce++); } } @@ -341,16 +342,16 @@ public void snapshot5() { Properties config = new Properties(); config.put("tx-timeout", "100"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 100; Random r = new Random(); for (int i = 0; i < cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) i; - ITransaction txn = genTransaction(nonce); + Transaction txn = genTransaction(nonce); ((AionTransaction) txn).sign(key.get(0)); txn.setNrgConsume(r.nextInt(1000)); txnl.add(txn); @@ -359,12 +360,12 @@ public void snapshot5() { assertTrue(tp.size() == cnt); // sort the inserted txs - List txl = tp.snapshot(); + List txl = tp.snapshot(); assertTrue(tp.size() == txl.size()); assertTrue(tp.snapshotAll().size() == txl.size()); long nonce = 0; - for (ITransaction tx : txl) { + for (Transaction tx : txl) { assertTrue((new BigInteger(tx.getNonce())).longValue() == nonce++); } } @@ -374,16 +375,16 @@ public void snapshot6() { Properties config = new Properties(); config.put("tx-timeout", "100"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 200; Random r = new Random(); for (int i = 0; i < cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) i; - ITransaction txn = genTransactionRandomPrice(nonce, r.nextInt(1000)); + Transaction txn = genTransactionRandomPrice(nonce, r.nextInt(1000)); ((AionTransaction) txn).sign(key.get(0)); txn.setNrgConsume(r.nextInt(1000)); txnl.add(txn); @@ -392,12 +393,12 @@ public void snapshot6() { assertTrue(tp.size() == cnt); // sort the inserted txs - List txl = tp.snapshot(); + List txl = tp.snapshot(); assertTrue(tp.size() == txl.size()); assertTrue(tp.snapshotAll().size() == txl.size()); long nonce = 0; - for (ITransaction tx : txl) { + for (Transaction tx : txl) { assertTrue((new BigInteger(tx.getNonce())).longValue() == nonce++); } } @@ -407,16 +408,16 @@ public void snapshot7() { Properties config = new Properties(); config.put("tx-timeout", "100"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 200; Random r = new Random(); for (int i = 0; i < cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) i; - ITransaction txn = genTransactionRandomPrice(nonce, r.nextInt(1000)); + Transaction txn = genTransactionRandomPrice(nonce, r.nextInt(1000)); ((AionTransaction) txn).sign(key.get(i < 100 ? 0 : 1)); txn.setNrgConsume(r.nextInt(1000)); @@ -426,12 +427,12 @@ public void snapshot7() { assertTrue(tp.size() == cnt); // sort the inserted txs - List txl = tp.snapshot(); + List txl = tp.snapshot(); assertTrue(tp.size() == txl.size()); assertTrue(tp.snapshotAll().size() == txl.size()); long nonce = 0; - for (ITransaction tx : txl) { + for (Transaction tx : txl) { assertTrue((new BigInteger(tx.getNonce())).longValue() == nonce++); } } @@ -441,16 +442,16 @@ public void snapshot8() { Properties config = new Properties(); config.put("tx-timeout", "100"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 200; Random r = new Random(); for (int i = 0; i < cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) i; - ITransaction txn = genTransactionRandomPrice(nonce, r.nextInt(1000)); + Transaction txn = genTransactionRandomPrice(nonce, r.nextInt(1000)); ((AionTransaction) txn).sign(key.get(r.nextInt(10))); txn.setNrgConsume(r.nextInt(1000)); @@ -460,12 +461,12 @@ public void snapshot8() { assertTrue(tp.size() == cnt); // sort the inserted txs - List txl = tp.snapshot(); + List txl = tp.snapshot(); assertTrue(tp.size() == txl.size()); assertTrue(tp.snapshotAll().size() == txl.size()); long nonce = 0; - for (ITransaction tx : txl) { + for (Transaction tx : txl) { assertTrue((new BigInteger(tx.getNonce())).longValue() == nonce++); } } @@ -475,15 +476,15 @@ public void snapshot9() { Properties config = new Properties(); config.put("tx-timeout", "100"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 25; // Random r = new Random(); for (int i = 0; i < cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) i; - ITransaction txn = genTransaction(nonce, 0); + Transaction txn = genTransaction(nonce, 0); ((AionTransaction) txn).sign(key.get(0)); txn.setNrgConsume(1); @@ -492,11 +493,11 @@ public void snapshot9() { tp.add(txnl); assertTrue(tp.size() == cnt); - List txnl2 = new ArrayList<>(); + List txnl2 = new ArrayList<>(); for (int i = 0; i < cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) i; - ITransaction txn = genTransaction(nonce, 1); + Transaction txn = genTransaction(nonce, 1); ((AionTransaction) txn).sign(key.get(1)); txn.setNrgConsume(1); @@ -506,12 +507,12 @@ public void snapshot9() { assertTrue(tp.size() == cnt * 2); // sort the inserted txs - List txl = tp.snapshot(); + List txl = tp.snapshot(); assertTrue(tp.size() == txl.size()); assertTrue(tp.snapshotAll().size() == txl.size()); int check = 0; - for (ITransaction tx : txl) { + for (Transaction tx : txl) { if (check < 25) { assertTrue( Hash256.wrap(txnl.get(check).getTransactionHash()) @@ -533,15 +534,15 @@ public void snapshot10() { Properties config = new Properties(); config.put("tx-timeout", "100"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 16; // Random r = new Random(); for (int i = 0; i < cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) i; - ITransaction txn = genTransaction(nonce, 0); + Transaction txn = genTransaction(nonce, 0); ((AionTransaction) txn).sign(key.get(0)); txn.setNrgConsume(1); @@ -551,7 +552,7 @@ public void snapshot10() { for (int i = 0; i < cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) i; - ITransaction txn = genTransaction(nonce, 1); + Transaction txn = genTransaction(nonce, 1); ((AionTransaction) txn).sign(key.get(1)); txn.setNrgConsume(1); @@ -561,7 +562,7 @@ public void snapshot10() { for (int i = 16; i < 16 + cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) i; - ITransaction txn = genTransaction(nonce, 0); + Transaction txn = genTransaction(nonce, 0); ((AionTransaction) txn).sign(key.get(0)); txn.setNrgConsume(1); @@ -571,7 +572,7 @@ public void snapshot10() { for (int i = 16; i < 16 + cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) i; - ITransaction txn = genTransaction(nonce, 1); + Transaction txn = genTransaction(nonce, 1); ((AionTransaction) txn).sign(key.get(1)); txn.setNrgConsume(1); @@ -582,12 +583,12 @@ public void snapshot10() { assertTrue(tp.size() == cnt * 4); // sort the inserted txs - List txl = tp.snapshot(); + List txl = tp.snapshot(); assertTrue(tp.size() == txl.size()); assertTrue(tp.snapshotAll().size() == txl.size()); int check = 0; - for (ITransaction tx : txl) { + for (Transaction tx : txl) { assertTrue( Hash256.wrap(txnl.get(check).getTransactionHash()) .toString() @@ -601,12 +602,12 @@ public void addRepeatedTxn() { Properties config = new Properties(); config.put("tx-timeout", "10"); - ITxPool tp = new TxPoolA0<>(config); - ITransaction txn = + ITxPool tp = new TxPoolA0<>(config); + Transaction txn = new AionTransaction( ByteUtils.fromHexString("0000000000000001"), - AionAddress.wrap(key.get(0).getAddress()), - AionAddress.wrap(key.get(0).getAddress()), + Address.wrap(key.get(0).getAddress()), + Address.wrap(key.get(0).getAddress()), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), 10000L, @@ -614,7 +615,7 @@ public void addRepeatedTxn() { ((AionTransaction) txn).sign(key.get(0)); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); txnl.add(txn); txnl.add(txn); tp.add(txnl); @@ -627,15 +628,15 @@ public void addRepeatedTxn2() { Properties config = new Properties(); config.put("tx-timeout", "10"); - ITxPool tp = new TxPoolA0<>(config); + ITxPool tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 10; for (int i = 0; i < cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) i; - ITransaction txn = genTransaction(nonce); + Transaction txn = genTransaction(nonce); ((AionTransaction) txn).sign(key.get(0)); txn.setNrgConsume(50); txnl.add(txn); @@ -646,12 +647,12 @@ public void addRepeatedTxn2() { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) 5; - ITransaction txn = genTransaction(nonce); + Transaction txn = genTransaction(nonce); ((AionTransaction) txn).sign(key.get(0)); txn.setNrgConsume(500); tp.add(txn); - List snapshot = tp.snapshot(); + List snapshot = tp.snapshot(); assertTrue(snapshot.size() == cnt); assertTrue(snapshot.get(5).equals(txn)); @@ -662,15 +663,15 @@ public void addRepeatedTxn3() { Properties config = new Properties(); config.put("tx-timeout", "10"); - ITxPool tp = new TxPoolA0<>(config); + ITxPool tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 10; for (int i = 0; i < cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) i; - ITransaction txn = genTransaction(nonce); + Transaction txn = genTransaction(nonce); ((AionTransaction) txn).sign(key.get(0)); txn.setNrgConsume(50); txnl.add(txn); @@ -682,12 +683,12 @@ public void addRepeatedTxn3() { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) 5; - ITransaction txn = genTransaction(nonce); + Transaction txn = genTransaction(nonce); ((AionTransaction) txn).sign(key.get(0)); txn.setNrgConsume(500); tp.add(txn); - List snapshot = tp.snapshot(); + List snapshot = tp.snapshot(); assertTrue(snapshot.size() == cnt); assertTrue(snapshot.get(5).equals(txn)); @@ -698,12 +699,12 @@ public void addTxWithSameNonce() { Properties config = new Properties(); config.put("tx-timeout", "10"); - ITxPool tp = new TxPoolA0<>(config); + ITxPool tp = new TxPoolA0<>(config); - ITransaction txn = genTransaction(ByteUtils.fromHexString("0000000000000001")); + Transaction txn = genTransaction(ByteUtils.fromHexString("0000000000000001")); txn.setNrgConsume(100); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); ((AionTransaction) txn).sign(key.get(0)); txnl.add(txn); @@ -716,7 +717,7 @@ public void addTxWithSameNonce() { assertTrue(tp.size() == 1); - List txl = tp.snapshot(); + List txl = tp.snapshot(); assertTrue(txl.size() == 1); assertTrue(new BigInteger(txl.get(0).getTimestamp()).longValue() == t); } @@ -726,20 +727,20 @@ public void noncebyAccountTest() { Properties config = new Properties(); config.put("tx-timeout", "10"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - Address acc = AionAddress.wrap(key.get(0).getAddress()); + Address acc = Address.wrap(key.get(0).getAddress()); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 100; for (int i = 0; i < cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) (i + 1); - ITransaction txn = + Transaction txn = new AionTransaction( nonce, acc, - AionAddress.wrap( + Address.wrap( "0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), @@ -768,20 +769,20 @@ public void noncebyAccountTest2() { Properties config = new Properties(); config.put("tx-timeout", "10"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 100; for (ECKey aKey1 : key) { - Address acc = AionAddress.wrap(aKey1.getAddress()); + Address acc = Address.wrap(aKey1.getAddress()); for (int i = 0; i < cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) (i + 1); - ITransaction txn = + Transaction txn = new AionTransaction( nonce, acc, - AionAddress.wrap( + Address.wrap( "0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), @@ -801,7 +802,7 @@ public void noncebyAccountTest2() { tp.snapshot(); for (ECKey aKey : key) { - List nl = tp.getNonceList(AionAddress.wrap(aKey.getAddress())); + List nl = tp.getNonceList(Address.wrap(aKey.getAddress())); for (int i = 0; i < cnt; i++) { assertTrue(nl.get(i).equals(BigInteger.valueOf(i + 1))); } @@ -813,20 +814,20 @@ public void feemapTest() { Properties config = new Properties(); config.put("tx-timeout", "10"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 100; byte[] nonce = new byte[Long.BYTES]; for (int i = 0; i < cnt; i++) { nonce[Long.BYTES - 1] = 1; - Address addr = AionAddress.wrap(key2.get(i).getAddress()); - ITransaction txn = + Address addr = Address.wrap(key2.get(i).getAddress()); + Transaction txn = new AionTransaction( nonce, addr, - AionAddress.wrap( + Address.wrap( "0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), @@ -857,15 +858,15 @@ public void TxnfeeCombineTest() { Properties config = new Properties(); config.put("tx-timeout", "100"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 10; for (int i = 0; i < cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) (i + 1); - ITransaction txn = genTransaction(nonce); + Transaction txn = genTransaction(nonce); ((AionTransaction) txn).sign(key.get(0)); txn.setNrgConsume(i + 1); @@ -888,15 +889,15 @@ public void TxnfeeCombineTest2() { Properties config = new Properties(); config.put("tx-timeout", "100"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 17; for (int i = 0; i < cnt; i++) { byte[] nonce = new byte[Long.BYTES]; nonce[Long.BYTES - 1] = (byte) (i + 1); - ITransaction txn = genTransaction(nonce); + Transaction txn = genTransaction(nonce); ((AionTransaction) txn).sign(key.get(0)); txn.setNrgConsume(i + 1); txnl.add(txn); @@ -921,18 +922,18 @@ public void TxnfeeCombineTest2() { Properties config = new Properties(); config.put("tx-timeout", "100"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 10000; for (ECKey aKey1 : key) { - Address acc = AionAddress.wrap(aKey1.getAddress()); + Address acc = Address.wrap(aKey1.getAddress()); for (int i = 0; i < cnt; i++) { - ITransaction txn = + Transaction txn = new AionTransaction( BigInteger.valueOf(i).toByteArray(), acc, - AionAddress.wrap( + Address.wrap( "0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), @@ -953,7 +954,7 @@ public void TxnfeeCombineTest2() { System.out.println("time spent: " + (System.currentTimeMillis() - start) + " ms."); for (ECKey aKey : key) { - List nl = tp.getNonceList(AionAddress.wrap(aKey.getAddress())); + List nl = tp.getNonceList(Address.wrap(aKey.getAddress())); for (int i = 0; i < cnt; i++) { assertTrue(nl.get(i).equals(BigInteger.valueOf(i))); } @@ -968,18 +969,18 @@ public void TxnfeeCombineTest2() { Properties config = new Properties(); config.put("tx-timeout", "100"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 10000; for (ECKey aKey2 : key) { - Address acc = AionAddress.wrap(aKey2.getAddress()); + Address acc = Address.wrap(aKey2.getAddress()); for (int i = 0; i < cnt; i++) { - ITransaction txn = + Transaction txn = new AionTransaction( BigInteger.valueOf(i).toByteArray(), acc, - AionAddress.wrap( + Address.wrap( "0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), @@ -1003,11 +1004,11 @@ public void TxnfeeCombineTest2() { txnl.clear(); for (ECKey aKey1 : key) { for (int i = 0; i < cnt2; i++) { - ITransaction txn = + Transaction txn = new AionTransaction( BigInteger.valueOf(cnt + i).toByteArray(), - AionAddress.wrap(aKey1.getAddress()), - AionAddress.wrap( + Address.wrap(aKey1.getAddress()), + Address.wrap( "0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), @@ -1027,7 +1028,7 @@ public void TxnfeeCombineTest2() { System.out.println("2nd time spent: " + (System.currentTimeMillis() - start) + " ms."); for (ECKey aKey : key) { - List nl = tp.getNonceList(AionAddress.wrap(aKey.getAddress())); + List nl = tp.getNonceList(Address.wrap(aKey.getAddress())); for (int i = 0; i < cnt + cnt2; i++) { assertTrue(nl.get(i).equals(BigInteger.valueOf(i))); } @@ -1044,20 +1045,20 @@ public void TxnfeeCombineTest2() { Properties config = new Properties(); config.put("tx-timeout", "100"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 100; System.out.println("Gen new transactions --"); long start = System.currentTimeMillis(); for (ECKey aKey21 : key2) { - Address acc = AionAddress.wrap(aKey21.getAddress()); + Address acc = Address.wrap(aKey21.getAddress()); for (int i = 0; i < cnt; i++) { - ITransaction txn = + Transaction txn = new AionTransaction( BigInteger.valueOf(i).toByteArray(), acc, - AionAddress.wrap( + Address.wrap( "0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), @@ -1084,7 +1085,7 @@ public void TxnfeeCombineTest2() { System.out.println("time spent: " + (System.currentTimeMillis() - start) + " ms."); for (ECKey aKey2 : key2) { - List nl = tp.getNonceList(AionAddress.wrap(aKey2.getAddress())); + List nl = tp.getNonceList(Address.wrap(aKey2.getAddress())); for (int i = 0; i < cnt; i++) { assertTrue(nl.get(i).equals(BigInteger.valueOf(i))); } @@ -1097,21 +1098,21 @@ public void TxnfeeCombineTest2() { Properties config = new Properties(); config.put("tx-timeout", "100"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); - List txnlrm = new ArrayList<>(); + List txnl = new ArrayList<>(); + List txnlrm = new ArrayList<>(); int cnt = 100000; int rmCnt = 10; - Address acc = AionAddress.wrap(key.get(0).getAddress()); + Address acc = Address.wrap(key.get(0).getAddress()); System.out.println("gen new transactions..."); long start = System.currentTimeMillis(); for (int i = 0; i < cnt; i++) { - ITransaction txn = + Transaction txn = new AionTransaction( BigInteger.valueOf(i).toByteArray(), acc, - AionAddress.wrap( + Address.wrap( "0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), @@ -1151,7 +1152,7 @@ public void TxnfeeCombineTest2() { tp.snapshot(); System.out.println("time spent: " + (System.currentTimeMillis() - start) + " ms."); - List nl = tp.getNonceList(AionAddress.wrap(key.get(0).getAddress())); + List nl = tp.getNonceList(Address.wrap(key.get(0).getAddress())); for (int i = 0; i < nl.size(); i++) { assertTrue(nl.get(i).equals(BigInteger.valueOf(i).add(BigInteger.valueOf(rmCnt)))); } @@ -1165,18 +1166,18 @@ public void TxnfeeCombineTest2() { Properties config = new Properties(); config.put("tx-timeout", "100"); - TxPoolA0 tp = new TxPoolA0<>(config); + TxPoolA0 tp = new TxPoolA0<>(config); - List txnl = new ArrayList<>(); + List txnl = new ArrayList<>(); int cnt = 10000; for (ECKey aKey1 : key) { - Address acc = AionAddress.wrap(aKey1.getAddress()); + Address acc = Address.wrap(aKey1.getAddress()); for (int i = 0; i < cnt; i++) { - ITransaction txn = + Transaction txn = new AionTransaction( BigInteger.valueOf(i).toByteArray(), acc, - AionAddress.wrap( + Address.wrap( "0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), @@ -1203,7 +1204,7 @@ public void TxnfeeCombineTest2() { System.out.println("2nd time spent: " + (System.currentTimeMillis() - start) + " ms."); for (ECKey aKey : key) { - List nl = tp.getNonceList(AionAddress.wrap(aKey.getAddress())); + List nl = tp.getNonceList(Address.wrap(aKey.getAddress())); for (int i = 0; i < cnt; i++) { assertTrue(nl.get(i).equals(BigInteger.valueOf(i))); } @@ -1220,8 +1221,8 @@ public void testSnapshotAll() { AionTransaction tx = new AionTransaction( BigInteger.valueOf(i).toByteArray(), - AionAddress.wrap(key.getAddress()), - AionAddress.wrap( + Address.wrap(key.getAddress()), + Address.wrap( "0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), @@ -1254,8 +1255,8 @@ public void testSnapshotAll2() { AionTransaction tx = new AionTransaction( BigInteger.valueOf(i).toByteArray(), - AionAddress.wrap(key.getAddress()), - AionAddress.wrap( + Address.wrap(key.getAddress()), + Address.wrap( "0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), @@ -1284,8 +1285,8 @@ public void testRemove2() { AionTransaction tx = new AionTransaction( BigInteger.valueOf(i).toByteArray(), - AionAddress.wrap(key.getAddress()), - AionAddress.wrap( + Address.wrap(key.getAddress()), + Address.wrap( "0000000000000000000000000000000000000000000000000000000000000001"), ByteUtils.fromHexString("1"), ByteUtils.fromHexString("1"), diff --git a/modUtil/build.gradle b/modUtil/build.gradle index ddf19dc71f..e2785e9fcb 100644 --- a/modUtil/build.gradle +++ b/modUtil/build.gradle @@ -1,6 +1,117 @@ ext.moduleName = 'aion.util' +// set the publish to true when the code ready to push the lib to the maven repo +def publish = false; + +apply plugin: 'maven' +apply plugin: 'signing' + +group = "network.aion" +archivesBaseName = "util4j" + +def getCommitHash = { -> + def hashStdOut = new ByteArrayOutputStream() + exec { + commandLine "sh", "-c", "git log --pretty=format:%h | head -1" + standardOutput = hashStdOut + } + + return hashStdOut.toString().trim() +} + dependencies { testCompile 'junit:junit:4.12' testCompile 'pl.pragmatists:JUnitParams:1.1.1' + testCompile 'com.google.truth:truth:0.42' + testCompile 'com.madgag.spongycastle:core:1.58.0.0' +} + +sourceSets { + + if (publish) { + version = "0.4.0" + } else { + jar.baseName = 'util4j-' + getCommitHash() + } + + main { + java.srcDirs = ['src/main/java'] + } + test { + java.srcDirs = ['src/test/java'] + } +} + +signing { + sign configurations.archives +} +signArchives.enabled = publish + + +task sourcesJar(type: Jar) { + classifier = 'sources' + from sourceSets.main.allSource +} +sourcesJar.enabled = publish + +javadoc { + source = sourceSets.main.allJava + classpath = configurations.compile + options.tags = ["implSpec"] +} + +task javadocJar(type: Jar) { + classifier = 'javadoc' + from javadoc +} +javadocJar.enabled = publish + +artifacts { + archives sourcesJar, javadocJar +} + +uploadArchives { + repositories { + mavenDeployer { + + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } + + repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { + authentication(userName: ossrhUsername, password: ossrhPassword) + } + + pom.project { + name 'util4j' + packaging 'jar' + // optionally artifactId can be defined here + description 'a util module for the aion java kernel.' + url 'https://github.com/aionnetwork/aion/tree/master-pre-merge/modUtil' + + scm { + connection 'scm:git:https://github.com/aionnetwork/aion.git' + developerConnection 'git:https://github.com/aionnetwork/aion.git' + url 'https://github.com/aionnetwork/aion/tree/master' + } + + licenses { + license { + name 'MIT' + url 'https://opensource.org/licenses/MIT' + } + } + + developers { + developer { + id 'aion foundation dev' + name 'aion foundation dev' + email 'toengineering@aion.network' + } + } + } + } + } } +uploadArchives.enabled = publish + + + diff --git a/modUtil/src/main/java/module-info.java b/modUtil/src/main/java/module-info.java new file mode 100644 index 0000000000..6944582e10 --- /dev/null +++ b/modUtil/src/main/java/module-info.java @@ -0,0 +1,10 @@ +module aion.util { + exports org.aion.util.bytes; + exports org.aion.util.conversions; + exports org.aion.util.others; + exports org.aion.util.time; + exports org.aion.util.string; + exports org.aion.util.file; + exports org.aion.util.biginteger; + exports org.aion.util.map; +} diff --git a/modAionBase/src/org/aion/base/util/BIUtil.java b/modUtil/src/main/java/org/aion/util/biginteger/BIUtil.java similarity index 98% rename from modAionBase/src/org/aion/base/util/BIUtil.java rename to modUtil/src/main/java/org/aion/util/biginteger/BIUtil.java index 7ad7e5796e..d07c7b7240 100644 --- a/modAionBase/src/org/aion/base/util/BIUtil.java +++ b/modUtil/src/main/java/org/aion/util/biginteger/BIUtil.java @@ -1,4 +1,4 @@ -package org.aion.base.util; +package org.aion.util.biginteger; import java.math.BigInteger; diff --git a/modUtil/src/org/aion/util/bytes/ByteUtil.java b/modUtil/src/main/java/org/aion/util/bytes/ByteUtil.java similarity index 99% rename from modUtil/src/org/aion/util/bytes/ByteUtil.java rename to modUtil/src/main/java/org/aion/util/bytes/ByteUtil.java index 598863b3c6..15a32d8193 100644 --- a/modUtil/src/org/aion/util/bytes/ByteUtil.java +++ b/modUtil/src/main/java/org/aion/util/bytes/ByteUtil.java @@ -648,7 +648,7 @@ public static byte[] shortToBytes(short n) { /** * Converts string hex representation to data bytes Accepts following hex: - with or without 0x - * prefix - with no leading 0, like 0xabc -> 0x0abc + * prefix - with no leading 0, like 0xabc v.s. 0x0abc * * @param data String like '0xa5e..' or just 'a5e..' * @return decoded bytes array diff --git a/modUtil/src/org/aion/util/conversions/Hex.java b/modUtil/src/main/java/org/aion/util/conversions/Hex.java similarity index 93% rename from modUtil/src/org/aion/util/conversions/Hex.java rename to modUtil/src/main/java/org/aion/util/conversions/Hex.java index 858763f18d..88312ca5ad 100644 --- a/modUtil/src/org/aion/util/conversions/Hex.java +++ b/modUtil/src/main/java/org/aion/util/conversions/Hex.java @@ -3,6 +3,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.Arrays; /** Utility class for converting hex data to bytes and back again. */ public class Hex { @@ -45,7 +46,7 @@ public static byte[] encode(byte[] data, int off, int length) { * * @return the number of bytes produced. */ - public static int encode(byte[] data, OutputStream out) throws IOException { + public static int encode(byte[] data, OutputStream out) { return encoder.encode(data, 0, data.length, out); } @@ -54,8 +55,7 @@ public static int encode(byte[] data, OutputStream out) throws IOException { * * @return the number of bytes produced. */ - public static int encode(byte[] data, int off, int length, OutputStream out) - throws IOException { + public static int encode(byte[] data, int off, int length, OutputStream out) { return encoder.encode(data, off, length, out); } @@ -69,7 +69,7 @@ public static byte[] decode(byte[] data) { try { encoder.decode(data, 0, data.length, bOut); } catch (IOException e) { - System.err.println("Hex decode failed! " + data); + System.err.println("Hex decode failed! " + Arrays.toString(data)); return null; } diff --git a/modUtil/src/org/aion/util/conversions/HexEncoder.java b/modUtil/src/main/java/org/aion/util/conversions/HexEncoder.java similarity index 84% rename from modUtil/src/org/aion/util/conversions/HexEncoder.java rename to modUtil/src/main/java/org/aion/util/conversions/HexEncoder.java index 9abfd7d715..171e6fbf5e 100644 --- a/modUtil/src/org/aion/util/conversions/HexEncoder.java +++ b/modUtil/src/main/java/org/aion/util/conversions/HexEncoder.java @@ -6,7 +6,7 @@ /** A streaming Hex encoder. */ public class HexEncoder { - protected final byte[] encodingTable = { + private final static byte[] encodingTable = { (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', @@ -16,9 +16,9 @@ public class HexEncoder { /* * set up the decoding table. */ - protected final byte[] decodingTable = new byte[128]; + private final static byte[] decodingTable = new byte[128]; - protected void initialiseDecodingTable() { + private void initialiseDecodingTable() { for (int i = 0; i < decodingTable.length; i++) { decodingTable[i] = (byte) 0xff; } @@ -44,13 +44,13 @@ public HexEncoder() { * * @return the number of bytes produced. */ - public int encode(byte[] data, int off, int length, OutputStream out) { + public static int encode(byte[] data, int off, int length, OutputStream out) { for (int i = off; i < (off + length); i++) { int v = data[i] & 0xff; try { out.write(encodingTable[(v >>> 4)]); out.write(encodingTable[v & 0xf]); - } catch (Exception e) { + } catch (Exception ignored) { } } @@ -67,7 +67,7 @@ private static boolean ignore(char c) { * * @return the number of bytes produced. */ - public int decode(byte[] data, int off, int length, OutputStream out) throws IOException { + public static int decode(byte[] data, int off, int length, OutputStream out) throws IOException { byte b1, b2; int outLen = 0; @@ -78,7 +78,7 @@ public int decode(byte[] data, int off, int length, OutputStream out) throws IOE break; } - end--; + --end; } int i = off; @@ -101,11 +101,11 @@ public int decode(byte[] data, int off, int length, OutputStream out) throws IOE try { out.write((b1 << 4) | b2); - } catch (Exception e) { + } catch (Exception ignored) { } - outLen++; + ++outLen; } return outLen; @@ -117,7 +117,7 @@ public int decode(byte[] data, int off, int length, OutputStream out) throws IOE * * @return the number of bytes produced. */ - public int decode(String data, OutputStream out) throws IOException { + public static int decode(String data, OutputStream out) throws IOException { byte b1, b2; int length = 0; @@ -128,19 +128,19 @@ public int decode(String data, OutputStream out) throws IOException { break; } - end--; + --end; } int i = 0; while (i < end) { while (i < end && ignore(data.charAt(i))) { - i++; + ++i; } b1 = decodingTable[data.charAt(i++)]; while (i < end && ignore(data.charAt(i))) { - i++; + ++i; } b2 = decodingTable[data.charAt(i++)]; @@ -151,7 +151,7 @@ public int decode(String data, OutputStream out) throws IOException { out.write((b1 << 4) | b2); - length++; + ++length; } return length; diff --git a/modAionBase/src/org/aion/base/io/File.java b/modUtil/src/main/java/org/aion/util/file/File.java similarity index 96% rename from modAionBase/src/org/aion/base/io/File.java rename to modUtil/src/main/java/org/aion/util/file/File.java index 37e4b949cf..046795d2ca 100644 --- a/modAionBase/src/org/aion/base/io/File.java +++ b/modUtil/src/main/java/org/aion/util/file/File.java @@ -1,4 +1,4 @@ -package org.aion.base.io; +package org.aion.util.file; import java.nio.file.Path; import java.util.Arrays; diff --git a/modUtil/src/main/java/org/aion/util/file/NativeLoader.java b/modUtil/src/main/java/org/aion/util/file/NativeLoader.java new file mode 100644 index 0000000000..45c080676f --- /dev/null +++ b/modUtil/src/main/java/org/aion/util/file/NativeLoader.java @@ -0,0 +1,138 @@ +package org.aion.util.file; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Scanner; + +/** + * Native library loader. + * + * @author jin + */ +public class NativeLoader { + + /** + * Returns the current OS name. + * + * @return current system OS name. + */ + private static String getOS() { + String osName = System.getProperty("os.name").toLowerCase(); + if (osName.contains("win")) { + return "win"; + } else if (osName.contains("linux")) { + return "linux"; + } else if (osName.contains("mac")) { + return "mac"; + } else { + throw new RuntimeException("Unrecognized OS: " + osName); + } + } + + /** + * Builds a file path given a list of folder names. + * + * @param args list of folder names + * @return file object + */ + private static File buildPath(String... args) { + StringBuilder sb = new StringBuilder(); + for (String arg : args) { + sb.append(File.separator); + sb.append(arg); + } + + return sb.length() > 0 ? new File(sb.substring(1)) : new File("."); + } + + /** + * Loads library based on the file list in the given module folder. + * + * @param module module name + */ + public static void loadLibrary(String module) { + File dir = buildPath("native", getOS(), module); + + try (Scanner s = new Scanner(new File(dir, "file.list"))) { + while (s.hasNextLine()) { + String line = s.nextLine(); + + if (line.startsWith("/") || line.startsWith(".")) { // for debug + // purpose + // mainly + System.load(line); + } else { + System.load(new File(dir, line).getCanonicalPath()); + } + } + } catch (IOException e) { + throw new RuntimeException("Failed to load libraries for " + module, e); + } + } + + public static void loadLibraryFromJar(@SuppressWarnings("rawtypes") Class clz, String path) + throws IOException { + + if (!path.startsWith("/")) { + throw new IllegalArgumentException("The path has to be absolute (start with '/')."); + } + + // Obtain filename from path + String[] parts = path.split("/"); + String filename = (parts.length > 1) ? parts[parts.length - 1] : null; + + // Split filename to prexif and suffix (extension) + String prefix = ""; + String suffix = null; + if (filename != null) { + parts = filename.split("\\.", 2); + prefix = parts[0]; + suffix = (parts.length > 1) ? "." + parts[parts.length - 1] : null; + } + + // Check if the filename is okay + if (filename == null || prefix.length() < 3) { + throw new IllegalArgumentException( + "The filename has to be at least 3 characters long."); + } + + // Prepare temporary file + File temp = File.createTempFile(prefix, suffix); + temp.deleteOnExit(); + + if (!temp.exists()) { + throw new FileNotFoundException("File " + temp.getAbsolutePath() + " does not exist."); + } + + // Prepare buffer for data copying + byte[] buffer = new byte[1024]; + int readBytes; + + // Open and check input stream + InputStream is = clz.getResourceAsStream(path); + if (is == null) { + throw new FileNotFoundException("File " + path + " was not found inside JAR."); + } + + // Open output stream and copy data between source file in JAR and the + // temporary file + OutputStream os = new FileOutputStream(temp); + try { + while ((readBytes = is.read(buffer)) != -1) { + os.write(buffer, 0, readBytes); + } + } finally { + // If read/write fails, close streams safely before throwing an + // exception + os.close(); + is.close(); + } + + // Finally, load the library + System.load(temp.getAbsolutePath()); + } +} diff --git a/modAionBase/src/org/aion/base/util/AbstractMap.java b/modUtil/src/main/java/org/aion/util/map/AbstractMap.java similarity index 99% rename from modAionBase/src/org/aion/base/util/AbstractMap.java rename to modUtil/src/main/java/org/aion/util/map/AbstractMap.java index 6874fd1c2c..50d99117ff 100644 --- a/modAionBase/src/org/aion/base/util/AbstractMap.java +++ b/modUtil/src/main/java/org/aion/util/map/AbstractMap.java @@ -1,4 +1,4 @@ -package org.aion.base.util; +package org.aion.util.map; import java.util.AbstractCollection; import java.util.AbstractSet; diff --git a/modAionBase/src/org/aion/base/util/HashMap.java b/modUtil/src/main/java/org/aion/util/map/HashMap.java similarity index 99% rename from modAionBase/src/org/aion/base/util/HashMap.java rename to modUtil/src/main/java/org/aion/util/map/HashMap.java index a3f6547012..bc0923038b 100644 --- a/modAionBase/src/org/aion/base/util/HashMap.java +++ b/modUtil/src/main/java/org/aion/util/map/HashMap.java @@ -1,4 +1,4 @@ -package org.aion.base.util; +package org.aion.util.map; import java.io.IOException; import java.io.InvalidObjectException; @@ -51,7 +51,7 @@ public abstract class HashMap extends AbstractMap * ordered primarily by hashCode, but in the case of ties, if two * elements are of the same "class C implements Comparable", * type then their compareTo method is used for ordering. (We - * conservatively check generic types via reflection to validate + * conservatively check generic type via reflection to validate * this -- see method comparableClassFor). The added complexity * of tree bins is worthwhile in providing worst-case O(log n) * operations when keys either have distinct hashes or are diff --git a/modAionBase/src/org/aion/base/util/MAF.java b/modUtil/src/main/java/org/aion/util/others/MAF.java similarity index 88% rename from modAionBase/src/org/aion/base/util/MAF.java rename to modUtil/src/main/java/org/aion/util/others/MAF.java index efdc5787f7..a7abf22605 100644 --- a/modAionBase/src/org/aion/base/util/MAF.java +++ b/modUtil/src/main/java/org/aion/util/others/MAF.java @@ -1,8 +1,8 @@ -package org.aion.base.util; +package org.aion.util.others; import java.util.ArrayDeque; import java.util.Queue; -/** @author: ali sharif Implements a simple Moving Average Filter This class is thread safe */ +/** @author ali sharif Implements a simple Moving Average Filter This class is thread safe */ public class MAF { // rationale for using ArrayDeque - doc: 'This class is likely to be faster than Stack when used // as a stack, @@ -38,7 +38,8 @@ public void add(double value) { count++; } if (count > window) { - total -= myQ.poll(); + Double d = myQ.poll(); + total -= d == null ? 0 : d; count--; } movingAvg = total / count; diff --git a/modUtil/src/main/java/org/aion/util/others/Utils.java b/modUtil/src/main/java/org/aion/util/others/Utils.java new file mode 100644 index 0000000000..2b869823b6 --- /dev/null +++ b/modUtil/src/main/java/org/aion/util/others/Utils.java @@ -0,0 +1,70 @@ +package org.aion.util.others; + +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Utils { + + public static final Object dummy = new Object(); + + private static final Pattern matchPattern = Pattern.compile("^([0-9]+)([a-zA-Z]+)$"); + public static final long KILO_BYTE = 1024; + public static final long MEGA_BYTE = 1048576; + public static final long GIGA_BYTE = 1073741824; + /** + * Matches file sizes based on fileSize string, in the format: [numericalValue][sizeDescriptor] + * + *

    Examples of acceptable formats: + * 10b,10B,10K,10KB,10kB,10M,10mB,10MB,10G,10gB,10GB + * + *

    Commas are not accepted by the parser, and are considered invalid. + * + *

    Note: Anything beyond {@code gigaByte (GB, G, gB)} is not considered valid, and will be + * treated as a parse exception. + * + *

    Note: this function assumes the binary representation of magnitudes, therefore 1kB + * (kiloByte) is not {@code 1000 bytes} but rather {@code 1024 bytes}. + * + * @param fileSize file size string + * @return {@code Optional.of(fileSizeInt)} if we were able to successfully decode the filesize + * string, otherwise outputs {@code Optional.empty()} indicating that we were unable to + * decode the file size string, this usually refers to some sort of syntactic error made by + * the user. + */ + public static Optional parseSize(String fileSize) { + Matcher m = matchPattern.matcher(fileSize); + // if anything does not match + if (!m.find()) { + return Optional.empty(); + } + + String numerical = m.group(1); + String sizeSuffix = m.group(2); + + long size = Integer.parseInt(numerical); + switch (sizeSuffix) { + case "B": + break; + case "K": + case "kB": + case "KB": + // process kiloByte (1024 * byte) here + size = size * KILO_BYTE; + break; + case "M": + case "mB": + case "MB": + size = size * MEGA_BYTE; + break; + case "G": + case "gB": + case "GB": + size = size * GIGA_BYTE; + break; + default: + return Optional.empty(); + } + return Optional.of(size); + } +} diff --git a/modUtil/src/main/java/org/aion/util/string/StringUtils.java b/modUtil/src/main/java/org/aion/util/string/StringUtils.java new file mode 100644 index 0000000000..61381db1a2 --- /dev/null +++ b/modUtil/src/main/java/org/aion/util/string/StringUtils.java @@ -0,0 +1,95 @@ +package org.aion.util.string; + +import java.math.BigInteger; +import java.util.Arrays; +import org.aion.util.conversions.Hex; + +public class StringUtils { + + /** Validate a passed hex string is a valid address */ + public static boolean isValidAddress(String address) { + if (address == null || address.isEmpty() || address.length() < 64) { + return false; + } + + if (address.startsWith("0x")) { + address = address.substring(2); + } + + // Will need to change this for a1, a2.... + if (address.startsWith("a0")) { + return address.length() == 64 && address.substring(2).matches("^[0-9A-Fa-f]+$"); + } else { + return false; + } + } + + public static String getNodeIdShort(String nodeId) { + return nodeId == null ? "" : nodeId.substring(0, 8); + } + + public static String align(String s, char fillChar, int targetLen, boolean alignRight) { + if (targetLen <= s.length()) { + return s; + } + String alignString = repeat("" + fillChar, targetLen - s.length()); + return alignRight ? alignString + s : s + alignString; + } + + public static String repeat(String s, int n) { + if (s.length() == 1) { + byte[] bb = new byte[n]; + Arrays.fill(bb, s.getBytes()[0]); + return new String(bb); + } else { + StringBuilder ret = new StringBuilder(); + for (int i = 0; i < n; i++) { + ret.append(s); + } + return ret.toString(); + } + } + + public static BigInteger StringNumberAsBigInt(String input) { + if (input.startsWith("0x")) { + return StringHexToBigInteger(input); + } else { + return StringDecimalToBigInteger(input); + } + } + + public static BigInteger StringHexToBigInteger(String input) { + String hexa = input.startsWith("0x") ? input.substring(2) : input; + return new BigInteger(hexa, 16); + } + + private static BigInteger StringDecimalToBigInteger(String input) { + return new BigInteger(input); + } + + public static byte[] StringHexToByteArray(String x) { + if (x.startsWith("0x")) { + x = x.substring(2); + } + if (x.length() % 2 != 0) { + x = "0" + x; + } + return Hex.decode(x); + } + + public static String toJsonHex(byte[] x) { + return "0x" + Hex.toHexString(x); + } + + public static String toJsonHex(String x) { + return x.startsWith("0x") ? x : "0x" + x; + } + + public static String toJsonHex(long n) { + return "0x" + Long.toHexString(n); + } + + public static String toJsonHex(BigInteger n) { + return "0x" + n.toString(16); + } +} diff --git a/modAionBase/src/org/aion/base/util/TimeInstant.java b/modUtil/src/main/java/org/aion/util/time/TimeInstant.java similarity index 96% rename from modAionBase/src/org/aion/base/util/TimeInstant.java rename to modUtil/src/main/java/org/aion/util/time/TimeInstant.java index f1b63fdd5a..1c9b2c5771 100644 --- a/modAionBase/src/org/aion/base/util/TimeInstant.java +++ b/modUtil/src/main/java/org/aion/util/time/TimeInstant.java @@ -1,8 +1,8 @@ -package org.aion.base.util; +package org.aion.util.time; import java.time.Instant; -public final class TimeInstant { +public final class TimeInstant { private static Instant instant; public static final TimeInstant EPOCH = new TimeInstant(); diff --git a/modAionBase/src/org/aion/base/util/TimeUtils.java b/modUtil/src/main/java/org/aion/util/time/TimeUtils.java similarity index 68% rename from modAionBase/src/org/aion/base/util/TimeUtils.java rename to modUtil/src/main/java/org/aion/util/time/TimeUtils.java index cbfa2bc6b2..53fe3eb6f3 100644 --- a/modAionBase/src/org/aion/base/util/TimeUtils.java +++ b/modUtil/src/main/java/org/aion/util/time/TimeUtils.java @@ -1,8 +1,12 @@ -package org.aion.base.util; +package org.aion.util.time; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; public class TimeUtils { - /** + /* * Converts minutes to millis * * @param minutes time in minutes @@ -23,6 +27,18 @@ public static long secondsToMillis(long seconds) { } /** + * Return formatted Date String: yyyy.MM.dd HH:mm:ss Based on Unix's time() input in seconds + * + * @param timestamp seconds since start of Unix-time + * @return String formatted as - yyyy.MM.dd HH:mm:ss + */ + public static String longToDateTime(long timestamp) { + Date date = new Date(timestamp * 1000); + DateFormat formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss"); + return formatter.format(date); + } + + /* * Converts millis to minutes * * @param millis time in millis @@ -32,7 +48,7 @@ public static long secondsToMillis(long seconds) { // return Math.round(millis / 60.0 / 1000.0); // } - /** + /* * Converts millis to seconds * * @param millis time in millis @@ -42,7 +58,7 @@ public static long secondsToMillis(long seconds) { // return Math.round(millis / 1000.0); // } - /** + /* * Returns timestamp in the future after some millis passed from now * * @param millis millis count diff --git a/modUtil/src/module-info.java b/modUtil/src/module-info.java deleted file mode 100644 index 83b2a379e0..0000000000 --- a/modUtil/src/module-info.java +++ /dev/null @@ -1,5 +0,0 @@ -module aion.util { - exports org.aion.util; - exports org.aion.util.bytes; - exports org.aion.util.conversions; -} diff --git a/modUtil/src/org/aion/util/NativeLoader.java b/modUtil/src/org/aion/util/NativeLoader.java deleted file mode 100644 index 58e61d5505..0000000000 --- a/modUtil/src/org/aion/util/NativeLoader.java +++ /dev/null @@ -1,142 +0,0 @@ -package org.aion.util; - -import java.io.File; -import java.io.IOException; -import java.util.Scanner; - -// import java.io.FileNotFoundException; -// import java.io.FileOutputStream; -// import java.io.InputStream; -// import java.io.OutputStream; - -/** - * Native library loader. - * - * @author jin - */ -public class NativeLoader { - - /** - * Returns the current OS name. - * - * @return - */ - public static String getOS() { - String osName = System.getProperty("os.name").toLowerCase(); - if (osName.contains("win")) { - return "win"; - } else if (osName.contains("linux")) { - return "linux"; - } else if (osName.contains("mac")) { - return "mac"; - } else { - throw new RuntimeException("Unrecognized OS: " + osName); - } - } - - /** - * Builds a file path given a list of folder names. - * - * @param args - * @return - */ - public static File buildPath(String... args) { - StringBuilder sb = new StringBuilder(); - for (String arg : args) { - sb.append(File.separator); - sb.append(arg); - } - - return sb.length() > 0 ? new File(sb.substring(1)) : new File("."); - } - - /** - * Loads library based on the file list in the given module folder. - * - * @param module - */ - public static void loadLibrary(String module) { - File dir = buildPath("native", getOS(), module); - - try (Scanner s = new Scanner(new File(dir, "file.list"))) { - while (s.hasNextLine()) { - String line = s.nextLine(); - - if (line.startsWith("/") || line.startsWith(".")) { // for debug - // purpose - // mainly - System.load(line); - } else { - System.load(new File(dir, line).getCanonicalPath()); - } - } - } catch (IOException e) { - throw new RuntimeException("Failed to load libraries for " + module, e); - } - } - - // public static void loadLibraryFromJar(@SuppressWarnings("rawtypes") Class clz, String - // path) - // throws IOException { - // - // if (!path.startsWith("/")) { - // throw new IllegalArgumentException("The path has to be absolute (start with - // '/')."); - // } - // - // // Obtain filename from path - // String[] parts = path.split("/"); - // String filename = (parts.length > 1) ? parts[parts.length - 1] : null; - // - // // Split filename to prexif and suffix (extension) - // String prefix = ""; - // String suffix = null; - // if (filename != null) { - // parts = filename.split("\\.", 2); - // prefix = parts[0]; - // suffix = (parts.length > 1) ? "." + parts[parts.length - 1] : null; - // } - // - // // Check if the filename is okay - // if (filename == null || prefix.length() < 3) { - // throw new IllegalArgumentException( - // "The filename has to be at least 3 characters long."); - // } - // - // // Prepare temporary file - // File temp = File.createTempFile(prefix, suffix); - // temp.deleteOnExit(); - // - // if (!temp.exists()) { - // throw new FileNotFoundException("File " + temp.getAbsolutePath() + " does not - // exist."); - // } - // - // // Prepare buffer for data copying - // byte[] buffer = new byte[1024]; - // int readBytes; - // - // // Open and check input stream - // InputStream is = clz.getResourceAsStream(path); - // if (is == null) { - // throw new FileNotFoundException("File " + path + " was not found inside JAR."); - // } - // - // // Open output stream and copy data between source file in JAR and the - // // temporary file - // OutputStream os = new FileOutputStream(temp); - // try { - // while ((readBytes = is.read(buffer)) != -1) { - // os.write(buffer, 0, readBytes); - // } - // } finally { - // // If read/write fails, close streams safely before throwing an - // // exception - // os.close(); - // is.close(); - // } - // - // // Finally, load the library - // System.load(temp.getAbsolutePath()); - // } -} diff --git a/modAionBase/test/org/aion/base/util/AddressValidationTest.java b/modUtil/src/test/java/org/aion/util/bytes/AddressValidationTest.java similarity index 67% rename from modAionBase/test/org/aion/base/util/AddressValidationTest.java rename to modUtil/src/test/java/org/aion/util/bytes/AddressValidationTest.java index 601d6ff532..59a6498751 100644 --- a/modAionBase/test/org/aion/base/util/AddressValidationTest.java +++ b/modUtil/src/test/java/org/aion/util/bytes/AddressValidationTest.java @@ -1,7 +1,7 @@ -package org.aion.base.util; - -import static org.junit.Assert.assertEquals; +package org.aion.util.bytes; +import org.aion.util.string.StringUtils; +import org.junit.Assert; import org.junit.Test; public class AddressValidationTest { @@ -10,45 +10,45 @@ public class AddressValidationTest { public void allZeroPrefix() { String addr = "0x0000000000000000000000000000000000000000000000000000000000000000"; - assertEquals(false, Utils.isValidAddress(addr)); + Assert.assertFalse(StringUtils.isValidAddress(addr)); } @Test public void allZeroNoPrefix() { String addr = "0000000000000000000000000000000000000000000000000000000000000000"; - assertEquals(false, Utils.isValidAddress(addr)); + Assert.assertFalse(StringUtils.isValidAddress(addr)); } @Test public void burnPrefix() { String addr = "0xa000000000000000000000000000000000000000000000000000000000000000"; - assertEquals(true, Utils.isValidAddress(addr)); + Assert.assertTrue(StringUtils.isValidAddress(addr)); } @Test public void burnNoPrefix() { String addr = "a000000000000000000000000000000000000000000000000000000000000000"; - assertEquals(true, Utils.isValidAddress(addr)); + Assert.assertTrue(StringUtils.isValidAddress(addr)); } @Test public void previouslyGeneratedPrefix() { String addr = "0xa0ad207b4ae29a4e6219a8a8a1a82310de491194a33bd95907515a3c2196f357"; - assertEquals(true, Utils.isValidAddress(addr)); + Assert.assertTrue(StringUtils.isValidAddress(addr)); } @Test public void previouslyGeneratedNoPrefix() { String addr = "a0ad207b4ae29a4e6219a8a8a1a82310de491194a33bd95907515a3c2196f357"; - assertEquals(true, Utils.isValidAddress(addr)); + Assert.assertTrue(StringUtils.isValidAddress(addr)); } @Test public void incorrectLength() { String addr = "a0ad207b4ae29a4e6219a8a8a1a82310de491194a33bd95907515a3c2196f3"; - assertEquals(false, Utils.isValidAddress(addr)); + Assert.assertFalse(StringUtils.isValidAddress(addr)); } } diff --git a/modUtil/src/test/java/org/aion/util/bytes/BIUtilTest.java b/modUtil/src/test/java/org/aion/util/bytes/BIUtilTest.java new file mode 100644 index 0000000000..3683efc340 --- /dev/null +++ b/modUtil/src/test/java/org/aion/util/bytes/BIUtilTest.java @@ -0,0 +1,155 @@ +package org.aion.util.bytes; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.math.BigInteger; +import org.aion.util.biginteger.BIUtil; +import org.junit.Assert; +import org.junit.Test; + +public class BIUtilTest { + + private final BigInteger[][] bigInt = { + {new BigInteger("-00000000000000000000"), new BigInteger("00000000000000000000")}, + {new BigInteger("-00000000000000000001"), new BigInteger("00000000000000000001")}, + {new BigInteger("-10000000000000000000"), new BigInteger("10000000000000000000")}, + {new BigInteger("-20000000000000000000"), new BigInteger("20000000000000000000")}, + {new BigInteger("-30000000000000000000"), new BigInteger("30000000000000000000")}, + {new BigInteger("-99999999999999999999"), new BigInteger("99999999999999999999")}, + }; + + @Test + public void testIntegrity() { + + // isZero && isPositive + assertTrue(BIUtil.isZero(bigInt[0][0])); + assertTrue(BIUtil.isZero(bigInt[0][1])); + + assertFalse(BIUtil.isPositive(bigInt[0][0])); + assertFalse(BIUtil.isPositive(bigInt[0][1])); + + // isEqual && isNotEqual + assertTrue(BIUtil.isEqual(bigInt[0][0], bigInt[0][1])); + assertFalse(BIUtil.isNotEqual(bigInt[0][0], bigInt[0][1])); + + // isLessThan && isMoreThan + assertFalse(BIUtil.isLessThan(bigInt[0][0], bigInt[0][1])); + assertFalse(BIUtil.isMoreThan(bigInt[0][0], bigInt[0][1])); + + for (int a = 1; a < bigInt.length; a++) { + + assertFalse(BIUtil.isPositive(bigInt[a][0])); + assertTrue(BIUtil.isPositive(bigInt[a][1])); + + assertFalse(BIUtil.isEqual(bigInt[a][0], bigInt[a][1])); + assertTrue(BIUtil.isNotEqual(bigInt[a][0], bigInt[a][1])); + + assertTrue(BIUtil.isLessThan(bigInt[a][0], bigInt[a][1])); + assertFalse(BIUtil.isMoreThan(bigInt[a][0], bigInt[a][1])); + } + + // isCovers && isNotCovers + for (int a = 1; a < bigInt.length; a++) { + assertTrue(BIUtil.isNotCovers(bigInt[a - 1][1], bigInt[a][1])); + } + for (int a = 1; a < bigInt.length; a++) { + assertTrue(BIUtil.isNotCovers(bigInt[a][0], bigInt[a - 1][0])); + } + for (int a = bigInt.length - 1; a > 0; a--) { + assertTrue(BIUtil.isCovers(bigInt[a][1], bigInt[a - 1][1])); + } + + for (int a = bigInt.length - 1; a > 0; a--) { + assertTrue(BIUtil.isCovers(bigInt[a - 1][0], bigInt[a][0])); + } + + // isIn20PercentRange + } + + @Test + public void testType() { + + // toBI(byte), toBI(long) + final long[] testLong = { + 0L, 1L, 1000000000000000000L, 9223372036854775807L, + }; + + final byte[][] testByte = { + ByteUtil.longToBytes(testLong[0]), + ByteUtil.longToBytes(testLong[1]), + ByteUtil.longToBytes(testLong[2]), + ByteUtil.longToBytes(testLong[3]), + }; + + for (int i = 0; i < 4; i++) { + Assert.assertEquals(BIUtil.toBI(testLong[i]), BIUtil.toBI(testByte[i])); + } + + // exitLong + } + + @Test + public void testSum() { + + // sum + for (BigInteger[] bigIntegers : bigInt) { + Assert.assertEquals(new BigInteger("0"), BIUtil.sum(bigIntegers[0], bigIntegers[1])); + } + + for (int b = 0; b < 2; b++) { + for (BigInteger[] bigIntegers : bigInt) { + Assert.assertEquals(bigIntegers[b], BIUtil.sum(bigInt[0][b], bigIntegers[b])); + } + } + + Assert.assertEquals( + new BigInteger("-160000000000000000000"), + BIUtil.sum( + bigInt[0][0], + BIUtil.sum( + bigInt[1][0], + BIUtil.sum( + bigInt[2][0], + BIUtil.sum(bigInt[3][0], BIUtil.sum(bigInt[4][0], bigInt[5][0])))))); + + Assert.assertEquals( + new BigInteger("160000000000000000000"), + BIUtil.sum( + bigInt[0][1], + BIUtil.sum( + bigInt[1][1], + BIUtil.sum( + bigInt[2][1], + BIUtil.sum(bigInt[3][1], BIUtil.sum(bigInt[4][1], bigInt[5][1])))))); + } + + @Test + public void testMinMax() { + // min && max + for (BigInteger[] bigIntegers : bigInt) { + Assert.assertEquals(bigIntegers[0], BIUtil.min(bigIntegers[0], bigIntegers[1])); + Assert.assertEquals(bigIntegers[1], BIUtil.max(bigIntegers[0], bigIntegers[1])); + } + + Assert.assertEquals( + bigInt[bigInt.length - 1][0], + BIUtil.min( + bigInt[0][0], + BIUtil.min( + bigInt[1][0], + BIUtil.min( + bigInt[2][0], + BIUtil.min(bigInt[3][0], BIUtil.min(bigInt[4][0], bigInt[5][0])))))); + + Assert.assertEquals( + bigInt[bigInt.length - 1][1], + BIUtil.max( + bigInt[0][1], + BIUtil.max( + bigInt[1][1], + BIUtil.max( + bigInt[2][1], + BIUtil.max(bigInt[3][1], BIUtil.max(bigInt[4][1], bigInt[5][1])))))); + } +} diff --git a/modRlp/test/org/aion/rlp/ByteUtilTest.java b/modUtil/src/test/java/org/aion/util/bytes/ByteUtilExtendTest.java similarity index 99% rename from modRlp/test/org/aion/rlp/ByteUtilTest.java rename to modUtil/src/test/java/org/aion/util/bytes/ByteUtilExtendTest.java index db58724b08..8ce1a29bf8 100644 --- a/modRlp/test/org/aion/rlp/ByteUtilTest.java +++ b/modUtil/src/test/java/org/aion/util/bytes/ByteUtilExtendTest.java @@ -1,4 +1,4 @@ -package org.aion.rlp; +package org.aion.util.bytes; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -9,14 +9,13 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.aion.util.bytes.ByteUtil; import org.aion.util.conversions.Hex; import org.junit.Assert; import org.junit.Test; import org.spongycastle.util.BigIntegers; /** TODO: functionality should be moved to modUtil */ -public class ByteUtilTest { +public class ByteUtilExtendTest { @Test public void testAppendByte() { diff --git a/modUtil/test/org/aion/util/bytes/ByteUtilTest.java b/modUtil/src/test/java/org/aion/util/bytes/ByteUtilTest.java similarity index 98% rename from modUtil/test/org/aion/util/bytes/ByteUtilTest.java rename to modUtil/src/test/java/org/aion/util/bytes/ByteUtilTest.java index 8e1b8ab7b1..95ed19b587 100644 --- a/modUtil/test/org/aion/util/bytes/ByteUtilTest.java +++ b/modUtil/src/test/java/org/aion/util/bytes/ByteUtilTest.java @@ -138,11 +138,9 @@ private Object intValues() { @SuppressWarnings("unused") private Object shortValues() { - Short[] temp = { + return new Short[] { 0, 1, 10, 15, 20, (short) random.nextInt(Integer.MAX_VALUE), (short) Integer.MAX_VALUE }; - - return temp; } /** @@ -176,9 +174,9 @@ public void bigIntegerTest() { // encodeDataList(Object) @Test public void objectTest() { - for (int a = 0; a < testNum.length; a++) { + for (String[] strings : testNum) { try { - byte[] temp1 = encodeValFor32Bits(testNum[a][1]); + encodeValFor32Bits(strings[1]); } catch (NullPointerException e) { System.out.println("\nNull Object Test!"); } @@ -277,12 +275,14 @@ public void byteTest() { // Empty Array byte[] temp1 = stripLeadingZeroes(testByte[1]); + assert temp1 != null; assertEquals(-1, firstNonZeroByte(temp1)); assertEquals(-1, firstNonZeroByte(testByte[1])); assertTrue(isNullOrZeroArray(testByte[1])); // Leading Non-zero byte[] temp2 = stripLeadingZeroes(testByte[2]); + assert temp2 != null; assertEquals(0, firstNonZeroByte(temp2)); assertEquals(0, firstNonZeroByte(testByte[2])); assertEquals(0, firstNonZeroByte(testByte[3])); @@ -295,6 +295,7 @@ public void byteTest() { // Leading Zeroes byte[] temp3 = stripLeadingZeroes(testByte[6]); + assert temp3 != null; assertEquals(0, firstNonZeroByte(temp3)); assertEquals(31, firstNonZeroByte(testByte[6])); @@ -312,13 +313,14 @@ public void byteTest() { for (int a = 1; a < testBigInt.length; a++) { byte[] temp4 = bigIntegerToBytes(testBigInt[a][1]); String temp5 = toHexString(temp4); + assert temp4 != null; assertEquals(temp5.length() / 2, temp4.length); assertEquals(temp5.length() / 2, numBytes(testNum[a][1])); } // Append - for (int a = 0; a < testHex.length; a++) { - byte[] temp6 = hexStringToBytes(testHex[a]); + for (String testHex1 : testHex) { + byte[] temp6 = hexStringToBytes(testHex1); byte temp7 = toByte(testByte[2]); byte[] temp8 = appendByte(temp6, temp7); String temp9 = oneByteToHexString(temp7); diff --git a/modAionBase/test/org/aion/base/util/MAFTest.java b/modUtil/src/test/java/org/aion/util/bytes/MAFTest.java similarity index 52% rename from modAionBase/test/org/aion/base/util/MAFTest.java rename to modUtil/src/test/java/org/aion/util/bytes/MAFTest.java index 75c84632e1..e37272e29e 100644 --- a/modAionBase/test/org/aion/base/util/MAFTest.java +++ b/modUtil/src/test/java/org/aion/util/bytes/MAFTest.java @@ -1,7 +1,8 @@ -package org.aion.base.util; +package org.aion.util.bytes; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.atomic.AtomicBoolean; +import org.aion.util.others.MAF; import org.junit.Test; public class MAFTest { @@ -37,47 +38,41 @@ public void testMAFMultiThread() { MAF ma = new MAF(5); Thread producerA = - new Thread() { - public void run() { - try { - for (int i = 0; i < itrCount; i++) { - ma.add(ThreadLocalRandom.current().nextDouble(min, max)); - } - System.out.println("producerA done --------------"); - } catch (Exception e) { - e.printStackTrace(); - } + new Thread(() -> { + try { + for (int i = 0; i < itrCount; i++) { + ma.add(ThreadLocalRandom.current().nextDouble(min, max)); } - }; + System.out.println("producerA done --------------"); + } catch (Exception e) { + e.printStackTrace(); + } + }); Thread producerB = - new Thread() { - public void run() { - try { - for (int i = 0; i < itrCount; i++) { - ma.add(ThreadLocalRandom.current().nextDouble(min, max)); - } - System.out.println("producerB done --------------"); - } catch (Exception e) { - e.printStackTrace(); - } + new Thread(() -> { + try { + for (int i = 0; i < itrCount; i++) { + ma.add(ThreadLocalRandom.current().nextDouble(min, max)); } - }; + System.out.println("producerB done --------------"); + } catch (Exception e) { + e.printStackTrace(); + } + }); AtomicBoolean shutdown = new AtomicBoolean(false); Thread consumer = - new Thread() { - public void run() { - try { - while (!shutdown.get()) { - System.out.println(ma.getAverage()); - // Thread.sleep(1); - } - System.out.println("consumer done --------------"); - } catch (Exception e) { - e.printStackTrace(); - } + new Thread(() -> { + try { + while (!shutdown.get()) { + System.out.println(ma.getAverage()); + // Thread.sleep(1); } - }; + System.out.println("consumer done --------------"); + } catch (Exception e) { + e.printStackTrace(); + } + }); try { producerA.start(); diff --git a/modAionBase/test/org/aion/base/util/SizeParseTest.java b/modUtil/src/test/java/org/aion/util/bytes/SizeParseTest.java similarity index 78% rename from modAionBase/test/org/aion/base/util/SizeParseTest.java rename to modUtil/src/test/java/org/aion/util/bytes/SizeParseTest.java index 680ddebb6d..2fe8d55b00 100644 --- a/modAionBase/test/org/aion/base/util/SizeParseTest.java +++ b/modUtil/src/test/java/org/aion/util/bytes/SizeParseTest.java @@ -1,10 +1,10 @@ -package org.aion.base.util; - -import static com.google.common.truth.Truth.assertThat; +package org.aion.util.bytes; +import com.google.common.truth.Truth; import java.util.Arrays; import java.util.Collection; import java.util.Optional; +import org.aion.util.others.Utils; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -35,11 +35,11 @@ public static Collection data() { } private static class Bundle { - public final String input; - public final boolean expectedResult; - public final long expectedSize; + final String input; + final boolean expectedResult; + final long expectedSize; - public Bundle(String input, boolean expectedResult, long expectedSize) { + Bundle(String input, boolean expectedResult, long expectedSize) { this.input = input; this.expectedResult = expectedResult; this.expectedSize = expectedSize; @@ -55,8 +55,8 @@ public SizeParseTest(Bundle bundle) { @Test public void test() { Optional maybeSize = Utils.parseSize(bundle.input); - assertThat(maybeSize.isPresent()).isEqualTo(bundle.expectedResult); + Truth.assertThat(maybeSize.isPresent()).isEqualTo(bundle.expectedResult); - maybeSize.ifPresent((p) -> assertThat(p).isEqualTo(bundle.expectedSize)); + maybeSize.ifPresent((p) -> Truth.assertThat(p).isEqualTo(bundle.expectedSize)); } } diff --git a/modVM/build.gradle b/modVM/build.gradle index 1afbcab536..1caeee876b 100644 --- a/modVM/build.gradle +++ b/modVM/build.gradle @@ -1,20 +1,29 @@ ext.moduleName = 'aion.vm' dependencies { - compile project(':modAionBase') + compile project(':aion_vm_api') + compile 'network.aion:util4j:0.4.0' + compile 'network.aion:crypto4j:0.4.0' + compile project(':modAion') compile project(':modMcf') - compile project(':modCrypto') - compile project(':aion_vm_api') compile project(':aion_fastvm') compile files('../lib/org-aion-avm-core.jar') - compile files('../lib/org-aion-avm-rt.jar') compile 'com.google.code.findbugs:jsr305:3.0.2' compile 'org.slf4j:slf4j-api:1.7.25' compile group: 'org.apache.commons', name: 'commons-collections4', version: '4.0' compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.4' compile group: 'commons-codec', name: 'commons-codec', version: '1.10' + runtimeOnly group: 'org.ow2.asm', name: 'asm', version: '6.2.1' + runtimeOnly group: 'org.ow2.asm', name: 'asm-analysis', version: '6.2.1' + runtimeOnly group: 'org.ow2.asm', name: 'asm-commons', version: '6.2.1' + runtimeOnly group: 'org.ow2.asm', name: 'asm-tree', version: '6.2.1' + runtimeOnly group: 'org.ow2.asm', name: 'asm-util', version: '6.2.1' + runtimeOnly files('../lib/org-aion-avm-api.jar') + runtimeOnly files('../lib/org-aion-avm-rt.jar') + runtimeOnly files('../lib/org-aion-avm-userlib.jar') + testCompile 'junit:junit:4.12' testCompile 'org.hamcrest:hamcrest-all:1.3' } diff --git a/modVM/src/module-info.java b/modVM/src/module-info.java index a867da95c9..7a9ac2feea 100644 --- a/modVM/src/module-info.java +++ b/modVM/src/module-info.java @@ -1,5 +1,4 @@ module aion.vm { - requires aion.base; requires aion.mcf; requires transitive slf4j.api; requires aion.zero; @@ -10,6 +9,8 @@ requires org.aion.avm.core; requires aion.precompiled; requires com.google.common; + requires aion.crypto; exports org.aion.vm; + exports org.aion.vm.exception; } diff --git a/modVM/src/org/aion/vm/AionCapabilities.java b/modVM/src/org/aion/vm/AionCapabilities.java new file mode 100644 index 0000000000..6c4dfc05de --- /dev/null +++ b/modVM/src/org/aion/vm/AionCapabilities.java @@ -0,0 +1,34 @@ +package org.aion.vm; + +import org.aion.avm.core.IExternalCapabilities; +import org.aion.crypto.HashUtil; +import org.aion.types.Address; +import org.aion.vm.api.interfaces.TransactionInterface; + +public class AionCapabilities implements IExternalCapabilities { + + @Override + public byte[] sha256(byte[] bytes) { + return HashUtil.sha256(bytes); + } + + @Override + public byte[] blake2b(byte[] bytes) { + return org.aion.crypto.hash.Blake2bNative.blake256(bytes); + } + + @Override + public byte[] keccak256(byte[] bytes) { + return HashUtil.keccak256(bytes); + } + + @Override + public boolean verifyEdDSA(byte[] bytes, byte[] bytes1, byte[] bytes2) { + return org.aion.crypto.ed25519.ECKeyEd25519.verify(bytes, bytes1, bytes2); + } + + @Override + public Address generateContractAddress(TransactionInterface tx) { + return Address.wrap(HashUtil.calcNewAddr(tx.getSenderAddress().toBytes(), tx.getNonce())); + } +} diff --git a/modVM/src/org/aion/vm/BulkExecutor.java b/modVM/src/org/aion/vm/BulkExecutor.java index 87b93416d7..b00ef61ece 100644 --- a/modVM/src/org/aion/vm/BulkExecutor.java +++ b/modVM/src/org/aion/vm/BulkExecutor.java @@ -1,22 +1,23 @@ package org.aion.vm; +import static org.aion.mcf.valid.TransactionTypeRule.isValidAVMContractDeployment; + import java.util.ArrayList; import java.util.List; -import org.aion.avm.core.NodeEnvironment; -import org.aion.base.db.IRepository; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.type.ITxExecSummary; -import org.aion.base.vm.VirtualMachineSpecs; -import org.aion.fastvm.FastVirtualMachine; import org.aion.fastvm.FastVmResultCode; import org.aion.fastvm.SideEffects; +import org.aion.interfaces.db.Repository; +import org.aion.interfaces.db.RepositoryCache; +import org.aion.interfaces.tx.TxExecSummary; import org.aion.kernel.AvmTransactionResult; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; import org.aion.mcf.vm.types.KernelInterfaceForFastVM; import org.aion.mcf.vm.types.Log; +import org.aion.precompiled.ContractFactory; +import org.aion.types.Address; +import org.aion.util.bytes.ByteUtil; import org.aion.vm.VmFactoryImplementation.VM; -import org.aion.vm.api.interfaces.Address; import org.aion.vm.api.interfaces.IExecutionLog; import org.aion.vm.api.interfaces.KernelInterface; import org.aion.vm.api.interfaces.ResultCode; @@ -24,6 +25,7 @@ import org.aion.vm.api.interfaces.TransactionContext; import org.aion.vm.api.interfaces.TransactionResult; import org.aion.vm.api.interfaces.VirtualMachine; +import org.aion.vm.exception.VMException; import org.aion.zero.types.AionTransaction; import org.aion.zero.types.AionTxExecSummary; import org.aion.zero.types.AionTxReceipt; @@ -61,8 +63,8 @@ public static void enabledAvmCheck(boolean isEnabled) { avmEnabled = isEnabled; } - private IRepository repository; - private IRepositoryCache> repositoryChild; + private Repository repository; + private RepositoryCache> repositoryChild; private PostExecutionWork postExecutionWork; private ExecutionBatch executionBatch; private Logger logger; @@ -90,8 +92,8 @@ public static void enabledAvmCheck(boolean isEnabled) { */ public BulkExecutor( ExecutionBatch executionBatch, - IRepository repository, - IRepositoryCache> repositoryChild, + Repository repository, + RepositoryCache> repositoryChild, boolean isLocalCall, boolean allowNonceIncrement, long blockRemainingEnergy, @@ -125,7 +127,7 @@ public BulkExecutor( */ public BulkExecutor( ExecutionBatch executionBatch, - IRepositoryCache> repositoryChild, + RepositoryCache> repositoryChild, boolean isLocalCall, boolean allowNonceIncrement, long blockRemainingEnergy, @@ -143,7 +145,7 @@ public BulkExecutor( work); } - public List execute() { + public List execute() throws VMException { synchronized (LOCK) { List summaries = new ArrayList<>(); @@ -155,31 +157,33 @@ public List execute() { AionTransaction firstTransactionInNextBatch = this.executionBatch.getTransactions().get(currentIndex); - if (transactionIsForFastVirtualMachine(firstTransactionInNextBatch)) { - KernelInterfaceForFastVM fvmKernel = - new KernelInterfaceForFastVM( + KernelInterface vmKernel; + if (transactionIsForAionVirtualMachine(firstTransactionInNextBatch)) { + vmKernel = + new KernelInterfaceForAVM( this.repositoryChild.startTracking(), this.allowNonceIncrement, this.isLocalCall); virtualMachineForNextBatch = - VirtualMachineProvider.getVirtualMachineInstance(VM.FVM, fvmKernel); + VirtualMachineProvider.getVirtualMachineInstance(VM.AVM, vmKernel); nextBatchToExecute = - fetchNextBatchOfTransactionsForFastVirtualMachine(currentIndex); + fetchNextBatchOfTransactionsForAionVirtualMachine(currentIndex); } else { - KernelInterfaceForAVM avmKernel = - new KernelInterfaceForAVM( + vmKernel = + new KernelInterfaceForFastVM( this.repositoryChild.startTracking(), this.allowNonceIncrement, this.isLocalCall); virtualMachineForNextBatch = - VirtualMachineProvider.getVirtualMachineInstance(VM.AVM, avmKernel); + VirtualMachineProvider.getVirtualMachineInstance(VM.FVM, vmKernel); nextBatchToExecute = - fetchNextBatchOfTransactionsForAionVirtualMachine(currentIndex); + fetchNextBatchOfTransactionsForFastVirtualMachine(currentIndex); } // Execute the next batch of transactions using the specified virtual machine. summaries.addAll( - executeTransactions(virtualMachineForNextBatch, nextBatchToExecute)); + executeTransactions( + virtualMachineForNextBatch, nextBatchToExecute, vmKernel)); currentIndex += nextBatchToExecute.size(); } @@ -188,12 +192,13 @@ public List execute() { } private List executeTransactions( - VirtualMachine virtualMachine, ExecutionBatch details) { + VirtualMachine virtualMachine, ExecutionBatch details, KernelInterface kernel) + throws VMException { List summaries = new ArrayList<>(); // Run the transactions. SimpleFuture[] resultsAsFutures = - virtualMachine.run(details.getExecutionContexts()); + virtualMachine.run(kernel, details.getExecutionContexts()); // Process the results of the transactions. List transactions = details.getTransactions(); @@ -202,6 +207,11 @@ private List executeTransactions( int length = resultsAsFutures.length; for (int i = 0; i < length; i++) { TransactionResult result = resultsAsFutures[i].get(); + + if (result.getResultCode().isFatal()) { + throw new VMException(result.toString()); + } + KernelInterface kernelFromVM = result.getKernelInterface(); AionTransaction transaction = transactions.get(i); @@ -211,7 +221,7 @@ private List executeTransactions( long energyUsed = computeEnergyUsed(transaction.getEnergyLimit(), result); if (energyUsed > this.blockRemainingEnergy) { result.setResultCode(FastVmResultCode.INVALID_NRG_LIMIT); - result.setReturnData(new byte[0]); + result.setReturnData(ByteUtil.EMPTY_BYTE_ARRAY); if (transactionIsForAionVirtualMachine(transaction)) { ((AvmTransactionResult) result).setEnergyUsed(transaction.getEnergyLimit()); @@ -246,9 +256,10 @@ private AionTxExecSummary buildSummaryAndUpdateRepository( KernelInterface kernelFromVM, TransactionResult result) { - // TODO: Avm should assure us this is not null: need to add this to VM API specifications. + // TODO: should Avm assure us that this is always non-null like the fvm does? But in Avm + // TODO: a null return value is actually meaningful. Need to figure this out. if (result.getReturnData() == null) { - result.setReturnData(new byte[0]); + result.setReturnData(ByteUtil.EMPTY_BYTE_ARRAY); } SideEffects sideEffects = new SideEffects(); @@ -261,8 +272,7 @@ private AionTxExecSummary buildSummaryAndUpdateRepository( // We have to do this for now, because the kernel uses the log serialization, which is not // implemented in the Avm, and this type may become a POD type anyway.. List logs; - if (transactionIsForAionVirtualMachine(transaction) - || transaction.getTargetVM() == VirtualMachineSpecs.AVM_CREATE_CODE) { + if (transactionIsForAionVirtualMachine(transaction)) { logs = transferAvmLogsToKernel(sideEffects.getExecutionLogs()); } else { logs = sideEffects.getExecutionLogs(); @@ -305,7 +315,7 @@ private AionTxExecSummary buildSummaryAndUpdateRepository( return summary; } - private List transferAvmLogsToKernel(List avmLogs) { + private static List transferAvmLogsToKernel(List avmLogs) { List logs = new ArrayList<>(); for (IExecutionLog avmLog : avmLogs) { logs.add(new Log(avmLog.getSourceAddress(), avmLog.getTopics(), avmLog.getData())); @@ -313,7 +323,7 @@ private List transferAvmLogsToKernel(List avmLogs) return logs; } - private AionTxReceipt makeReceipt( + private static AionTxReceipt makeReceipt( AionTransaction transaction, List logs, TransactionResult result) { AionTxReceipt receipt = new AionTxReceipt(); receipt.setTransaction(transaction); @@ -326,35 +336,35 @@ private AionTxReceipt makeReceipt( } private void updateRepository( - ITxExecSummary summary, + TxExecSummary summary, AionTransaction tx, Address coinbase, List

    deleteAccounts, TransactionResult result) { if (!isLocalCall && !summary.isRejected()) { - IRepositoryCache> track = + RepositoryCache> track = this.repositoryChild.startTracking(); + tx.setNrgConsume(computeEnergyUsed(tx.getEnergyLimit(), result)); + // Refund energy if transaction was successfully or reverted. - if (result.getResultCode().isSuccess() || result.getResultCode().isRevert()) { - if (!transactionIsForAionVirtualMachine(tx)) { + if (!transactionIsForAionVirtualMachine(tx)) { + if (result.getResultCode().isSuccess() || result.getResultCode().isRevert()) { track.addBalance(tx.getSenderAddress(), summary.getRefund()); } - } - - tx.setNrgConsume(computeEnergyUsed(tx.getEnergyLimit(), result)); - // Pay the miner. - track.addBalance(coinbase, summary.getFee()); + // Pay the miner. + track.addBalance(coinbase, summary.getFee()); - // Delete any accounts marked for deletion. - if (result.getResultCode().isSuccess()) { - for (Address addr : deleteAccounts) { - track.deleteAccount(addr); + // Delete any accounts marked for deletion. + if (result.getResultCode().isSuccess()) { + for (Address addr : deleteAccounts) { + track.deleteAccount(addr); + } } + track.flush(); } - track.flush(); } if (this.logger.isDebugEnabled()) { @@ -363,73 +373,80 @@ private void updateRepository( } } - private long computeEnergyUsed(long limit, TransactionResult result) { + private static long computeEnergyUsed(long limit, TransactionResult result) { return limit - result.getEnergyRemaining(); } + /** + * Returns a batch of transactions to execute that are destined to be executed by the FVM, + * starting with the transaction at index {@code startIndex} (inclusive) up to and including all + * subsequent FVM-bound transactions. + */ private ExecutionBatch fetchNextBatchOfTransactionsForFastVirtualMachine(int startIndex) { - // Find the index of the next transaction that is not fvm-bound. List transactions = this.executionBatch.getTransactions(); + for (int i = startIndex; i < this.executionBatch.size(); i++) { - if (!transactionIsForFastVirtualMachine(transactions.get(i))) { + // Find the index of the next transaction that is not fvm-bound, that is where we stop. + if (transactionIsForAionVirtualMachine(transactions.get(i))) { return this.executionBatch.slice(startIndex, i); } } + return this.executionBatch.slice(startIndex, this.executionBatch.size()); } + /** + * Returns a batch of transactions to execute that are destined to be executed by the AVM, + * starting with the transaction at index {@code startIndex} (inclusive) up to and including all + * subsequent AVM-bound transactions. + */ private ExecutionBatch fetchNextBatchOfTransactionsForAionVirtualMachine(int startIndex) { - // Find the index of the next transaction that is not avm-bound. List transactions = this.executionBatch.getTransactions(); + for (int i = startIndex; i < this.executionBatch.size(); i++) { + // Find the index of the next transaction that is not avm-bound, that is where we stop. if (!transactionIsForAionVirtualMachine(transactions.get(i))) { return this.executionBatch.slice(startIndex, i); } } + return this.executionBatch.slice(startIndex, this.executionBatch.size()); } /** - * A transaction is for the {@link FastVirtualMachine} iff: + * A transaction can only be for the avm if the avm is enabled. If it is not enabled this method + * always returns false. * - *

    - It is a CREATE transaction and its target VM is the FVM - It is a CALL transaction and - * the destination is not an AVM contract address + * Otherwise, assuming the avm is enabled, a transaction is for the Avm if, and only if, one of + * the following is true: * - *

    NOTE: If a transaction is a precompiled contract call it will return true and head into - * the Fvm. This is currently what we want, but it will be changed and separated out in the - * future. + *

    1. It is a CREATE transaction and its target VM is the AVM 2. It is a CALL transaction and + * the destination is an AVM contract address 3. It is a CALL transaction and the destination is + * not a contract address. */ - private boolean transactionIsForFastVirtualMachine(AionTransaction transaction) { + private boolean transactionIsForAionVirtualMachine(AionTransaction transaction) { // first verify that the AVM is enabled if (avmEnabled) { if (transaction.isContractCreationTransaction()) { - return transaction.getTargetVM() != VirtualMachineSpecs.AVM_CREATE_CODE; + return isValidAVMContractDeployment(transaction.getTargetVM()); } else { - return transaction.getDestinationAddress().toBytes()[0] - != NodeEnvironment.CONTRACT_PREFIX; + Address destination = transaction.getDestinationAddress(); + return isValidAVMContractDeployment(repositoryChild.getVMUsed(destination)) + || !isContractAddress(destination); } } else { - return true; + return false; } } - /** - * A transaction is for the Avm iff: - * - *

    - It is a CREATE transaction and its target VM is the AVM - It is a CALL transaction and - * the destination is an AVM contract address - */ - private boolean transactionIsForAionVirtualMachine(AionTransaction transaction) { - // first verify that the AVM is enabled - if (avmEnabled) { - if (transaction.isContractCreationTransaction()) { - return transaction.getTargetVM() == VirtualMachineSpecs.AVM_CREATE_CODE; - } else { - return transaction.getDestinationAddress().toBytes()[0] - == NodeEnvironment.CONTRACT_PREFIX; - } + /** Returns true only if address is a contract. */ + private boolean isContractAddress(Address address) { + if (ContractFactory.isPrecompiledContract(address)) { + return true; } else { - return false; + RepositoryCache cache = this.repositoryChild.startTracking(); + byte[] code = cache.getCode(address); + return (code != null) && (code.length > 0); } } } diff --git a/modVM/src/org/aion/vm/ExecutionBatch.java b/modVM/src/org/aion/vm/ExecutionBatch.java index a7510fdf12..19f7a26375 100644 --- a/modVM/src/org/aion/vm/ExecutionBatch.java +++ b/modVM/src/org/aion/vm/ExecutionBatch.java @@ -4,9 +4,8 @@ import java.util.Arrays; import java.util.List; import org.aion.fastvm.ExecutionContext; -import org.aion.mcf.vm.types.DataWord; -import org.aion.util.bytes.ByteUtil; -import org.aion.vm.api.interfaces.Address; +import org.aion.mcf.vm.types.DataWordImpl; +import org.aion.types.Address; import org.aion.zero.types.AionTransaction; import org.aion.zero.types.IAionBlock; import org.apache.commons.lang3.ArrayUtils; @@ -64,7 +63,7 @@ private ExecutionBatch( * @param stop The index of the last transaction in the slice, exclusive. * @return The sliced version of this BlockDetails object. */ - public ExecutionBatch slice(int start, int stop) { + ExecutionBatch slice(int start, int stop) { List transactions = this.transactions.subList(start, stop); List contexts = this.contexts.subList(start, stop); return new ExecutionBatch(this.block, transactions, contexts); @@ -93,7 +92,7 @@ public List getTransactions() { * * @return The contexts. */ - public KernelTransactionContext[] getExecutionContexts() { + KernelTransactionContext[] getExecutionContexts() { KernelTransactionContext[] contextsAsArray = new KernelTransactionContext[this.contexts.size()]; this.contexts.toArray(contextsAsArray); @@ -104,7 +103,7 @@ public int size() { return this.transactions.size(); } - private List constructTransactionContexts( + private static List constructTransactionContexts( List transactions, IAionBlock block) { List contexts = new ArrayList<>(); for (AionTransaction transaction : transactions) { @@ -113,7 +112,7 @@ private List constructTransactionContexts( return contexts; } - private KernelTransactionContext constructTransactionContext( + private static KernelTransactionContext constructTransactionContext( AionTransaction transaction, IAionBlock block) { byte[] txHash = transaction.getTransactionHash(); Address address = @@ -123,10 +122,9 @@ private KernelTransactionContext constructTransactionContext( Address origin = transaction.getSenderAddress(); Address caller = transaction.getSenderAddress(); - DataWord nrgPrice = transaction.nrgPrice(); - long energyLimit = transaction.nrgLimit(); + DataWordImpl nrgPrice = transaction.nrgPrice(); long nrg = transaction.nrgLimit() - transaction.transactionCost(block.getNumber()); - DataWord callValue = new DataWord(ArrayUtils.nullToEmpty(transaction.getValue())); + DataWordImpl callValue = new DataWordImpl(ArrayUtils.nullToEmpty(transaction.getValue())); byte[] callData = ArrayUtils.nullToEmpty(transaction.getData()); int depth = 0; @@ -146,7 +144,7 @@ private KernelTransactionContext constructTransactionContext( if (diff.length > 16) { diff = Arrays.copyOfRange(diff, diff.length - 16, diff.length); } - DataWord blockDifficulty = new DataWord(diff); + DataWordImpl blockDifficulty = new DataWordImpl(diff); return new KernelTransactionContext( transaction, diff --git a/modVM/src/org/aion/vm/KernelInterfaceForAVM.java b/modVM/src/org/aion/vm/KernelInterfaceForAVM.java index 2598ebbcfb..aab2f37570 100644 --- a/modVM/src/org/aion/vm/KernelInterfaceForAVM.java +++ b/modVM/src/org/aion/vm/KernelInterfaceForAVM.java @@ -1,24 +1,23 @@ package org.aion.vm; import java.math.BigInteger; -import org.aion.avm.core.NodeEnvironment; -import org.aion.base.db.IRepositoryCache; -import org.aion.base.util.ByteArrayWrapper; -import org.aion.base.vm.VirtualMachineSpecs; +import org.aion.interfaces.db.RepositoryCache; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; +import org.aion.mcf.valid.TransactionTypeRule; import org.aion.mcf.valid.TxNrgRule; import org.aion.mcf.vm.types.KernelInterfaceForFastVM; import org.aion.precompiled.ContractFactory; -import org.aion.vm.api.interfaces.Address; +import org.aion.types.Address; +import org.aion.types.ByteArrayWrapper; import org.aion.vm.api.interfaces.KernelInterface; public class KernelInterfaceForAVM implements KernelInterface { - private IRepositoryCache> repositoryCache; + private RepositoryCache> repositoryCache; private boolean allowNonceIncrement, isLocalCall; public KernelInterfaceForAVM( - IRepositoryCache> repositoryCache, + RepositoryCache> repositoryCache, boolean allowNonceIncrement, boolean isLocalCall) { @@ -31,8 +30,8 @@ public KernelInterfaceForAVM( } @Override - public KernelInterfaceForFastVM makeChildKernelInterface() { - return new KernelInterfaceForFastVM( + public KernelInterfaceForAVM makeChildKernelInterface() { + return new KernelInterfaceForAVM( this.repositoryCache.startTracking(), this.allowNonceIncrement, this.isLocalCall); } @@ -51,7 +50,7 @@ public void rollback() { this.repositoryCache.rollback(); } - public IRepositoryCache> getRepositoryCache() { + public RepositoryCache> getRepositoryCache() { return this.repositoryCache; } @@ -75,6 +74,17 @@ public byte[] getCode(Address address) { return this.repositoryCache.getCode(address); } + @Override + public void putObjectGraph(Address contract, byte[] graph) { + //Todo: implement it when avm is ready. + } + + @Override + public byte[] getObjectGraph(Address contract) { + //Todo: implement it when avm is ready. + return new byte[0]; + } + @Override public void putStorage(Address address, byte[] key, byte[] value) { ByteArrayWrapper storageKey = new ByteArrayWrapper(key); @@ -183,6 +193,6 @@ public boolean destinationAddressIsSafeForThisVM(Address address) { } // Otherwise, it must be an Avm contract address. - return address.toBytes()[0] == NodeEnvironment.CONTRACT_PREFIX; + return TransactionTypeRule.isValidAVMContractDeployment(repositoryCache.getVMUsed(address)); } } diff --git a/modVM/src/org/aion/vm/KernelTransactionContext.java b/modVM/src/org/aion/vm/KernelTransactionContext.java index 9ca4f273ec..f35f2cd09d 100644 --- a/modVM/src/org/aion/vm/KernelTransactionContext.java +++ b/modVM/src/org/aion/vm/KernelTransactionContext.java @@ -3,14 +3,13 @@ import java.math.BigInteger; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import org.aion.avm.core.NodeEnvironment; -import org.aion.base.type.AionAddress; -import org.aion.base.vm.IDataWord; +import org.aion.crypto.AddressSpecs; import org.aion.fastvm.SideEffects; -import org.aion.mcf.vm.types.DataWord; +import org.aion.interfaces.vm.DataWord; +import org.aion.mcf.vm.types.DataWordImpl; import org.aion.mcf.vm.types.DoubleDataWord; +import org.aion.types.Address; import org.aion.util.bytes.ByteUtil; -import org.aion.vm.api.interfaces.Address; import org.aion.vm.api.interfaces.TransactionContext; import org.aion.vm.api.interfaces.TransactionSideEffects; import org.aion.zero.types.AionTransaction; @@ -18,7 +17,7 @@ public class KernelTransactionContext implements TransactionContext { private static final int ENCODE_BASE_LEN = - (Address.SIZE * 4) + (DataWord.BYTES * 3) + (Long.BYTES * 4) + (Integer.BYTES * 4); + (Address.SIZE * 4) + (DataWordImpl.BYTES * 3) + (Long.BYTES * 4) + (Integer.BYTES * 4); public static int CALL = 0; public static int DELEGATECALL = 1; public static int CALLCODE = 2; @@ -33,9 +32,9 @@ public class KernelTransactionContext implements TransactionContext { public Address address; public Address sender; private Address blockCoinbase; - private IDataWord nrgPrice; - private IDataWord callValue; - private IDataWord blockDifficulty; + private DataWord nrgPrice; + private DataWord callValue; + private DataWord blockDifficulty; private byte[] callData; private byte[] txHash; private long nrg; // NOTE: nrg = tx_nrg_limit - tx_basic_cost @@ -74,9 +73,9 @@ public KernelTransactionContext( Address destination, Address origin, Address sender, - IDataWord nrgPrice, + DataWordImpl nrgPrice, long nrg, - IDataWord callValue, + DataWordImpl callValue, byte[] callData, int depth, int kind, @@ -85,7 +84,7 @@ public KernelTransactionContext( long blockNumber, long blockTimestamp, long blockNrgLimit, - IDataWord blockDifficulty) { + DataWord blockDifficulty) { this.transaction = transaction; this.address = destination; @@ -166,11 +165,8 @@ public Address getDestinationAddress() { return address; } - @Override public Address getContractAddress() { - byte[] rawBytes = this.transaction.getContractAddress().toBytes(); - rawBytes[0] = NodeEnvironment.CONTRACT_PREFIX; - return AionAddress.wrap(rawBytes); + return this.transaction.getContractAddress(); } /** @return the origination address, which is the sender of original transaction. */ @@ -188,8 +184,8 @@ public Address getSenderAddress() { /** @return the nrg price in current environment. */ @Override public long getTransactionEnergyPrice() { - if (this.nrgPrice instanceof DataWord) { - return ((DataWord) this.nrgPrice).longValue(); + if (this.nrgPrice instanceof DataWordImpl) { + return ((DataWordImpl) this.nrgPrice).longValue(); } else { return ((DoubleDataWord) this.nrgPrice).longValue(); } @@ -257,8 +253,8 @@ public long getBlockEnergyLimit() { /** @return the block difficulty. */ @Override public long getBlockDifficulty() { - if (blockDifficulty instanceof DataWord) { - return ((DataWord) blockDifficulty).longValue(); + if (blockDifficulty instanceof DataWordImpl) { + return ((DataWordImpl) blockDifficulty).longValue(); } else { return ((DoubleDataWord) blockDifficulty).longValue(); } diff --git a/modVM/src/org/aion/vm/PostExecutionWork.java b/modVM/src/org/aion/vm/PostExecutionWork.java index 0a1d4f1345..ce142178c1 100644 --- a/modVM/src/org/aion/vm/PostExecutionWork.java +++ b/modVM/src/org/aion/vm/PostExecutionWork.java @@ -1,7 +1,7 @@ package org.aion.vm; -import org.aion.base.db.IRepository; -import org.aion.base.db.IRepositoryCache; +import org.aion.interfaces.db.Repository; +import org.aion.interfaces.db.RepositoryCache; import org.aion.mcf.core.AccountState; import org.aion.mcf.db.IBlockStoreBase; import org.aion.zero.types.AionTransaction; @@ -39,8 +39,8 @@ public interface PostExecutionWork { * @return The amount of energy that this transaction uses in its block. */ long doPostExecutionWork( - IRepository repository, - IRepositoryCache> repositoryChild, + Repository repository, + RepositoryCache> repositoryChild, AionTxExecSummary summary, AionTransaction transaction, long blockEnergyRemaining); diff --git a/modVM/src/org/aion/vm/VmFactoryImplementation.java b/modVM/src/org/aion/vm/VmFactoryImplementation.java index 3ab34178cf..d787536a5f 100644 --- a/modVM/src/org/aion/vm/VmFactoryImplementation.java +++ b/modVM/src/org/aion/vm/VmFactoryImplementation.java @@ -1,5 +1,6 @@ package org.aion.vm; +import org.aion.avm.core.AvmConfiguration; import org.aion.avm.core.AvmImpl; import org.aion.avm.core.CommonAvmFactory; import org.aion.fastvm.FastVirtualMachine; @@ -66,7 +67,7 @@ public void initializeAllVirtualMachines() { } // initialize the Avm. This buildAvmInstance method already calls start() for us. - this.aionVirtualMachine = CommonAvmFactory.buildAvmInstance(null); + this.aionVirtualMachine = CommonAvmFactory.buildAvmInstanceForConfiguration(new AionCapabilities(), new AvmConfiguration()); this.state = MachineState.ALL_MACHINES_LIVE; } @@ -95,11 +96,8 @@ public VirtualMachine getVirtualMachineInstance(VM request, KernelInterface kern switch (request) { case FVM: - FastVirtualMachine fvm = new FastVirtualMachine(); - fvm.setKernelInterface(kernel); - return fvm; + return new FastVirtualMachine(); case AVM: - this.aionVirtualMachine.setKernelInterface(kernel); return this.aionVirtualMachine; default: throw new UnsupportedOperationException("Unsupported VM request."); diff --git a/modVM/src/org/aion/vm/exception/VMException.java b/modVM/src/org/aion/vm/exception/VMException.java new file mode 100644 index 0000000000..ccae5de472 --- /dev/null +++ b/modVM/src/org/aion/vm/exception/VMException.java @@ -0,0 +1,15 @@ +package org.aion.vm.exception; + +/** + * @implNote The VMException is an Exception throws from the BulkExecutor {@link + * org.aion.vm.BulkExecutor} when the vm has fatal situation occurs,e.g. OOM. The kernel will + * handle this exception by shutting down the kernel immediately. + * @author Jay Tseng + */ +public class VMException extends Exception { + + /** @param result the transaction executing result returned by the VM. */ + public VMException(String result) { + super(result); + } +} diff --git a/override-config.py b/override-config.py deleted file mode 100644 index 6a69f72b45..0000000000 --- a/override-config.py +++ /dev/null @@ -1,100 +0,0 @@ -import os -import xml.etree.ElementTree -import subprocess -from xml.dom import minidom - -config_file = 'mainnet/config/config.xml' -indentation = '\t' - -def override_attrib(element, attrib, name, value): - if name != None and value != None: - print('Overriding kernel property ' + name + ' attribute ' + attrib + ' with value ' + value) - element.attrib[attrib] = value - -def override_child_text(element, child, name, value): - if name != None and value != None: - print('Overriding kernel property ' + name + ' with value ' + value) - element.find(child).text = value - -def add_child_text(element, child, name, value): - if name != None and value != None: - print('Overriding kernel property ' + name + ' with value ' + value) - new_child = xml.etree.ElementTree.SubElement(element, child) - new_child.text = value - -def add_peers(element, override_peers, peer_list): - if peer_list != None: - peers = peer_list.split(",") - if override_peers != None and override_peers == 'true': - print('override_peer_list=true; overriding current peer list') - old_nodes = element.findall('node') - if len(old_nodes) > 0: - for old_node in list(old_nodes): - print('Removing peer ' + old_node.text) - element.remove(old_node) - if peer_list != "": - for peer in peers: - add_child_text(element, 'node', 'node', peer) - else: - print('override_peer_list not specified or false; new peers are going to be appended to the current list') - for peer in peers: - add_child_text(element, 'node', 'node', peer) - -# pretty printing does not work with ElementTree -# use this function after inserting new elements in the xml file -def indent(elem, level=0): - i = "\n" + level*indentation - if len(elem): - if not elem.text or not elem.text.strip(): - elem.text = i + indentation - if not elem.tail or not elem.tail.strip(): - elem.tail = i - for elem in elem: - indent(elem, level+1) - if not elem.tail or not elem.tail.strip(): - elem.tail = i - else: - if level and (not elem.tail or not elem.tail.strip()): - elem.tail = i - - -et = xml.etree.ElementTree.parse(config_file) -root = et.getroot() - -api = root.find('api') -new_rpc = api.find('rpc') -override_attrib(new_rpc, 'ip', 'rpc_listen_address', os.environ.get('rpc_listen_address')) -override_attrib(new_rpc, 'port', 'rpc_listen_port', os.environ.get('rpc_listen_port')) -override_child_text(new_rpc, 'cors-enabled', 'cors_enabled', os.environ.get('cors_enabled')) -override_child_text(new_rpc, 'apis-enabled', 'apis_enabled', os.environ.get('apis_enabled')) - -new_java = api.find('java') -override_attrib(new_java, 'ip', 'java_api_listen_address', os.environ.get('java_api_listen_address')) -override_attrib(new_java, 'port', 'java_api_listen_port', os.environ.get('java_api_listen_port')) - -net = root.find('net') -new_p2p = net.find('p2p') -override_child_text(new_p2p, 'ip', 'p2p_listen_address', os.environ.get('p2p_listen_address')) -override_child_text(new_p2p, 'port', 'p2p_listen_port', os.environ.get('p2p_listen_port')) -override_child_text(new_p2p, 'discover', 'discover', os.environ.get('discover')) - -new_nodes = net.find('nodes') -add_peers(new_nodes, os.environ.get('override_peer_list'), os.environ.get('peer_list')) - -new_consensus = root.find('consensus') -override_child_text(new_consensus, 'mining', 'mining', os.environ.get('mining')) -override_child_text(new_consensus, 'miner-address', 'miner_address', os.environ.get('miner_address')) -override_child_text(new_consensus, 'cpu-mine-threads', 'cpu-mine-threads', os.environ.get('cpu_mine_threads')) - -new_log = root.find('log') -override_child_text(new_log, 'log-file', 'log_file', os.environ.get('log_file')) -override_child_text(new_log, 'log-path', 'log_path', os.environ.get('log_path')) -override_child_text(new_log, 'GEN', 'log_level_gen', os.environ.get('log_level_gen')) -override_child_text(new_log, 'VM', 'log_level_vm', os.environ.get('log_level_vm')) -override_child_text(new_log, 'API', 'log_level_api', os.environ.get('log_level_api')) -override_child_text(new_log, 'SYNC', 'log_level_sync', os.environ.get('log_level_sync')) -override_child_text(new_log, 'CONS', 'log_level_cons', os.environ.get('log_level_cons')) -override_child_text(new_log, 'DB', 'log_level_db', os.environ.get('log_level_db')) - -indent(root) -et.write(config_file, encoding='utf-8', xml_declaration=True) diff --git a/settings.gradle b/settings.gradle index 14bc4395cb..f23023a8bf 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,5 @@ rootProject.name = 'aion' -include 'modAionBase', 'modAion', 'modAionImpl', +include 'modAion', 'modAionImpl', 'modUtil', 'modCrypto', 'modLogger',