diff --git a/contracts/javascore/aggregator/src/main/java/relay/aggregator/RelayAggregator.java b/contracts/javascore/aggregator/src/main/java/relay/aggregator/RelayAggregator.java
index 440b8c19..c597f81a 100644
--- a/contracts/javascore/aggregator/src/main/java/relay/aggregator/RelayAggregator.java
+++ b/contracts/javascore/aggregator/src/main/java/relay/aggregator/RelayAggregator.java
@@ -41,6 +41,7 @@ public class RelayAggregator {
private final ArrayDB
relayers = Context.newArrayDB("relayers", Address.class);
private final DictDB relayersLookup = Context.newDictDB("relayersLookup", Boolean.class);
+ private final DictDB acknowledgedPackets = Context.newDictDB("acknowledgedPackets", Boolean.class);
private final DictDB packets = Context.newDictDB("packets", Packet.class);
private final BranchDB> signatures = Context.newBranchDB("signatures",
@@ -130,6 +131,20 @@ public boolean packetSubmitted(
return existingSign != null;
}
+ @External(readonly = true)
+ public boolean packetAcknowledged(
+ String srcNetwork,
+ String srcContractAddress,
+ BigInteger srcSn,
+ BigInteger srcHeight,
+ String dstNetwork,
+ String dstContractAddress,
+ byte[] data) {
+ Packet pkt = new Packet(srcNetwork, srcContractAddress, srcSn, srcHeight, dstNetwork, dstContractAddress, data);
+ byte[] pktID = pkt.getId();
+ return acknowledgedPackets.get(pktID) != null && acknowledgedPackets.get(pktID) == true;
+ }
+
@External
public void submitPacket(
String srcNetwork,
@@ -146,6 +161,10 @@ public void submitPacket(
Packet pkt = new Packet(srcNetwork, srcContractAddress, srcSn, srcHeight, dstNetwork, dstContractAddress, data);
byte[] pktID = pkt.getId();
+ if (acknowledgedPackets.get(pktID) != null && acknowledgedPackets.get(pktID) == true) {
+ return;
+ }
+
if (packets.get(pktID) == null) {
packets.set(pktID, pkt);
if (signatureThreshold.get() > 1) {
@@ -178,6 +197,7 @@ public void submitPacket(
pkt.getDstContractAddress(),
pkt.getData(),
encodedSigs);
+ acknowledgedPackets.set(pktID, true);
removePacket(pktID);
}
}
diff --git a/contracts/javascore/aggregator/src/test/java/relay/aggregator/RelayAggregatorTest.java b/contracts/javascore/aggregator/src/test/java/relay/aggregator/RelayAggregatorTest.java
index 4165d4e6..9f1137d1 100644
--- a/contracts/javascore/aggregator/src/test/java/relay/aggregator/RelayAggregatorTest.java
+++ b/contracts/javascore/aggregator/src/test/java/relay/aggregator/RelayAggregatorTest.java
@@ -236,7 +236,7 @@ public void testPacketSubmitted_false() throws Exception {
}
@Test
- public void testSubmitPacket() throws Exception {
+ public void testPacketAcknowledged_true() throws Exception {
String srcNetwork = "0x2.icon";
String dstNetwork = "sui";
BigInteger srcSn = BigInteger.ONE;
@@ -248,20 +248,40 @@ public void testSubmitPacket() throws Exception {
aggregator.invoke(adminAc, "setSignatureThreshold", 2);
byte[] dataHash = Context.hash("sha-256", data);
- byte[] sign = relayerOne.sign(dataHash);
+ byte[] signOne = relayerOne.sign(dataHash);
aggregator.invoke(relayerOneAc, "submitPacket", srcNetwork,
srcContractAddress, srcSn, srcHeight, dstNetwork,
+ dstContractAddress,
+ data,
+ signOne);
+
+ byte[] signTwo = relayerTwo.sign(dataHash);
+ aggregator.invoke(relayerTwoAc, "submitPacket", srcNetwork,
+ srcContractAddress, srcSn, srcHeight, dstNetwork,
+ dstContractAddress,
+ data,
+ signTwo);
+
+ byte[][] sigs = new byte[2][];
+ sigs[0] = signOne;
+ sigs[1] = signTwo;
+
+ byte[] encodedSigs = RelayAggregator.serializeSignatures(sigs);
+ byte[][] decodedSigs = RelayAggregator.deserializeSignatures(encodedSigs);
+
+ assertArrayEquals(signOne, decodedSigs[0]);
+ assertArrayEquals(signTwo, decodedSigs[1]);
+
+ verify(aggregatorSpy).PacketAcknowledged(srcNetwork, srcContractAddress,
+ srcSn, srcHeight, dstNetwork,
dstContractAddress, data,
- sign);
+ encodedSigs);
- Packet pkt = new Packet(srcNetwork, srcContractAddress, srcSn, srcHeight, dstNetwork,
- dstContractAddress, data);
- byte[] pktID = pkt.getId();
- verify(aggregatorSpy).PacketRegistered(srcNetwork, srcContractAddress, srcSn,
- srcHeight, dstNetwork,
- dstContractAddress, data);
- verify(aggregatorSpy).setSignature(pktID, relayerOneAc.getAddress(), sign);
+ boolean acknowledged = (boolean) aggregator.call("packetAcknowledged",
+ srcNetwork,
+ srcContractAddress, srcSn, srcHeight, dstNetwork, dstContractAddress, data);
+ assertEquals(acknowledged, true);
}
@Test