diff --git a/contracts/javascore/aggregator/src/main/java/relay/aggregator/Packet.java b/contracts/javascore/aggregator/src/main/java/relay/aggregator/Packet.java index 0568de37..16d600cf 100644 --- a/contracts/javascore/aggregator/src/main/java/relay/aggregator/Packet.java +++ b/contracts/javascore/aggregator/src/main/java/relay/aggregator/Packet.java @@ -2,6 +2,7 @@ import java.math.BigInteger; +import score.ByteArrayObjectWriter; import score.Context; import score.ObjectReader; import score.ObjectWriter; @@ -66,8 +67,6 @@ public Packet(String srcNetwork, String srcContractAddress, BigInteger srcSn, Bi || srcHeight == null || dstNetwork == null || dstContractAddress == null || data == null; Context.require(!isIllegalArg, "srcNetwork, contractAddress, srcSn, srcHeight, dstNetwork, and data cannot be null"); - if (isIllegalArg) { - } this.srcNetwork = srcNetwork; this.srcContractAddress = srcContractAddress; this.srcSn = srcSn; @@ -77,12 +76,8 @@ public Packet(String srcNetwork, String srcContractAddress, BigInteger srcSn, Bi this.data = data; } - public String getId() { - return createId(this.srcNetwork, this.srcContractAddress, this.srcSn); - } - - public static String createId(String srcNetwork, String contractAddress, BigInteger srcSn) { - return srcNetwork + "/" + contractAddress + "/" + srcSn.toString(); + public byte[] getId() { + return Context.hash("sha-256", this.toBytes()); } /** @@ -173,4 +168,10 @@ public static Packet readObject(ObjectReader r) { r.end(); return p; } + + public byte[] toBytes() { + ByteArrayObjectWriter writer = Context.newByteArrayObjectWriter("RLPn"); + Packet.writeObject(writer, this); + return writer.toByteArray(); + } } 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 ec475a99..440b8c19 100644 --- a/contracts/javascore/aggregator/src/main/java/relay/aggregator/RelayAggregator.java +++ b/contracts/javascore/aggregator/src/main/java/relay/aggregator/RelayAggregator.java @@ -41,16 +41,15 @@ public class RelayAggregator { private final ArrayDB
relayers = Context.newArrayDB("relayers", Address.class); private final DictDB relayersLookup = Context.newDictDB("relayersLookup", Boolean.class); - private final DictDB packets = Context.newDictDB("packets", Packet.class); + private final DictDB packets = Context.newDictDB("packets", Packet.class); - private final BranchDB> signatures = Context.newBranchDB("signatures", + private final BranchDB> signatures = Context.newBranchDB("signatures", byte[].class); public RelayAggregator(Address _admin) { if (admin.get() == null) { admin.set(_admin); signatureThreshold.set(DEFAULT_SIGNATURE_THRESHOLD); - addRelayer(_admin); } } @@ -60,12 +59,6 @@ public void setAdmin(Address _admin) { Context.require(admin.get() != _admin, "admin already set"); - // add new admin as relayer - addRelayer(_admin); - - // remove old admin from relayer list - removeRelayer(admin.get()); - admin.set(_admin); } @@ -107,10 +100,9 @@ public void setRelayers(Address[] newRelayers, int threshold) { addRelayer(newRelayer); } - Address adminAdrr = admin.get(); for (int i = 0; i < relayers.size(); i++) { Address oldRelayer = relayers.get(i); - if (!oldRelayer.equals(adminAdrr) && !newRelayersMap.containsKey(oldRelayer)) { + if (!newRelayersMap.containsKey(oldRelayer)) { removeRelayer(oldRelayer); } } @@ -127,8 +119,13 @@ public boolean packetSubmitted( Address relayer, String srcNetwork, String srcContractAddress, - BigInteger srcSn) { - String pktID = Packet.createId(srcNetwork, srcContractAddress, srcSn); + 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(); byte[] existingSign = signatures.at(pktID).get(relayer); return existingSign != null; } @@ -147,7 +144,7 @@ public void submitPacket( relayersOnly(); Packet pkt = new Packet(srcNetwork, srcContractAddress, srcSn, srcHeight, dstNetwork, dstContractAddress, data); - String pktID = pkt.getId(); + byte[] pktID = pkt.getId(); if (packets.get(pktID) == null) { packets.set(pktID, pkt); @@ -170,7 +167,7 @@ public void submitPacket( setSignature(pktID, Context.getCaller(), signature); if (signatureThresholdReached(pktID)) { - byte[][] sigs = getSignatures(srcNetwork, srcContractAddress, srcSn); + byte[][] sigs = getSignatures(pktID); byte[] encodedSigs = serializeSignatures(sigs); PacketAcknowledged( pkt.getSrcNetwork(), @@ -185,8 +182,7 @@ public void submitPacket( } } - private byte[][] getSignatures(String srcNetwork, String srcContractAddress, BigInteger srcSn) { - String pktID = Packet.createId(srcNetwork, srcContractAddress, srcSn); + private byte[][] getSignatures(byte[] pktID) { DictDB signDict = signatures.at(pktID); ArrayList signatureList = new ArrayList(); @@ -205,7 +201,7 @@ private byte[][] getSignatures(String srcNetwork, String srcContractAddress, Big return sigs; } - protected void setSignature(String pktID, Address addr, byte[] sign) { + protected void setSignature(byte[] pktID, Address addr, byte[] sign) { signatures.at(pktID).set(addr, sign); } @@ -241,7 +237,7 @@ protected static byte[][] deserializeSignatures(byte[] encodedSigs) { } private void adminOnly() { - Context.require(Context.getCaller().equals(admin.get()), "Unauthorized: caller is not the leader relayer"); + Context.require(Context.getCaller().equals(admin.get()), "Unauthorized: caller is not the admin"); } private void relayersOnly() { @@ -270,7 +266,7 @@ private void removeRelayer(Address oldRelayer) { } } - private Boolean signatureThresholdReached(String pktID) { + private Boolean signatureThresholdReached(byte[] pktID) { int noOfSignatures = 0; for (int i = 0; i < relayers.size(); i++) { Address relayer = relayers.get(i); @@ -282,7 +278,7 @@ private Boolean signatureThresholdReached(String pktID) { return noOfSignatures >= signatureThreshold.get(); } - private void removePacket(String pktID) { + private void removePacket(byte[] pktID) { packets.set(pktID, null); DictDB signDict = signatures.at(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 0da3391f..4165d4e6 100644 --- a/contracts/javascore/aggregator/src/test/java/relay/aggregator/RelayAggregatorTest.java +++ b/contracts/javascore/aggregator/src/test/java/relay/aggregator/RelayAggregatorTest.java @@ -1,7 +1,6 @@ package relay.aggregator; import java.math.BigInteger; -import java.util.Arrays; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -21,347 +20,342 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; class RelayAggregatorTest extends TestBase { - private final ServiceManager sm = getServiceManager(); + private final ServiceManager sm = getServiceManager(); - private KeyWallet admin; - private Account adminAc; + private KeyWallet admin; + private Account adminAc; - private KeyWallet relayerOne; - private Account relayerOneAc; + private KeyWallet relayerOne; + private Account relayerOneAc; - private KeyWallet relayerTwo; - private Account relayerTwoAc; + private KeyWallet relayerTwo; + private Account relayerTwoAc; - private KeyWallet relayerThree; - private Account relayerThreeAc; + private KeyWallet relayerThree; + private Account relayerThreeAc; - private KeyWallet relayerFour; - private Account relayerFourAc; + private KeyWallet relayerFour; + private Account relayerFourAc; - private Score aggregator; - private RelayAggregator aggregatorSpy; + private Score aggregator; + private RelayAggregator aggregatorSpy; - @BeforeEach - void setup() throws Exception { - admin = KeyWallet.create(); - adminAc = sm.getAccount(Address.fromString(admin.getAddress().toString())); + @BeforeEach + void setup() throws Exception { + admin = KeyWallet.create(); + adminAc = sm.getAccount(Address.fromString(admin.getAddress().toString())); - relayerOne = KeyWallet.create(); - relayerOneAc = sm.getAccount(Address.fromString(relayerOne.getAddress().toString())); + relayerOne = KeyWallet.create(); + relayerOneAc = sm.getAccount(Address.fromString(relayerOne.getAddress().toString())); - relayerTwo = KeyWallet.create(); - relayerTwoAc = sm.getAccount(Address.fromString(relayerTwo.getAddress().toString())); + relayerTwo = KeyWallet.create(); + relayerTwoAc = sm.getAccount(Address.fromString(relayerTwo.getAddress().toString())); - relayerThree = KeyWallet.create(); - relayerThreeAc = sm.getAccount(Address.fromString(relayerThree.getAddress().toString())); + relayerThree = KeyWallet.create(); + relayerThreeAc = sm.getAccount(Address.fromString(relayerThree.getAddress().toString())); - relayerFour = KeyWallet.create(); - relayerFourAc = sm.getAccount(Address.fromString(relayerFour.getAddress().toString())); + relayerFour = KeyWallet.create(); + relayerFourAc = sm.getAccount(Address.fromString(relayerFour.getAddress().toString())); - aggregator = sm.deploy(adminAc, RelayAggregator.class, adminAc.getAddress()); + aggregator = sm.deploy(adminAc, RelayAggregator.class, adminAc.getAddress()); - Address[] relayers = new Address[] { adminAc.getAddress(), relayerOneAc.getAddress(), relayerTwoAc.getAddress(), - relayerThreeAc.getAddress() }; + Address[] relayers = new Address[] { relayerOneAc.getAddress(), relayerTwoAc.getAddress(), + relayerThreeAc.getAddress() }; - aggregator.invoke(adminAc, "setRelayers", (Object) relayers, 2); + aggregator.invoke(adminAc, "setRelayers", (Object) relayers, 2); - aggregatorSpy = (RelayAggregator) spy(aggregator.getInstance()); - aggregator.setInstance(aggregatorSpy); - } + aggregatorSpy = (RelayAggregator) spy(aggregator.getInstance()); + aggregator.setInstance(aggregatorSpy); + } + + @Test + public void testSetAdmin() { + Account newAdminAc = sm.createAccount(); + aggregator.invoke(adminAc, "setAdmin", newAdminAc.getAddress()); + + Address newAdmin = (Address) aggregator.call("getAdmin"); + assertEquals(newAdminAc.getAddress(), newAdmin); + } + + @Test + public void testSetAdmin_unauthorized() { + Account normalAc = sm.createAccount(); + Account newAdminAc = sm.createAccount(); + + Executable action = () -> aggregator.invoke(normalAc, "setAdmin", newAdminAc.getAddress()); + UserRevertedException e = assertThrows(UserRevertedException.class, action); + + assertEquals("Reverted(0): Unauthorized: caller is not the admin", e.getMessage()); + } + + @Test + public void testSetSignatureThreshold() { + int threshold = 3; + aggregator.invoke(adminAc, "setSignatureThreshold", threshold); + + Integer result = (Integer) aggregator.call("getSignatureThreshold"); + assertEquals(threshold, result); + } + + @Test + public void testSetSignatureThreshold_unauthorised() { + int threshold = 3; + + Executable action = () -> aggregator.invoke(relayerOneAc, + "setSignatureThreshold", threshold); + UserRevertedException e = assertThrows(UserRevertedException.class, action); + + assertEquals("Reverted(0): Unauthorized: caller is not the admin", + e.getMessage()); + } + + @Test + public void testSetRelayers() { + Account relayerFiveAc = sm.createAccount(); + Address[] newRelayers = new Address[] { relayerThreeAc.getAddress(), relayerFourAc.getAddress(), + relayerFiveAc.getAddress() }; + + Integer threshold = 3; + aggregator.invoke(adminAc, "setRelayers", (Object) newRelayers, threshold); + + Address[] updatedRelayers = (Address[]) aggregator.call("getRelayers"); - @Test - public void testSetAdmin() { - Address oldAdmin = (Address) aggregator.call("getAdmin"); + Address[] expectedRelayers = new Address[] { relayerThreeAc.getAddress(), + relayerFourAc.getAddress(), + relayerFiveAc.getAddress() }; - Account newAdminAc = sm.createAccount(); - aggregator.invoke(adminAc, "setAdmin", newAdminAc.getAddress()); + HashSet
updatedRelayersSet = new HashSet
(); + for (Address rlr : updatedRelayers) { + updatedRelayersSet.add(rlr); + } - Address newAdmin = (Address) aggregator.call("getAdmin"); - assertEquals(newAdminAc.getAddress(), newAdmin); + HashSet
expectedRelayersSet = new HashSet
(); + for (Address rlr : expectedRelayers) { + expectedRelayersSet.add(rlr); + } + + assertEquals(expectedRelayersSet, updatedRelayersSet); + + Integer result = (Integer) aggregator.call("getSignatureThreshold"); + assertEquals(threshold, result); + } - Address[] relayers = (Address[]) aggregator.call("getRelayers"); + @Test + public void testSetRelayers_unauthorized() { + Account relayerFiveAc = sm.createAccount(); + Address[] newRelayers = new Address[] { relayerThreeAc.getAddress(), relayerFourAc.getAddress(), + relayerFiveAc.getAddress() }; - boolean containsNewAdmin = Arrays.asList(relayers).contains(newAdmin); - boolean containsOldAdmin = Arrays.asList(relayers).contains(oldAdmin); + Integer threshold = 3; + Executable action = () -> aggregator.invoke(relayerOneAc, "setRelayers", + (Object) newRelayers, threshold); + UserRevertedException e = assertThrows(UserRevertedException.class, action); - assertTrue(containsNewAdmin); - assertFalse(containsOldAdmin); - } + assertEquals("Reverted(0): Unauthorized: caller is not the admin", + e.getMessage()); - @Test - public void testSetAdmin_unauthorized() { - Account normalAc = sm.createAccount(); - Account newAdminAc = sm.createAccount(); + } - Executable action = () -> aggregator.invoke(normalAc, "setAdmin", newAdminAc.getAddress()); - UserRevertedException e = assertThrows(UserRevertedException.class, action); + @Test + public void testSetRelayers_invalidThreshold() { + Account relayerFiveAc = sm.createAccount(); + Address[] newRelayers = new Address[] { relayerThreeAc.getAddress(), relayerFourAc.getAddress(), + relayerFiveAc.getAddress() }; - assertEquals("Reverted(0): Unauthorized: caller is not the leader relayer", e.getMessage()); - } + Integer threshold = 5; + Executable action = () -> aggregator.invoke(adminAc, "setRelayers", + (Object) newRelayers, threshold); + UserRevertedException e = assertThrows(UserRevertedException.class, action); - @Test - public void testSetSignatureThreshold() { - int threshold = 3; - aggregator.invoke(adminAc, "setSignatureThreshold", threshold); + assertEquals("Reverted(0): threshold value should be at least 1 and not greater than relayers size", + e.getMessage()); - Integer result = (Integer) aggregator.call("getSignatureThreshold"); - assertEquals(threshold, result); - } + } - @Test - public void testSetSignatureThreshold_unauthorised() { - int threshold = 3; + @Test + public void testSetRelayers_invalidThresholdZero() { + Account relayerFiveAc = sm.createAccount(); + Address[] newRelayers = new Address[] { relayerThreeAc.getAddress(), relayerFourAc.getAddress(), + relayerFiveAc.getAddress() }; - Executable action = () -> aggregator.invoke(relayerOneAc, - "setSignatureThreshold", threshold); - UserRevertedException e = assertThrows(UserRevertedException.class, action); + Integer threshold = 0; + Executable action = () -> aggregator.invoke(adminAc, "setRelayers", + (Object) newRelayers, threshold); + UserRevertedException e = assertThrows(UserRevertedException.class, action); - assertEquals("Reverted(0): Unauthorized: caller is not the leader relayer", - e.getMessage()); - } + assertEquals("Reverted(0): threshold value should be at least 1 and not greater than relayers size", + e.getMessage()); - @Test - public void testSetRelayers() { - Account relayerFiveAc = sm.createAccount(); - Address[] newRelayers = new Address[] { relayerThreeAc.getAddress(), relayerFourAc.getAddress(), - relayerFiveAc.getAddress() }; + } - Integer threshold = 3; - aggregator.invoke(adminAc, "setRelayers", (Object) newRelayers, threshold); + @Test + public void testPacketSubmitted_true() throws Exception { + String srcNetwork = "0x2.icon"; + String dstNetwork = "sui"; + BigInteger srcSn = BigInteger.ONE; + BigInteger srcHeight = BigInteger.ONE; + String srcContractAddress = "hxjuiod"; + String dstContractAddress = "hxjuiod"; + byte[] data = new byte[] { 0x01, 0x02 }; + + aggregator.invoke(adminAc, "setSignatureThreshold", 2); + + byte[] dataHash = Context.hash("sha-256", data); + byte[] sign = relayerOne.sign(dataHash); + + aggregator.invoke(relayerOneAc, "submitPacket", srcNetwork, + srcContractAddress, srcSn, srcHeight, dstNetwork, + dstContractAddress, data, + sign); + + boolean submitted = (boolean) aggregator.call("packetSubmitted", + relayerOneAc.getAddress(), srcNetwork, + srcContractAddress, srcSn, srcHeight, dstNetwork, dstContractAddress, data); + assertEquals(submitted, true); + } - Address[] updatedRelayers = (Address[]) aggregator.call("getRelayers"); + @Test + public void testPacketSubmitted_false() throws Exception { + String srcNetwork = "0x2.icon"; + String dstNetwork = "sui"; + BigInteger srcSn = BigInteger.ONE; + BigInteger srcHeight = BigInteger.ONE; + String srcContractAddress = "hxjuiod"; + String dstContractAddress = "hxjuiod"; + byte[] data = new byte[] { 0x01, 0x02 }; + + boolean submitted = (boolean) aggregator.call("packetSubmitted", + relayerOneAc.getAddress(), srcNetwork, + srcContractAddress, srcSn, srcHeight, dstNetwork, dstContractAddress, data); + assertEquals(submitted, false); + } - Address[] expectedRelayers = new Address[] { adminAc.getAddress(), relayerThreeAc.getAddress(), - relayerFourAc.getAddress(), - relayerFiveAc.getAddress() }; + @Test + public void testSubmitPacket() throws Exception { + String srcNetwork = "0x2.icon"; + String dstNetwork = "sui"; + BigInteger srcSn = BigInteger.ONE; + BigInteger srcHeight = BigInteger.ONE; + String srcContractAddress = "hxjuiod"; + String dstContractAddress = "hxjuiod"; + byte[] data = new byte[] { 0x01, 0x02 }; + + aggregator.invoke(adminAc, "setSignatureThreshold", 2); + + byte[] dataHash = Context.hash("sha-256", data); + byte[] sign = relayerOne.sign(dataHash); + + aggregator.invoke(relayerOneAc, "submitPacket", srcNetwork, + srcContractAddress, srcSn, srcHeight, dstNetwork, + dstContractAddress, data, + sign); + + 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); + } - HashSet
updatedRelayersSet = new HashSet
(); - for (Address rlr : updatedRelayers) { - updatedRelayersSet.add(rlr); + @Test + public void testSubmitPacket_thresholdReached() throws Exception { + String srcNetwork = "0x2.icon"; + String dstNetwork = "sui"; + BigInteger srcSn = BigInteger.ONE; + BigInteger srcHeight = BigInteger.ONE; + String srcContractAddress = "hxjuiod"; + String dstContractAddress = "hxjuiod"; + byte[] data = new byte[] { 0x01, 0x02 }; + + aggregator.invoke(adminAc, "setSignatureThreshold", 2); + + byte[] dataHash = Context.hash("sha-256", data); + + 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, + encodedSigs); } - HashSet
expectedRelayersSet = new HashSet
(); - for (Address rlr : expectedRelayers) { - expectedRelayersSet.add(rlr); + @Test + public void testSubmitPacket_unauthorized() throws Exception { + String srcNetwork = "0x2.icon"; + String dstNetwork = "sui"; + BigInteger srcSn = BigInteger.ONE; + BigInteger srcHeight = BigInteger.ONE; + String srcContractAddress = "hxjuiod"; + String dstContractAddress = "hxjuiod"; + byte[] data = new byte[] { 0x01, 0x02 }; + + byte[] dataHash = Context.hash("sha-256", data); + byte[] sign = relayerFour.sign(dataHash); + + Executable action = () -> aggregator.invoke(relayerFourAc, "submitPacket", + srcNetwork, srcContractAddress, + srcSn, + srcHeight, dstNetwork, dstContractAddress, data, sign); + + UserRevertedException e = assertThrows(UserRevertedException.class, action); + assertEquals("Reverted(0): Unauthorized: caller is not a registered relayer", + e.getMessage()); } - assertEquals(expectedRelayersSet, updatedRelayersSet); - - Integer result = (Integer) aggregator.call("getSignatureThreshold"); - assertEquals(threshold, result); - } - - @Test - public void testSetRelayers_unauthorized() { - Account relayerFiveAc = sm.createAccount(); - Address[] newRelayers = new Address[] { relayerThreeAc.getAddress(), relayerFourAc.getAddress(), - relayerFiveAc.getAddress() }; - - Integer threshold = 3; - Executable action = () -> aggregator.invoke(relayerOneAc, "setRelayers", - (Object) newRelayers, threshold); - UserRevertedException e = assertThrows(UserRevertedException.class, action); - - assertEquals("Reverted(0): Unauthorized: caller is not the leader relayer", - e.getMessage()); - - } - - @Test - public void testSetRelayers_invalidThreshold() { - Account relayerFiveAc = sm.createAccount(); - Address[] newRelayers = new Address[] { relayerThreeAc.getAddress(), relayerFourAc.getAddress(), - relayerFiveAc.getAddress() }; - - Integer threshold = 5; - Executable action = () -> aggregator.invoke(adminAc, "setRelayers", - (Object) newRelayers, threshold); - UserRevertedException e = assertThrows(UserRevertedException.class, action); - - assertEquals("Reverted(0): threshold value should be at least 1 and not greater than relayers size", - e.getMessage()); - - } - - @Test - public void testSetRelayers_invalidThresholdZero() { - Account relayerFiveAc = sm.createAccount(); - Address[] newRelayers = new Address[] { relayerThreeAc.getAddress(), relayerFourAc.getAddress(), - relayerFiveAc.getAddress() }; - - Integer threshold = 0; - Executable action = () -> aggregator.invoke(adminAc, "setRelayers", - (Object) newRelayers, threshold); - UserRevertedException e = assertThrows(UserRevertedException.class, action); - - assertEquals("Reverted(0): threshold value should be at least 1 and not greater than relayers size", - e.getMessage()); - - } - - @Test - public void testPacketSubmitted_true() throws Exception { - String srcNetwork = "0x2.icon"; - String dstNetwork = "sui"; - BigInteger srcSn = BigInteger.ONE; - BigInteger srcHeight = BigInteger.ONE; - String srcContractAddress = "hxjuiod"; - String dstContractAddress = "hxjuiod"; - byte[] data = new byte[] { 0x01, 0x02 }; - - aggregator.invoke(adminAc, "setSignatureThreshold", 2); - - byte[] dataHash = Context.hash("sha-256", data); - byte[] sign = relayerOne.sign(dataHash); - - aggregator.invoke(relayerOneAc, "submitPacket", srcNetwork, - srcContractAddress, srcSn, srcHeight, dstNetwork, - dstContractAddress, data, - sign); - - boolean submitted = (boolean) aggregator.call("packetSubmitted", - relayerOneAc.getAddress(), srcNetwork, - srcContractAddress, srcSn); - assertEquals(submitted, true); - } - - @Test - public void testPacketSubmitted_false() throws Exception { - String srcNetwork = "0x2.icon"; - BigInteger srcSn = BigInteger.ONE; - String srcContractAddress = "hxjuiod"; - - boolean submitted = (boolean) aggregator.call("packetSubmitted", - relayerOneAc.getAddress(), srcNetwork, - srcContractAddress, srcSn); - assertEquals(submitted, false); - } - - @Test - public void testSubmitPacket() throws Exception { - String srcNetwork = "0x2.icon"; - String dstNetwork = "sui"; - BigInteger srcSn = BigInteger.ONE; - BigInteger srcHeight = BigInteger.ONE; - String srcContractAddress = "hxjuiod"; - String dstContractAddress = "hxjuiod"; - byte[] data = new byte[] { 0x01, 0x02 }; - - aggregator.invoke(adminAc, "setSignatureThreshold", 2); - - byte[] dataHash = Context.hash("sha-256", data); - byte[] sign = relayerOne.sign(dataHash); - - aggregator.invoke(relayerOneAc, "submitPacket", srcNetwork, - srcContractAddress, srcSn, srcHeight, dstNetwork, - dstContractAddress, data, - sign); - - String pktID = Packet.createId(srcNetwork, srcContractAddress, srcSn); - verify(aggregatorSpy).PacketRegistered(srcNetwork, srcContractAddress, srcSn, - srcHeight, dstNetwork, - dstContractAddress, data); - verify(aggregatorSpy).setSignature(pktID, relayerOneAc.getAddress(), sign); - } - - @Test - public void testSubmitPacket_thresholdReached() throws Exception { - String srcNetwork = "0x2.icon"; - String dstNetwork = "sui"; - BigInteger srcSn = BigInteger.ONE; - BigInteger srcHeight = BigInteger.ONE; - String srcContractAddress = "hxjuiod"; - String dstContractAddress = "hxjuiod"; - byte[] data = new byte[] { 0x01, 0x02 }; - - aggregator.invoke(adminAc, "setSignatureThreshold", 2); - - byte[] dataHash = Context.hash("sha-256", data); - - byte[] signAdmin = admin.sign(dataHash); - aggregator.invoke(adminAc, "submitPacket", srcNetwork, srcContractAddress, - srcSn, srcHeight, dstNetwork, - dstContractAddress, data, - signAdmin); - - byte[] signOne = relayerOne.sign(dataHash); - aggregator.invoke(relayerOneAc, "submitPacket", srcNetwork, - srcContractAddress, srcSn, srcHeight, dstNetwork, - dstContractAddress, - data, - signOne); - - byte[][] sigs = new byte[2][]; - sigs[0] = signAdmin; - sigs[1] = signOne; - - byte[] encodedSigs = RelayAggregator.serializeSignatures(sigs); - byte[][] decodedSigs = RelayAggregator.deserializeSignatures(encodedSigs); - - assertArrayEquals(signAdmin, decodedSigs[0]); - assertArrayEquals(signOne, decodedSigs[1]); - - verify(aggregatorSpy).PacketAcknowledged(srcNetwork, srcContractAddress, - srcSn, srcHeight, dstNetwork, - dstContractAddress, data, - encodedSigs); - } - - @Test - public void testSubmitPacket_unauthorized() throws Exception { - String srcNetwork = "0x2.icon"; - String dstNetwork = "sui"; - BigInteger srcSn = BigInteger.ONE; - BigInteger srcHeight = BigInteger.ONE; - String srcContractAddress = "hxjuiod"; - String dstContractAddress = "hxjuiod"; - byte[] data = new byte[] { 0x01, 0x02 }; - - byte[] dataHash = Context.hash("sha-256", data); - byte[] sign = relayerFour.sign(dataHash); - - Executable action = () -> aggregator.invoke(relayerFourAc, "submitPacket", - srcNetwork, srcContractAddress, - srcSn, - srcHeight, dstNetwork, dstContractAddress, data, sign); - - UserRevertedException e = assertThrows(UserRevertedException.class, action); - assertEquals("Reverted(0): Unauthorized: caller is not a registered relayer", - e.getMessage()); - } - - @Test - public void testSubmitPacket_duplicate() throws Exception { - String srcNetwork = "0x2.icon"; - String dstNetwork = "sui"; - BigInteger srcSn = BigInteger.ONE; - BigInteger srcHeight = BigInteger.ONE; - String srcContractAddress = "hxjuiod"; - String dstContractAddress = "hxjuiod"; - byte[] data = new byte[] { 0x01, 0x02 }; - - aggregator.invoke(adminAc, "setSignatureThreshold", 2); - - byte[] dataHash = Context.hash("sha-256", data); - byte[] sign = relayerOne.sign(dataHash); - - aggregator.invoke(relayerOneAc, "submitPacket", srcNetwork, - srcContractAddress, srcSn, srcHeight, dstNetwork, - dstContractAddress, data, sign); - - Executable action = () -> aggregator.invoke(relayerOneAc, "submitPacket", - srcNetwork, srcContractAddress, srcSn, - srcHeight, dstNetwork, dstContractAddress, - data, sign); - ; - UserRevertedException e = assertThrows(UserRevertedException.class, action); - assertEquals("Reverted(0): Signature already exists", e.getMessage()); - } + @Test + public void testSubmitPacket_duplicate() throws Exception { + String srcNetwork = "0x2.icon"; + String dstNetwork = "sui"; + BigInteger srcSn = BigInteger.ONE; + BigInteger srcHeight = BigInteger.ONE; + String srcContractAddress = "hxjuiod"; + String dstContractAddress = "hxjuiod"; + byte[] data = new byte[] { 0x01, 0x02 }; + + aggregator.invoke(adminAc, "setSignatureThreshold", 2); + + byte[] dataHash = Context.hash("sha-256", data); + byte[] sign = relayerOne.sign(dataHash); + + aggregator.invoke(relayerOneAc, "submitPacket", srcNetwork, + srcContractAddress, srcSn, srcHeight, dstNetwork, + dstContractAddress, data, sign); + + Executable action = () -> aggregator.invoke(relayerOneAc, "submitPacket", + srcNetwork, srcContractAddress, srcSn, + srcHeight, dstNetwork, dstContractAddress, + data, sign); + ; + UserRevertedException e = assertThrows(UserRevertedException.class, action); + assertEquals("Reverted(0): Signature already exists", e.getMessage()); + } } diff --git a/contracts/soroban/libs/soroban-rlp/src/decoder.rs b/contracts/soroban/libs/soroban-rlp/src/decoder.rs index 37b83405..9d05760d 100644 --- a/contracts/soroban/libs/soroban-rlp/src/decoder.rs +++ b/contracts/soroban/libs/soroban-rlp/src/decoder.rs @@ -131,6 +131,9 @@ pub fn decode_u64(env: &Env, bytes: Bytes) -> u64 { } pub fn decode_u128(env: &Env, bytes: Bytes) -> u128 { + if bytes.len() == 1 { + return bytes_to_u128(bytes); + } let decoded = decode(&env, bytes); bytes_to_u128(decoded) } diff --git a/contracts/soroban/libs/soroban-rlp/src/utils.rs b/contracts/soroban/libs/soroban-rlp/src/utils.rs index b359078c..403cac52 100644 --- a/contracts/soroban/libs/soroban-rlp/src/utils.rs +++ b/contracts/soroban/libs/soroban-rlp/src/utils.rs @@ -53,7 +53,7 @@ pub fn bytes_to_u64(bytes: Bytes) -> u64 { } pub fn u128_to_bytes(env: &Env, number: u128) -> Bytes { - let mut bytes: Bytes = Bytes::new(&env); + let mut bytes = bytes!(&env, 0x00); let mut i = 15; let mut leading_zero = true; while i >= 0 {