Skip to content

Commit e48d333

Browse files
committed
Fix failing test and better management of pre London fee market in layered txpool
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
1 parent 5ac18fe commit e48d333

22 files changed

+476
-359
lines changed

besu/src/main/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,9 @@ public ConfigurationOverviewBuilder setHighSpecEnabled() {
168168
}
169169

170170
/**
171-
* Sets experimental layered txpool enabled.
171+
* Sets the txpool implementation in use.
172172
*
173+
* @param implementation the txpool implementation
173174
* @return the builder
174175
*/
175176
public ConfigurationOverviewBuilder setTxPoolImplementation(
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright Hyperledger Besu Contributors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5+
* the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11+
* specific language governing permissions and limitations under the License.
12+
*
13+
* SPDX-License-Identifier: Apache-2.0
14+
*/
15+
package org.hyperledger.besu.cli.converter;
16+
17+
import org.hyperledger.besu.cli.converter.exception.DurationConversionException;
18+
19+
import java.time.Duration;
20+
21+
import picocli.CommandLine;
22+
23+
/** The Percentage Cli type converter. */
24+
public class DurationMillisConverter
25+
implements CommandLine.ITypeConverter<Duration>, TypeFormatter<Duration> {
26+
27+
@Override
28+
public Duration convert(final String value) throws DurationConversionException {
29+
try {
30+
final long millis = Long.parseLong(value);
31+
if (millis < 0) {
32+
throw new DurationConversionException(millis);
33+
}
34+
return Duration.ofMillis(Long.parseLong(value));
35+
} catch (NullPointerException | IllegalArgumentException e) {
36+
throw new DurationConversionException(value);
37+
}
38+
}
39+
40+
@Override
41+
public String format(final Duration value) {
42+
return Long.toString(value.toMillis());
43+
}
44+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright Hyperledger Besu Contributors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5+
* the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11+
* specific language governing permissions and limitations under the License.
12+
*
13+
* SPDX-License-Identifier: Apache-2.0
14+
*/
15+
package org.hyperledger.besu.cli.converter;
16+
17+
/**
18+
* This interface can be used to give a converter the capability to format the converted value back
19+
* to its CLI form
20+
*
21+
* @param <V> the type of the CLI converted runtime value
22+
*/
23+
public interface TypeFormatter<V> {
24+
/**
25+
* Format a converted value back to its CLI form
26+
*
27+
* @param value the converted value
28+
* @return the textual CLI form of the value
29+
*/
30+
String format(V value);
31+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright Hyperledger Besu Contributors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5+
* the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11+
* specific language governing permissions and limitations under the License.
12+
*
13+
* SPDX-License-Identifier: Apache-2.0
14+
*/
15+
package org.hyperledger.besu.cli.converter.exception;
16+
17+
import static java.lang.String.format;
18+
19+
/** The custom Duration conversion exception. */
20+
public final class DurationConversionException extends Exception {
21+
22+
/**
23+
* Instantiates a new Duration conversion exception for malformed value.
24+
*
25+
* @param value the value
26+
*/
27+
public DurationConversionException(final String value) {
28+
super(format("'%s' is not a long", value));
29+
}
30+
31+
/**
32+
* Instantiates a new Duration conversion exception for negative value.
33+
*
34+
* @param millis the value
35+
*/
36+
public DurationConversionException(final long millis) {
37+
super(format("negative value '%d' is not allowed", millis));
38+
}
39+
}

besu/src/main/java/org/hyperledger/besu/cli/options/OptionParser.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,21 @@ public static String format(final Wei value) {
112112
return format(value.toUInt256());
113113
}
114114

115+
/**
116+
* Format any object to string. This implementation tries to find an existing format method, in
117+
* this class, that matches the type of the passed object, and if not found just invoke, to string
118+
* on the passed object
119+
*
120+
* @param value the object
121+
* @return the string
122+
*/
115123
public static String format(final Object value) {
116124
Method formatMethod;
117125
try {
118126
formatMethod = OptionParser.class.getMethod("format", value.getClass());
119127
} catch (NoSuchMethodException e) {
120128
try {
129+
// maybe a primitive version of the method exists
121130
formatMethod =
122131
OptionParser.class.getMethod(
123132
"format", MethodType.methodType(value.getClass()).unwrap().returnType());

besu/src/main/java/org/hyperledger/besu/cli/options/stable/TransactionPoolOptions.java

Lines changed: 16 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.hyperledger.besu.cli.converter.FractionConverter;
2424
import org.hyperledger.besu.cli.converter.PercentageConverter;
2525
import org.hyperledger.besu.cli.options.CLIOptions;
26-
import org.hyperledger.besu.cli.options.OptionParser;
2726
import org.hyperledger.besu.cli.util.CommandLineUtils;
2827
import org.hyperledger.besu.datatypes.Wei;
2928
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
@@ -32,16 +31,11 @@
3231
import org.hyperledger.besu.util.number.Percentage;
3332

3433
import java.io.File;
35-
import java.lang.annotation.Annotation;
36-
import java.lang.reflect.Field;
37-
import java.lang.reflect.Modifier;
38-
import java.util.ArrayList;
39-
import java.util.Arrays;
4034
import java.util.List;
41-
import java.util.Objects;
4235

4336
import picocli.CommandLine;
4437

38+
/** The Transaction pool Cli stable options. */
4539
public class TransactionPoolOptions implements CLIOptions<TransactionPoolConfiguration> {
4640
private static final String TX_POOL_IMPLEMENTATION = "--tx-pool";
4741
private static final String TX_POOL_DISABLE_LOCALS = "--tx-pool-disable-locals";
@@ -126,7 +120,7 @@ static class Layered {
126120
description =
127121
"Max amount of memory space, in bytes, that any layer within the transaction pool could occupy (default: ${DEFAULT-VALUE})",
128122
arity = "1")
129-
long txPoolLayerMaxCapacity =
123+
Long txPoolLayerMaxCapacity =
130124
TransactionPoolConfiguration.DEFAULT_PENDING_TRANSACTIONS_LAYER_MAX_CAPACITY_BYTES;
131125

132126
@CommandLine.Option(
@@ -135,15 +129,16 @@ static class Layered {
135129
description =
136130
"Max number of pending transactions that are prioritized and thus kept sorted (default: ${DEFAULT-VALUE})",
137131
arity = "1")
138-
int txPoolMaxPrioritized = TransactionPoolConfiguration.DEFAULT_MAX_PRIORITIZED_TRANSACTIONS;
132+
Integer txPoolMaxPrioritized =
133+
TransactionPoolConfiguration.DEFAULT_MAX_PRIORITIZED_TRANSACTIONS;
139134

140135
@CommandLine.Option(
141136
names = {TX_POOL_MAX_FUTURE_BY_SENDER},
142137
paramLabel = MANDATORY_INTEGER_FORMAT_HELP,
143138
description =
144139
"Max number of future pending transactions allowed for a single sender (default: ${DEFAULT-VALUE})",
145140
arity = "1")
146-
int txPoolMaxFutureBySender = TransactionPoolConfiguration.DEFAULT_MAX_FUTURE_BY_SENDER;
141+
Integer txPoolMaxFutureBySender = TransactionPoolConfiguration.DEFAULT_MAX_FUTURE_BY_SENDER;
147142
}
148143

149144
@CommandLine.ArgGroup(
@@ -163,7 +158,7 @@ static class Legacy {
163158
description =
164159
"Maximum retention period of pending transactions in hours (default: ${DEFAULT-VALUE})",
165160
arity = "1")
166-
int pendingTxRetentionPeriod = TransactionPoolConfiguration.DEFAULT_TX_RETENTION_HOURS;
161+
Integer pendingTxRetentionPeriod = TransactionPoolConfiguration.DEFAULT_TX_RETENTION_HOURS;
167162

168163
@CommandLine.Option(
169164
names = {TX_POOL_LIMIT_BY_ACCOUNT_PERCENTAGE},
@@ -181,7 +176,7 @@ static class Legacy {
181176
description =
182177
"Maximum number of pending transactions that will be kept in the transaction pool (default: ${DEFAULT-VALUE})",
183178
arity = "1")
184-
int txPoolMaxSize = TransactionPoolConfiguration.DEFAULT_MAX_PENDING_TRANSACTIONS;
179+
Integer txPoolMaxSize = TransactionPoolConfiguration.DEFAULT_MAX_PENDING_TRANSACTIONS;
185180
}
186181

187182
private TransactionPoolOptions() {}
@@ -222,34 +217,24 @@ public static TransactionPoolOptions fromConfig(final TransactionPoolConfigurati
222217
return options;
223218
}
224219

220+
/**
221+
* Validate that there are no inconsistencies in the specified options. For example that the
222+
* options are valid for the selected implementation.
223+
*
224+
* @param commandLine the full commandLine to check all the options specified by the user
225+
*/
225226
public void validate(final CommandLine commandLine) {
226227
CommandLineUtils.failIfOptionDoesntMeetRequirement(
227228
commandLine,
228229
"Could not use legacy transaction pool options with layered implementation",
229230
!txPoolImplementation.equals(LAYERED),
230-
allOptionsOfGroup(Legacy.class));
231+
CommandLineUtils.getCLIOptionNames(Legacy.class));
231232

232233
CommandLineUtils.failIfOptionDoesntMeetRequirement(
233234
commandLine,
234235
"Could not use layered transaction pool options with legacy implementation",
235236
!txPoolImplementation.equals(LEGACY),
236-
allOptionsOfGroup(Layered.class));
237-
}
238-
239-
private List<String> allOptionsOfGroup(final Class<?> group) {
240-
return Arrays.stream(group.getDeclaredFields())
241-
.filter(f -> Modifier.isStatic(f.getModifiers()))
242-
.map(
243-
f -> {
244-
try {
245-
return f.get(null);
246-
} catch (IllegalAccessException e) {
247-
throw new RuntimeException(e);
248-
}
249-
})
250-
.filter(o -> o instanceof String)
251-
.map(String.class::cast)
252-
.toList();
237+
CommandLineUtils.getCLIOptionNames(Layered.class));
253238
}
254239

255240
@Override
@@ -273,39 +258,6 @@ public TransactionPoolConfiguration toDomainObject() {
273258

274259
@Override
275260
public List<String> getCLIOptions() {
276-
return getCLIOptions(getClass(), this, new TransactionPoolOptions());
277-
}
278-
279-
private List<String> getCLIOptions(
280-
final Class<?> startClass, final Object currOptions, final Object defaults) {
281-
List<String> cliOpts = new ArrayList<>();
282-
Field[] fields = startClass.getDeclaredFields();
283-
for (Field field : fields) {
284-
Annotation optionAnnotation = field.getAnnotation(CommandLine.Option.class);
285-
if (optionAnnotation != null) {
286-
try {
287-
var optVal = field.get(currOptions);
288-
if (!Objects.equals(optVal, field.get(defaults))) {
289-
var optAnn = CommandLine.Option.class.cast(optionAnnotation);
290-
String optName = optAnn.names()[0];
291-
cliOpts.add(optName);
292-
cliOpts.add(OptionParser.format(optVal));
293-
}
294-
} catch (IllegalAccessException e) {
295-
throw new RuntimeException(e);
296-
}
297-
} else {
298-
Annotation groupAnnotation = field.getAnnotation(CommandLine.ArgGroup.class);
299-
if (groupAnnotation != null) {
300-
try {
301-
cliOpts.addAll(
302-
getCLIOptions(field.getType(), field.get(currOptions), field.get(defaults)));
303-
} catch (IllegalAccessException e) {
304-
throw new RuntimeException(e);
305-
}
306-
}
307-
}
308-
}
309-
return cliOpts;
261+
return CommandLineUtils.getCLIOptions(this, new TransactionPoolOptions());
310262
}
311263
}

besu/src/main/java/org/hyperledger/besu/cli/options/unstable/TransactionPoolOptions.java

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,18 @@
1414
*/
1515
package org.hyperledger.besu.cli.options.unstable;
1616

17+
import org.hyperledger.besu.cli.converter.DurationMillisConverter;
1718
import org.hyperledger.besu.cli.options.CLIOptions;
18-
import org.hyperledger.besu.cli.options.OptionParser;
19+
import org.hyperledger.besu.cli.util.CommandLineUtils;
1920
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
2021
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
2122

2223
import java.time.Duration;
23-
import java.util.Arrays;
2424
import java.util.List;
2525

2626
import picocli.CommandLine;
2727

28-
/** The Transaction pool Cli options. */
28+
/** The Transaction pool Cli unstable options. */
2929
public class TransactionPoolOptions implements CLIOptions<TransactionPoolConfiguration.Unstable> {
3030
private static final String TX_MESSAGE_KEEP_ALIVE_SEC_FLAG =
3131
"--Xincoming-tx-messages-keep-alive-seconds";
@@ -46,12 +46,13 @@ public class TransactionPoolOptions implements CLIOptions<TransactionPoolConfigu
4646
@CommandLine.Option(
4747
names = {ETH65_TX_ANNOUNCED_BUFFERING_PERIOD_FLAG},
4848
paramLabel = "<LONG>",
49+
converter = DurationMillisConverter.class,
4950
hidden = true,
5051
description =
5152
"The period for which the announced transactions remain in the buffer before being requested from the peers in milliseconds (default: ${DEFAULT-VALUE})",
5253
arity = "1")
53-
private long eth65TrxAnnouncedBufferingPeriod =
54-
TransactionPoolConfiguration.Unstable.ETH65_TRX_ANNOUNCED_BUFFERING_PERIOD.toMillis();
54+
private Duration eth65TrxAnnouncedBufferingPeriod =
55+
TransactionPoolConfiguration.Unstable.ETH65_TRX_ANNOUNCED_BUFFERING_PERIOD;
5556

5657
private TransactionPoolOptions() {}
5758

@@ -74,25 +75,20 @@ public static TransactionPoolOptions fromConfig(
7475
final TransactionPoolConfiguration.Unstable config) {
7576
final TransactionPoolOptions options = TransactionPoolOptions.create();
7677
options.txMessageKeepAliveSeconds = config.getTxMessageKeepAliveSeconds();
77-
options.eth65TrxAnnouncedBufferingPeriod =
78-
config.getEth65TrxAnnouncedBufferingPeriod().toMillis();
78+
options.eth65TrxAnnouncedBufferingPeriod = config.getEth65TrxAnnouncedBufferingPeriod();
7979
return options;
8080
}
8181

8282
@Override
8383
public TransactionPoolConfiguration.Unstable toDomainObject() {
8484
return ImmutableTransactionPoolConfiguration.Unstable.builder()
8585
.txMessageKeepAliveSeconds(txMessageKeepAliveSeconds)
86-
.eth65TrxAnnouncedBufferingPeriod(Duration.ofMillis(eth65TrxAnnouncedBufferingPeriod))
86+
.eth65TrxAnnouncedBufferingPeriod(eth65TrxAnnouncedBufferingPeriod)
8787
.build();
8888
}
8989

9090
@Override
9191
public List<String> getCLIOptions() {
92-
return Arrays.asList(
93-
TX_MESSAGE_KEEP_ALIVE_SEC_FLAG,
94-
OptionParser.format(txMessageKeepAliveSeconds),
95-
ETH65_TX_ANNOUNCED_BUFFERING_PERIOD_FLAG,
96-
OptionParser.format(eth65TrxAnnouncedBufferingPeriod));
92+
return CommandLineUtils.getCLIOptions(this, new TransactionPoolOptions());
9793
}
9894
}

0 commit comments

Comments
 (0)