mirror of https://github.com/hyperledger/besu
Added support for EIP-868 (#1721)
* #1695 - Added support for EIP-868 Signed-off-by: David Mechler <david.mechler@consensys.net> * Fix broken test Signed-off-by: David Mechler <david.mechler@consensys.net> * #1695 - Added tests for new functionality Signed-off-by: David Mechler <david.mechler@consensys.net> * #1695 - spotlessApply Signed-off-by: David Mechler <david.mechler@consensys.net> * Update changelog Signed-off-by: David Mechler <david.mechler@consensys.net>pull/1737/head
parent
850706ed94
commit
98383c5777
@ -0,0 +1,69 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.p2p.discovery.internal; |
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument; |
||||
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPInput; |
||||
import org.hyperledger.besu.ethereum.rlp.RLPOutput; |
||||
|
||||
public class ENRRequestPacketData implements PacketData { |
||||
|
||||
/* Fixed value that represents we're using v5 of the P2P discovery protocol. */ |
||||
private static final int VERSION = 5; |
||||
|
||||
/* In seconds after epoch. */ |
||||
private final long expiration; |
||||
|
||||
private ENRRequestPacketData(final long expiration) { |
||||
checkArgument(expiration >= 0, "expiration cannot be negative"); |
||||
|
||||
this.expiration = expiration; |
||||
} |
||||
|
||||
public static ENRRequestPacketData create() { |
||||
return create(PacketData.defaultExpiration()); |
||||
} |
||||
|
||||
static ENRRequestPacketData create(final long expirationSec) { |
||||
return new ENRRequestPacketData(expirationSec); |
||||
} |
||||
|
||||
public static ENRRequestPacketData readFrom(final RLPInput in) { |
||||
in.enterList(); |
||||
// The first element signifies the "version", but this value is ignored as of EIP-8
|
||||
in.readBigIntegerScalar(); |
||||
final long expiration = in.readLongScalar(); |
||||
in.leaveListLenient(); |
||||
return new ENRRequestPacketData(expiration); |
||||
} |
||||
|
||||
@Override |
||||
public void writeTo(final RLPOutput out) { |
||||
out.startList(); |
||||
out.writeIntScalar(VERSION); |
||||
out.writeLongScalar(expiration); |
||||
out.endList(); |
||||
} |
||||
|
||||
public long getExpiration() { |
||||
return expiration; |
||||
} |
||||
|
||||
@Override |
||||
public String toString() { |
||||
return "ENRRequestPacketData{" + "expiration=" + expiration + '}'; |
||||
} |
||||
} |
@ -0,0 +1,75 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.p2p.discovery.internal; |
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument; |
||||
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPInput; |
||||
import org.hyperledger.besu.ethereum.rlp.RLPOutput; |
||||
|
||||
import org.apache.tuweni.bytes.Bytes; |
||||
import org.ethereum.beacon.discovery.schema.IdentitySchemaInterpreter; |
||||
import org.ethereum.beacon.discovery.schema.NodeRecord; |
||||
import org.ethereum.beacon.discovery.schema.NodeRecordFactory; |
||||
|
||||
public class ENRResponsePacketData implements PacketData { |
||||
/* The hash of the entire ENRRequest packet being replied to. */ |
||||
private final Bytes requestHash; |
||||
|
||||
/* The node record. */ |
||||
private final NodeRecord enr; |
||||
|
||||
private ENRResponsePacketData(final Bytes requestHash, final NodeRecord enr) { |
||||
checkArgument(requestHash != null, "request hash cannot be null"); |
||||
checkArgument(enr != null, "enr cannot be null"); |
||||
|
||||
this.requestHash = requestHash; |
||||
this.enr = enr; |
||||
} |
||||
|
||||
static ENRResponsePacketData create(final Bytes requestHash, final NodeRecord enr) { |
||||
return new ENRResponsePacketData(requestHash, enr); |
||||
} |
||||
|
||||
public static ENRResponsePacketData readFrom(final RLPInput in) { |
||||
in.enterList(); |
||||
final Bytes requestHash = in.readBytes(); |
||||
final NodeRecord enr = |
||||
new NodeRecordFactory(IdentitySchemaInterpreter.V4).fromBytes(in.readBytes()); |
||||
in.leaveListLenient(); |
||||
return new ENRResponsePacketData(requestHash, enr); |
||||
} |
||||
|
||||
@Override |
||||
public void writeTo(final RLPOutput out) { |
||||
out.startList(); |
||||
out.writeBytes(requestHash); |
||||
out.writeBytes(enr.serialize()); |
||||
out.endList(); |
||||
} |
||||
|
||||
public Bytes getRequestHash() { |
||||
return requestHash; |
||||
} |
||||
|
||||
public NodeRecord getEnr() { |
||||
return enr; |
||||
} |
||||
|
||||
@Override |
||||
public String toString() { |
||||
return "ENRResponsePacketData{" + "requestHash=" + requestHash + ", enr=" + enr + '}'; |
||||
} |
||||
} |
@ -0,0 +1,90 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.p2p.discovery.internal; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; |
||||
import org.hyperledger.besu.ethereum.rlp.RLP; |
||||
|
||||
import java.time.Instant; |
||||
|
||||
import org.apache.tuweni.bytes.Bytes; |
||||
import org.junit.Test; |
||||
|
||||
public class ENRRequestPacketDataTest { |
||||
@Test |
||||
public void serializeDeserialize() { |
||||
final long currentTimeSec = Instant.now().getEpochSecond(); |
||||
final ENRRequestPacketData packet = ENRRequestPacketData.create(); |
||||
final Bytes serialized = RLP.encode(packet::writeTo); |
||||
final ENRRequestPacketData deserialized = ENRRequestPacketData.readFrom(RLP.input(serialized)); |
||||
|
||||
assertThat(deserialized.getExpiration()).isGreaterThan(currentTimeSec); |
||||
} |
||||
|
||||
@Test |
||||
public void readFrom() { |
||||
final int version = 4; |
||||
final long time = System.currentTimeMillis(); |
||||
|
||||
final BytesValueRLPOutput out = new BytesValueRLPOutput(); |
||||
out.startList(); |
||||
out.writeIntScalar(version); |
||||
out.writeLongScalar(time); |
||||
out.endList(); |
||||
|
||||
final Bytes serialized = out.encoded(); |
||||
final ENRRequestPacketData deserialized = ENRRequestPacketData.readFrom(RLP.input(serialized)); |
||||
|
||||
assertThat(deserialized.getExpiration()).isEqualTo(time); |
||||
} |
||||
|
||||
@Test |
||||
public void readFrom_withExtraFields() { |
||||
final int version = 4; |
||||
final long time = System.currentTimeMillis(); |
||||
|
||||
final BytesValueRLPOutput out = new BytesValueRLPOutput(); |
||||
out.startList(); |
||||
out.writeIntScalar(version); |
||||
out.writeLongScalar(time); |
||||
// Add extra field
|
||||
out.writeLongScalar(11); |
||||
out.endList(); |
||||
|
||||
final Bytes serialized = out.encoded(); |
||||
final ENRRequestPacketData deserialized = ENRRequestPacketData.readFrom(RLP.input(serialized)); |
||||
|
||||
assertThat(deserialized.getExpiration()).isEqualTo(time); |
||||
} |
||||
|
||||
@Test |
||||
public void readFrom_unknownVersion() { |
||||
final int version = 99; |
||||
final long time = System.currentTimeMillis(); |
||||
|
||||
final BytesValueRLPOutput out = new BytesValueRLPOutput(); |
||||
out.startList(); |
||||
out.writeIntScalar(version); |
||||
out.writeLongScalar(time); |
||||
out.endList(); |
||||
|
||||
final Bytes serialized = out.encoded(); |
||||
final ENRRequestPacketData deserialized = ENRRequestPacketData.readFrom(RLP.input(serialized)); |
||||
|
||||
assertThat(deserialized.getExpiration()).isEqualTo(time); |
||||
} |
||||
} |
@ -0,0 +1,87 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.p2p.discovery.internal; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; |
||||
import org.hyperledger.besu.ethereum.rlp.RLP; |
||||
|
||||
import org.apache.tuweni.bytes.Bytes; |
||||
import org.apache.tuweni.units.bigints.UInt64; |
||||
import org.ethereum.beacon.discovery.schema.EnrField; |
||||
import org.ethereum.beacon.discovery.schema.IdentitySchema; |
||||
import org.ethereum.beacon.discovery.schema.IdentitySchemaInterpreter; |
||||
import org.ethereum.beacon.discovery.schema.NodeRecord; |
||||
import org.ethereum.beacon.discovery.schema.NodeRecordFactory; |
||||
import org.junit.Test; |
||||
|
||||
public class ENRResponsePacketDataTest { |
||||
@Test |
||||
public void serializeDeserialize() { |
||||
final Bytes requestHash = Bytes.fromHexStringLenient("0x1234"); |
||||
final NodeRecord nodeRecord = |
||||
new NodeRecordFactory(IdentitySchemaInterpreter.V4) |
||||
.createFromValues(UInt64.ONE, new EnrField(EnrField.ID, IdentitySchema.V4)); |
||||
|
||||
final ENRResponsePacketData packet = ENRResponsePacketData.create(requestHash, nodeRecord); |
||||
final Bytes serialized = RLP.encode(packet::writeTo); |
||||
final ENRResponsePacketData deserialized = |
||||
ENRResponsePacketData.readFrom(RLP.input(serialized)); |
||||
|
||||
assertThat(deserialized.getRequestHash()).isEqualTo(requestHash); |
||||
assertThat(deserialized.getEnr()).isEqualTo(nodeRecord); |
||||
} |
||||
|
||||
@Test |
||||
public void readFrom() { |
||||
final Bytes requestHash = Bytes.fromHexStringLenient("0x1234"); |
||||
final NodeRecord nodeRecord = |
||||
new NodeRecordFactory(IdentitySchemaInterpreter.V4) |
||||
.createFromValues(UInt64.ONE, new EnrField(EnrField.ID, IdentitySchema.V4)); |
||||
|
||||
BytesValueRLPOutput out = new BytesValueRLPOutput(); |
||||
out.startList(); |
||||
out.writeBytes(requestHash); |
||||
out.writeBytes(nodeRecord.serialize()); |
||||
out.endList(); |
||||
final Bytes encoded = out.encoded(); |
||||
|
||||
final ENRResponsePacketData deserialized = ENRResponsePacketData.readFrom(RLP.input(encoded)); |
||||
assertThat(deserialized.getRequestHash()).isEqualTo(requestHash); |
||||
assertThat(deserialized.getEnr()).isEqualTo(nodeRecord); |
||||
} |
||||
|
||||
@Test |
||||
public void readFrom_withExtraFields() { |
||||
final Bytes requestHash = Bytes.fromHexStringLenient("0x1234"); |
||||
final NodeRecord nodeRecord = |
||||
new NodeRecordFactory(IdentitySchemaInterpreter.V4) |
||||
.createFromValues(UInt64.ONE, new EnrField(EnrField.ID, IdentitySchema.V4)); |
||||
|
||||
BytesValueRLPOutput out = new BytesValueRLPOutput(); |
||||
out.startList(); |
||||
out.writeBytes(requestHash); |
||||
out.writeBytes(nodeRecord.serialize()); |
||||
// Add random fields
|
||||
out.writeLong(1234L); |
||||
out.endList(); |
||||
final Bytes encoded = out.encoded(); |
||||
|
||||
final ENRResponsePacketData deserialized = ENRResponsePacketData.readFrom(RLP.input(encoded)); |
||||
assertThat(deserialized.getRequestHash()).isEqualTo(requestHash); |
||||
assertThat(deserialized.getEnr()).isEqualTo(nodeRecord); |
||||
} |
||||
} |
Loading…
Reference in new issue