Skip to content

Commit 5b62e62

Browse files
authored
Introduce enr sig cache and bump nodeIdCache cache (#197)
1 parent f2064f0 commit 5b62e62

1 file changed

Lines changed: 26 additions & 3 deletions

File tree

src/main/java/org/ethereum/beacon/discovery/schema/IdentitySchemaV4Interpreter.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import static org.ethereum.beacon.discovery.schema.NodeRecordBuilder.addCustomField;
88

99
import com.google.common.base.Preconditions;
10+
import com.google.common.cache.Cache;
1011
import com.google.common.cache.CacheBuilder;
1112
import com.google.common.cache.CacheLoader;
1213
import com.google.common.cache.LoadingCache;
@@ -27,18 +28,28 @@
2728
import org.apache.tuweni.bytes.Bytes;
2829
import org.bouncycastle.math.ec.ECPoint;
2930
import org.ethereum.beacon.discovery.crypto.Signer;
31+
import org.ethereum.beacon.discovery.util.CryptoUtil;
3032
import org.ethereum.beacon.discovery.util.Functions;
3133
import org.ethereum.beacon.discovery.util.Utils;
3234

3335
public class IdentitySchemaV4Interpreter implements IdentitySchemaInterpreter {
3436

3537
private static final Logger LOG = LogManager.getLogger();
3638

39+
// key: compressed pubKey (33 bytes), value: nodeId (32 bytes)
40+
// ~165 bytes/entry with overhead, 10000 entries ≈ 1.6 MB
3741
private final LoadingCache<Bytes, Bytes> nodeIdCache =
3842
CacheBuilder.newBuilder()
39-
.maximumSize(4000)
43+
.maximumSize(10000)
4044
.build(CacheLoader.from(IdentitySchemaV4Interpreter::calculateNodeIdImpl));
4145

46+
// key: sha256(serializedNoSig) (32 bytes), value: signature (64 bytes)
47+
// ~196 bytes/entry (32 + 64 + ~100 Guava overhead), 10000 entries ≈ 1.9 MB
48+
// Only caches valid (true) results to prevent cache pollution attacks.
49+
// On cache hit, the stored signature is compared to the current to prevent reuse attacks.
50+
private final Cache<Bytes, Bytes> enrSignatureCache =
51+
CacheBuilder.newBuilder().maximumSize(10000).build();
52+
4253
private static final ImmutableSet<String> ADDRESS_IP_V4_FIELD_NAMES =
4354
ImmutableSet.of(EnrField.IP_V4, EnrField.UDP);
4455

@@ -57,9 +68,21 @@ public boolean isValid(final NodeRecord nodeRecord) {
5768
getScheme());
5869
return false;
5970
}
71+
Bytes signature = nodeRecord.getSignature();
72+
Bytes serializedNoSig = nodeRecord.serializeNoSignature();
73+
Bytes serializedNoSigHash = CryptoUtil.sha256(serializedNoSig);
74+
Bytes cachedSignature = enrSignatureCache.getIfPresent(serializedNoSigHash);
75+
if (cachedSignature != null && cachedSignature.equals(signature)) {
76+
return true;
77+
}
78+
6079
Bytes pubKey = (Bytes) nodeRecord.get(EnrField.PKEY_SECP256K1); // compressed
61-
return Functions.verifyECDSASignature(
62-
nodeRecord.getSignature(), Functions.hashKeccak(nodeRecord.serializeNoSignature()), pubKey);
80+
boolean result =
81+
Functions.verifyECDSASignature(signature, Functions.hashKeccak(serializedNoSig), pubKey);
82+
if (result) {
83+
enrSignatureCache.put(serializedNoSigHash, signature);
84+
}
85+
return result;
6386
}
6487

6588
@Override

0 commit comments

Comments
 (0)