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