Skip to content

Commit ad3047a

Browse files
committed
Merge branch 'master' into retry-url
2 parents 6494265 + 3004a66 commit ad3047a

File tree

32 files changed

+783
-265
lines changed

32 files changed

+783
-265
lines changed

Diff for: beacon/validator/src/main/java/tech/pegasys/teku/validator/coordinator/GraffitiBuilder.java

+58-33
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import java.util.Arrays;
2121
import java.util.Locale;
2222
import java.util.Optional;
23-
import java.util.concurrent.atomic.AtomicReference;
2423
import java.util.stream.Collectors;
2524
import org.apache.logging.log4j.LogManager;
2625
import org.apache.logging.log4j.Logger;
@@ -38,21 +37,22 @@
3837
* according to the clientGraffitiAppendFormat configuration.
3938
*/
4039
public class GraffitiBuilder implements ExecutionClientVersionChannel {
40+
4141
private static final Logger LOG = LogManager.getLogger();
4242

4343
private static final String SPACE = " ";
4444

45+
private volatile Optional<ClientVersion> executionClientVersion = Optional.empty();
46+
4547
private final ClientGraffitiAppendFormat clientGraffitiAppendFormat;
4648
private final ClientVersion consensusClientVersion;
47-
private final AtomicReference<ClientVersion> executionClientVersion;
4849
private final Optional<Bytes32> defaultUserGraffiti;
4950

5051
public GraffitiBuilder(
5152
final ClientGraffitiAppendFormat clientGraffitiAppendFormat,
5253
final Optional<Bytes32> defaultUserGraffiti) {
5354
this.clientGraffitiAppendFormat = clientGraffitiAppendFormat;
5455
this.consensusClientVersion = createTekuClientVersion();
55-
this.executionClientVersion = new AtomicReference<>(ClientVersion.UNKNOWN);
5656
this.defaultUserGraffiti = defaultUserGraffiti;
5757
}
5858

@@ -72,7 +72,16 @@ public ClientVersion getConsensusClientVersion() {
7272

7373
@Override
7474
public void onExecutionClientVersion(final ClientVersion executionClientVersion) {
75-
this.executionClientVersion.set(executionClientVersion);
75+
this.executionClientVersion = Optional.of(executionClientVersion);
76+
logDefaultGraffiti();
77+
}
78+
79+
@Override
80+
public void onExecutionClientVersionNotAvailable() {
81+
logDefaultGraffiti();
82+
}
83+
84+
private void logDefaultGraffiti() {
7685
final Optional<Bytes32> defaultGraffiti = Optional.of(buildGraffiti(defaultUserGraffiti));
7786
EVENT_LOG.logDefaultGraffiti(
7887
extractGraffiti(defaultGraffiti, calculateGraffitiLength(defaultGraffiti)));
@@ -85,13 +94,23 @@ public Bytes32 buildGraffiti(final Optional<Bytes32> userGraffiti) {
8594
return switch (clientGraffitiAppendFormat) {
8695
case AUTO -> {
8796
final int clientInfoLength = Bytes32.SIZE - 1 - userGraffitiLength;
97+
// Could drop SPACE's `-1` in a corner case
98+
if (clientInfoLength == 3) {
99+
yield joinNonEmpty(
100+
"", extractGraffiti(userGraffiti, userGraffitiLength), formatClientsInfo(4));
101+
}
88102
yield joinNonEmpty(
89103
SPACE,
90104
extractGraffiti(userGraffiti, userGraffitiLength),
91105
formatClientsInfo(clientInfoLength));
92106
}
93107
case CLIENT_CODES -> {
94108
final int clientInfoLength = Integer.min(Bytes32.SIZE - 1 - userGraffitiLength, 4);
109+
// Could drop SPACE's `-1` in a corner case
110+
if (clientInfoLength == 3) {
111+
yield joinNonEmpty(
112+
"", extractGraffiti(userGraffiti, userGraffitiLength), formatClientsInfo(4));
113+
}
95114
yield joinNonEmpty(
96115
SPACE,
97116
extractGraffiti(userGraffiti, userGraffitiLength),
@@ -128,56 +147,62 @@ protected Bytes32 joinNonEmpty(final String delimiter, final String... parts) {
128147

129148
@VisibleForTesting
130149
protected String formatClientsInfo(final int length) {
131-
final boolean isElInfoAvailable = !ClientVersion.UNKNOWN.equals(executionClientVersion.get());
132-
final String safeConsensusCode = extractClientCodeSafely(consensusClientVersion);
133-
final String safeExecutionCode =
134-
isElInfoAvailable ? extractClientCodeSafely(executionClientVersion.get()) : "";
150+
final String consensusCode = consensusClientVersion.code();
151+
final String executionCode = getExecutionCodeSafely();
135152
// LH1be52536BU0f91a674
136153
if (length >= 20) {
137154
return String.format(
138155
"%s%s%s%s",
139-
safeConsensusCode,
140-
consensusClientVersion.commit().toUnprefixedHexString(),
141-
safeExecutionCode,
142-
isElInfoAvailable ? executionClientVersion.get().commit().toUnprefixedHexString() : "");
156+
consensusCode,
157+
getCommit(consensusClientVersion),
158+
executionCode,
159+
executionClientVersion.map(this::getCommit).orElse(""));
143160
}
144161
// LH1be5BU0f91
145162
if (length >= 12) {
146163
return String.format(
147164
"%s%s%s%s",
148-
safeConsensusCode,
149-
consensusClientVersion.commit().toUnprefixedHexString().substring(0, 4),
150-
safeExecutionCode,
151-
isElInfoAvailable
152-
? executionClientVersion.get().commit().toUnprefixedHexString().substring(0, 4)
153-
: "");
165+
consensusCode,
166+
getCommit(consensusClientVersion, 4),
167+
executionCode,
168+
executionClientVersion.map(clientVersion -> getCommit(clientVersion, 4)).orElse(""));
154169
}
155170
// LH1bBU0f
156171
if (length >= 8) {
157172
return String.format(
158173
"%s%s%s%s",
159-
safeConsensusCode,
160-
consensusClientVersion.commit().toUnprefixedHexString().substring(0, 2),
161-
safeExecutionCode,
162-
isElInfoAvailable
163-
? executionClientVersion.get().commit().toUnprefixedHexString().substring(0, 2)
164-
: "");
174+
consensusCode,
175+
getCommit(consensusClientVersion, 2),
176+
executionCode,
177+
executionClientVersion.map(clientVersion -> getCommit(clientVersion, 2)).orElse(""));
165178
}
166179
// LHBU
167180
if (length >= 4) {
168-
return String.format("%s%s", safeConsensusCode, isElInfoAvailable ? safeExecutionCode : "");
181+
return String.format("%s%s", consensusCode, executionCode);
169182
}
170183

171184
return "";
172185
}
173186

174-
protected String extractClientCodeSafely(final ClientVersion clientVersion) {
175-
final boolean isValid =
176-
clientVersion.code() != null
177-
&& clientVersion.code().length() >= 2
178-
&& clientVersion.code().substring(0, 2).matches("[a-zA-Z]{2}");
179-
return isValid
180-
? clientVersion.code().substring(0, 2).toUpperCase(Locale.ROOT)
181-
: ClientVersion.UNKNOWN.code();
187+
private String getExecutionCodeSafely() {
188+
return executionClientVersion
189+
.map(
190+
clientVersion -> {
191+
final String code = clientVersion.code();
192+
final boolean isValid =
193+
code != null && code.length() >= 2 && code.substring(0, 2).matches("[a-zA-Z]{2}");
194+
return isValid
195+
? code.substring(0, 2).toUpperCase(Locale.ROOT)
196+
: ClientVersion.UNKNOWN_CLIENT_CODE;
197+
})
198+
.orElse("");
199+
}
200+
201+
private String getCommit(final ClientVersion clientVersion) {
202+
return clientVersion.commit().toUnprefixedHexString();
203+
}
204+
205+
private String getCommit(final ClientVersion clientVersion, final int length) {
206+
return getCommit(clientVersion).substring(0, length);
182207
}
183208
}

Diff for: beacon/validator/src/test/java/tech/pegasys/teku/validator/coordinator/GraffitiBuilderTest.java

+32-12
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ public class GraffitiBuilderTest {
4848

4949
private final String asciiGraffiti0 = "";
5050
private static final String ASCII_GRAFFITI_20 = "I've proposed ablock";
51+
private static final String ASCII_GRAFFITI_27 = "27 bytes of user's graffiti";
52+
private static final String ASCII_GRAFFITI_28 = "28 bytes of user's graffiti!";
5153
private final String asciiGraffiti32 = "I've proposed a good Teku block!";
5254

5355
private static final String UTF_8_GRAFFITI_4 = "\uD83D\uDE80";
@@ -107,7 +109,6 @@ public void buildGraffiti_shouldPreferCallInput() {
107109
final Bytes32 userGraffiti = Bytes32Parser.toBytes32(ASCII_GRAFFITI_20);
108110
final Bytes32 expectedGraffiti = Bytes32Parser.toBytes32(ASCII_GRAFFITI_20 + " TK");
109111
this.graffitiBuilder = new GraffitiBuilder(CLIENT_CODES, Optional.of(defaultGraffiti));
110-
graffitiBuilder.onExecutionClientVersion(ClientVersion.UNKNOWN);
111112
assertThat(graffitiBuilder.buildGraffiti(Optional.of(userGraffiti)))
112113
.isEqualTo(expectedGraffiti);
113114
}
@@ -140,7 +141,6 @@ public void buildGraffiti_shouldProvideCorrectOutput_whenElInfoNa(
140141
final Optional<String> maybeUserGraffiti,
141142
final String expectedGraffiti) {
142143
this.graffitiBuilder = new GraffitiBuilder(clientGraffitiAppendFormat, userGraffiti);
143-
graffitiBuilder.onExecutionClientVersion(ClientVersion.UNKNOWN);
144144
final Bytes32 expectedGraffitiBytes = Bytes32Parser.toBytes32(expectedGraffiti);
145145
assertThat(
146146
new String(
@@ -339,8 +339,6 @@ public void formatClientInfo_shouldSkipClientsInfo_whenNotEnoughSpace() {
339339

340340
@Test
341341
public void formatClientInfo_shouldRenderClClientNameAndFullCommit_whenElInfoNotAvailable() {
342-
graffitiBuilder.onExecutionClientVersion(ClientVersion.UNKNOWN);
343-
344342
// 20: LH1be52536BU0f91a674
345343
assertThat(graffitiBuilder.formatClientsInfo(30))
346344
.isEqualTo(
@@ -354,8 +352,6 @@ public void formatClientInfo_shouldRenderClClientNameAndFullCommit_whenElInfoNot
354352

355353
@Test
356354
public void formatClientInfo_shouldRenderClClientNameAndHalfCommit_whenElInfoNotAvailable() {
357-
graffitiBuilder.onExecutionClientVersion(ClientVersion.UNKNOWN);
358-
359355
// 12: LH1be5BU0f91
360356
assertThat(graffitiBuilder.formatClientsInfo(19))
361357
.isEqualTo(
@@ -371,8 +367,6 @@ public void formatClientInfo_shouldRenderClClientNameAndHalfCommit_whenElInfoNot
371367

372368
@Test
373369
public void formatClientInfo_shouldRenderClClientNameAnd1stCommitByte_whenElInfoNotAvailable() {
374-
graffitiBuilder.onExecutionClientVersion(ClientVersion.UNKNOWN);
375-
376370
// 8: LH1bBU0f
377371
assertThat(graffitiBuilder.formatClientsInfo(11))
378372
.isEqualTo(
@@ -388,8 +382,6 @@ public void formatClientInfo_shouldRenderClClientNameAnd1stCommitByte_whenElInfo
388382

389383
@Test
390384
public void formatClientInfo_shouldRenderClClientName_whenElInfoNotAvailable() {
391-
graffitiBuilder.onExecutionClientVersion(ClientVersion.UNKNOWN);
392-
393385
// 4: LHBU
394386
assertThat(graffitiBuilder.formatClientsInfo(7))
395387
.isEqualTo(TEKU_CLIENT_VERSION.code())
@@ -401,8 +393,6 @@ public void formatClientInfo_shouldRenderClClientName_whenElInfoNotAvailable() {
401393

402394
@Test
403395
public void formatClientInfo_shouldSkipClientsInfo_whenNotEnoughSpaceAndElInfoNotAvailable() {
404-
graffitiBuilder.onExecutionClientVersion(ClientVersion.UNKNOWN);
405-
406396
// Empty
407397
assertThat(graffitiBuilder.formatClientsInfo(3))
408398
.isEqualTo("")
@@ -541,6 +531,14 @@ private static Stream<Arguments> getBuildGraffitiFixtures() {
541531
+ TEKU_CLIENT_VERSION.commit().toUnprefixedHexString().substring(0, 2)
542532
+ BESU_CLIENT_VERSION.code()
543533
+ BESU_CLIENT_VERSION.commit().toUnprefixedHexString().substring(0, 2)),
534+
Arguments.of(
535+
AUTO,
536+
Optional.of(ASCII_GRAFFITI_27),
537+
ASCII_GRAFFITI_27 + " " + TEKU_CLIENT_VERSION.code() + BESU_CLIENT_VERSION.code()),
538+
Arguments.of(
539+
AUTO,
540+
Optional.of(ASCII_GRAFFITI_28),
541+
ASCII_GRAFFITI_28 + TEKU_CLIENT_VERSION.code() + BESU_CLIENT_VERSION.code()),
544542
Arguments.of(
545543
CLIENT_CODES,
546544
Optional.empty(),
@@ -557,6 +555,14 @@ private static Stream<Arguments> getBuildGraffitiFixtures() {
557555
CLIENT_CODES,
558556
Optional.of(ASCII_GRAFFITI_20),
559557
ASCII_GRAFFITI_20 + " " + TEKU_CLIENT_VERSION.code() + BESU_CLIENT_VERSION.code()),
558+
Arguments.of(
559+
CLIENT_CODES,
560+
Optional.of(ASCII_GRAFFITI_27),
561+
ASCII_GRAFFITI_27 + " " + TEKU_CLIENT_VERSION.code() + BESU_CLIENT_VERSION.code()),
562+
Arguments.of(
563+
CLIENT_CODES,
564+
Optional.of(ASCII_GRAFFITI_28),
565+
ASCII_GRAFFITI_28 + TEKU_CLIENT_VERSION.code() + BESU_CLIENT_VERSION.code()),
560566
Arguments.of(DISABLED, Optional.empty(), ""),
561567
Arguments.of(DISABLED, Optional.of("small"), "small"),
562568
Arguments.of(DISABLED, Optional.of(UTF_8_GRAFFITI_4), UTF_8_GRAFFITI_4),
@@ -589,6 +595,12 @@ private static Stream<Arguments> getBuildGraffitiFixturesElInfoNa() {
589595
+ " "
590596
+ TEKU_CLIENT_VERSION.code()
591597
+ TEKU_CLIENT_VERSION.commit().toUnprefixedHexString().substring(0, 2)),
598+
Arguments.of(
599+
AUTO,
600+
Optional.of(ASCII_GRAFFITI_27),
601+
ASCII_GRAFFITI_27 + " " + TEKU_CLIENT_VERSION.code()),
602+
Arguments.of(
603+
AUTO, Optional.of(ASCII_GRAFFITI_28), ASCII_GRAFFITI_28 + TEKU_CLIENT_VERSION.code()),
592604
Arguments.of(CLIENT_CODES, Optional.empty(), TEKU_CLIENT_VERSION.code()),
593605
Arguments.of(CLIENT_CODES, Optional.of("small"), "small " + TEKU_CLIENT_VERSION.code()),
594606
Arguments.of(
@@ -599,6 +611,14 @@ private static Stream<Arguments> getBuildGraffitiFixturesElInfoNa() {
599611
CLIENT_CODES,
600612
Optional.of(ASCII_GRAFFITI_20),
601613
ASCII_GRAFFITI_20 + " " + TEKU_CLIENT_VERSION.code()),
614+
Arguments.of(
615+
CLIENT_CODES,
616+
Optional.of(ASCII_GRAFFITI_27),
617+
ASCII_GRAFFITI_27 + " " + TEKU_CLIENT_VERSION.code()),
618+
Arguments.of(
619+
CLIENT_CODES,
620+
Optional.of(ASCII_GRAFFITI_28),
621+
ASCII_GRAFFITI_28 + TEKU_CLIENT_VERSION.code()),
602622
Arguments.of(DISABLED, Optional.empty(), ""),
603623
Arguments.of(DISABLED, Optional.of("small"), "small"),
604624
Arguments.of(DISABLED, Optional.of(UTF_8_GRAFFITI_4), UTF_8_GRAFFITI_4),

Diff for: eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/Eth2ReferenceTestCase.java

+9
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@ public abstract class Eth2ReferenceTestCase {
8989
.putAll(MerkleProofTests.MERKLE_PROOF_TEST_TYPES)
9090
.build();
9191

92+
private static final ImmutableMap<String, TestExecutor> ELECTRA_TEST_TYPES =
93+
ImmutableMap.<String, TestExecutor>builder()
94+
.putAll(TransitionTestExecutor.TRANSITION_TEST_TYPES)
95+
.putAll(ForkUpgradeTestExecutor.FORK_UPGRADE_TEST_TYPES)
96+
.putAll(RewardsTestExecutorBellatrix.REWARDS_TEST_TYPES)
97+
.putAll(MerkleProofTests.MERKLE_PROOF_TEST_TYPES)
98+
.build();
99+
92100
protected void runReferenceTest(final TestDefinition testDefinition) throws Throwable {
93101
getExecutorFor(testDefinition).runTest(testDefinition);
94102
}
@@ -102,6 +110,7 @@ private TestExecutor getExecutorFor(final TestDefinition testDefinition) {
102110
case TestFork.BELLATRIX -> BELLATRIX_TEST_TYPES.get(testDefinition.getTestType());
103111
case TestFork.CAPELLA -> CAPELLA_TEST_TYPES.get(testDefinition.getTestType());
104112
case TestFork.DENEB -> DENEB_TEST_TYPES.get(testDefinition.getTestType());
113+
case TestFork.ELECTRA -> ELECTRA_TEST_TYPES.get(testDefinition.getTestType());
105114
default -> null;
106115
};
107116

Diff for: eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/altair/fork/TransitionTestExecutor.java

+6
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ private void processUpgrade(final TestDefinition testDefinition, final MetaData
6565
.bellatrixBuilder(b -> b.bellatrixForkEpoch(UInt64.ZERO))
6666
.capellaBuilder(c -> c.capellaForkEpoch(UInt64.ZERO))
6767
.denebBuilder(d -> d.denebForkEpoch(forkEpoch));
68+
case ELECTRA -> builder
69+
.altairBuilder(a -> a.altairForkEpoch(UInt64.ZERO))
70+
.bellatrixBuilder(b -> b.bellatrixForkEpoch(UInt64.ZERO))
71+
.capellaBuilder(c -> c.capellaForkEpoch(UInt64.ZERO))
72+
.denebBuilder(d -> d.denebForkEpoch(UInt64.ZERO))
73+
.electraBuilder(e -> e.electraForkEpoch(forkEpoch));
6874
default -> throw new IllegalStateException(
6975
"Unhandled fork transition for test "
7076
+ testDefinition.getDisplayName()

Diff for: eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/common/epoch_processing/EpochOperation.java

+2
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,7 @@ public enum EpochOperation {
2626
PROCESS_HISTORICAL_ROOTS_UPDATE,
2727
SYNC_COMMITTEE_UPDATES,
2828
PROCESS_HISTORICAL_SUMMARIES_UPDATE,
29+
PENDING_BALANCE_DEPOSITS,
30+
PENDING_CONSOLIDATIONS,
2931
INACTIVITY_UPDATES
3032
}

Diff for: eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/common/epoch_processing/EpochProcessingExecutor.java

+10
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ public void executeOperation(final EpochOperation operation, final MutableBeacon
4545
state);
4646
case SYNC_COMMITTEE_UPDATES -> epochProcessor.processSyncCommitteeUpdates(state);
4747
case INACTIVITY_UPDATES -> processInactivityUpdates(state);
48+
case PENDING_BALANCE_DEPOSITS -> processPendingBalanceDeposits(state);
49+
case PENDING_CONSOLIDATIONS -> processPendingConsolidations(state);
4850
default -> throw new UnsupportedOperationException(
4951
"Attempted to execute unknown operation type: " + operation);
5052
}
@@ -55,6 +57,14 @@ private void processInactivityUpdates(final MutableBeaconState state) {
5557
state, validatorStatusFactory.createValidatorStatuses(state));
5658
}
5759

60+
private void processPendingBalanceDeposits(final MutableBeaconState state) {
61+
epochProcessor.processPendingBalanceDeposits(state);
62+
}
63+
64+
private void processPendingConsolidations(final MutableBeaconState state) {
65+
epochProcessor.processPendingConsolidations(state);
66+
}
67+
5868
public void processSlashings(final MutableBeaconState state) {
5969
epochProcessor.processSlashings(state, validatorStatusFactory.createValidatorStatuses(state));
6070
}

Diff for: eth-reference-tests/src/referenceTest/java/tech/pegasys/teku/reference/common/epoch_processing/EpochProcessingTestExecutor.java

+6
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ public class EpochProcessingTestExecutor implements TestExecutor {
7878
.put(
7979
"epoch_processing/inactivity_updates",
8080
new EpochProcessingTestExecutor(EpochOperation.INACTIVITY_UPDATES))
81+
.put(
82+
"epoch_processing/pending_consolidations",
83+
new EpochProcessingTestExecutor(EpochOperation.PENDING_CONSOLIDATIONS))
84+
.put(
85+
"epoch_processing/pending_balance_deposits",
86+
new EpochProcessingTestExecutor(EpochOperation.PENDING_BALANCE_DEPOSITS))
8187
.build();
8288

8389
private final EpochOperation operation;

0 commit comments

Comments
 (0)