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 0568de377..16d600cf7 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 ec475a999..440b8c199 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 0da3391f4..4165d4e66 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/javascore/settings.gradle b/contracts/javascore/settings.gradle
index bfa809806..4f1da5a87 100644
--- a/contracts/javascore/settings.gradle
+++ b/contracts/javascore/settings.gradle
@@ -4,7 +4,7 @@ include(
'xcall',
'xcall-lib',
'centralized-connection',
- 'cluster-connection'
+ 'cluster-connection',
'aggregator'
)
diff --git a/contracts/soroban/Cargo.lock b/contracts/soroban/Cargo.lock
index fbf3411ee..3b10ba1fd 100644
--- a/contracts/soroban/Cargo.lock
+++ b/contracts/soroban/Cargo.lock
@@ -159,6 +159,7 @@ version = "0.0.0"
dependencies = [
"soroban-rlp",
"soroban-sdk",
+ "soroban-xcall-lib",
]
[[package]]
diff --git a/contracts/soroban/contracts/cluster-connection/Cargo.toml b/contracts/soroban/contracts/cluster-connection/Cargo.toml
index e6f6b4820..8166e5e4f 100644
--- a/contracts/soroban/contracts/cluster-connection/Cargo.toml
+++ b/contracts/soroban/contracts/cluster-connection/Cargo.toml
@@ -10,7 +10,7 @@ doctest = false
[dependencies]
soroban-sdk = { workspace = true, features = ["alloc"] }
-soroban-rlp = { path = "../../libs/soroban-rlp" }
+soroban-xcall-lib = { path = "../../libs/soroban-xcall-lib" }
[dev-dependencies]
soroban-sdk = { workspace = true, features = ["testutils"] }
diff --git a/contracts/soroban/contracts/cluster-connection/src/helpers.rs b/contracts/soroban/contracts/cluster-connection/src/helpers.rs
index f37ed14fb..d7343698f 100644
--- a/contracts/soroban/contracts/cluster-connection/src/helpers.rs
+++ b/contracts/soroban/contracts/cluster-connection/src/helpers.rs
@@ -1,6 +1,6 @@
-use soroban_sdk::{token, vec, Address, Bytes, BytesN, Env, Map, String, Vec};
+use soroban_sdk::{token, xdr::ToXdr, Address, Bytes, BytesN, Env, Map, String, Vec};
use crate::{errors::ContractError, interfaces::interface_xcall::XcallClient, storage};
-use soroban_rlp::encoder;
+use soroban_xcall_lib::network_address::NetworkAddress;
pub fn ensure_relayer(e: &Env) -> Result {
let relayer = storage::relayer(&e)?;
@@ -63,13 +63,14 @@ pub fn verify_signatures(
conn_sn: &u128,
message: &Bytes,
) -> bool {
+ let dst_network = get_network_id(e);
let validators = storage::get_validators(e).unwrap();
let threshold = storage::get_validators_threshold(e).unwrap();
if signatures.len() < threshold {
return false
}
- let message_hash = e.crypto().keccak256(&get_encoded_message(e, src_network, conn_sn, message));
+ let message_hash = e.crypto().keccak256(&get_encoded_message(e, src_network, conn_sn, message, &dst_network));
let mut unique_validators = Map::new(e);
let mut count = 0;
@@ -98,13 +99,58 @@ pub fn verify_signatures(
}
-pub fn get_encoded_message(e: &Env, src_network: &String, conn_sn: &u128, message: &Bytes) -> Bytes {
- let mut list = vec![&e];
- list.push_back(encoder::encode_string(&e, src_network.clone()));
- list.push_back(encoder::encode_u128(&e, conn_sn.clone()));
- list.push_back(encoder::encode(&e, message.clone()));
+pub fn string_to_bytes(env: &Env, value: String) -> Bytes {
+ let string_xdr = value.clone().to_xdr(&env);
+ let mut bytes = Bytes::new(&env);
+ for i in 8..(8 + value.len()) {
+ if let Some(byte) = string_xdr.get(i) {
+ bytes.push_back(byte);
+ }
+ }
+ bytes
+}
+
+pub fn get_encoded_message(e: &Env, src_network: &String, conn_sn: &u128, message: &Bytes, dst_network: &String) -> Bytes {
+ let mut encoded = Bytes::new(e);
+ encoded.append(&string_to_bytes(e, src_network.clone()));
+ encoded.append(&u128_to_string(e, *conn_sn));
+ encoded.append(message);
+ encoded.append(&string_to_bytes(e, dst_network.clone()));
+ encoded
+}
- encoder::encode_list(&e, list, false)
+pub fn u128_to_string(env: &Env, value: u128) -> Bytes {
+ let mut num = value;
+ let mut temp_bytes = Bytes::new(&env);
+ let mut bytes = Bytes::new(&env);
+
+ if value == 0 {
+ temp_bytes.push_back(b'0');
+ return temp_bytes;
+ }
+ while num > 0 {
+ let digit = (num % 10) as u8 + b'0';
+ temp_bytes.push_back(digit);
+ num /= 10;
+ }
+ for byte in temp_bytes.iter().rev() {
+ bytes.push_back(byte);
+ }
+ bytes
+}
+
+#[cfg(not(test))]
+pub fn get_network_id(e: &Env) -> String {
+ let xcall_addr = storage::get_xcall(&e).unwrap();
+ let client = XcallClient::new(&e, &xcall_addr);
+ let network_address = NetworkAddress::from_string(client.get_network_address());
+ network_address.nid(&e)
+}
+
+#[cfg(test)]
+pub fn get_network_id(e: &Env) -> String {
+ let network_address = NetworkAddress::from_string(String::from_str(e, "archway/testnet"));
+ network_address.nid(&e)
}
#[cfg(not(test))]
@@ -130,3 +176,15 @@ pub fn call_xcall_handle_error(e: &Env, sn: u128) -> Result<(), ContractError> {
Ok(())
}
+
+#[test]
+fn verify_encoded_message() {
+ use soroban_sdk::bytes;
+ let env = Env::default();
+ let src_network = String::from_str(&env, "0x2.icon");
+ let conn_sn = 128;
+ let message = bytes!(&env, 0x68656c6c6f);
+ let dst_network = String::from_str(&env, "archway");
+ let encoded = get_encoded_message(&env, &src_network, &conn_sn, &message, &dst_network);
+ assert_eq!(encoded, bytes!(&env,0x3078322e69636f6e31323868656c6c6f61726368776179));
+}
\ No newline at end of file
diff --git a/contracts/soroban/contracts/cluster-connection/src/interfaces/interface_xcall.rs b/contracts/soroban/contracts/cluster-connection/src/interfaces/interface_xcall.rs
index c49d6c9c7..12ed8edb1 100644
--- a/contracts/soroban/contracts/cluster-connection/src/interfaces/interface_xcall.rs
+++ b/contracts/soroban/contracts/cluster-connection/src/interfaces/interface_xcall.rs
@@ -12,4 +12,6 @@ pub trait IXcall {
) -> Result<(), ContractError>;
fn handle_error(env: Env, sender: Address, sequence_no: u128) -> Result<(), ContractError>;
+
+ fn get_network_address(env: Env) -> Result;
}
diff --git a/contracts/soroban/contracts/cluster-connection/src/test.rs b/contracts/soroban/contracts/cluster-connection/src/test.rs
index fe375ba57..6b0cec874 100644
--- a/contracts/soroban/contracts/cluster-connection/src/test.rs
+++ b/contracts/soroban/contracts/cluster-connection/src/test.rs
@@ -13,7 +13,7 @@ use crate::{
types::InitializeMsg,
};
use soroban_sdk::{
- symbol_short, testutils::{Address as _, AuthorizedFunction, AuthorizedInvocation, Events}, token, vec, Address, Bytes, BytesN, Env, IntoVal, String, Symbol, Vec
+ bytesn, symbol_short, testutils::{Address as _, AuthorizedFunction, AuthorizedInvocation, Events}, token, vec, Address, Bytes, BytesN, Env, IntoVal, String, Symbol, Vec
};
pub struct TestContext {
@@ -356,14 +356,16 @@ fn test_add_validator() {
ctx.init_context(&client);
- let val1 = [4, 174, 54, 168, 191, 216, 207, 101, 134, 243, 76, 104, 133, 40, 137, 72, 53, 245, 231, 193, 157, 54, 104, 155, 172, 84, 96, 101, 107, 97, 60, 94, 171, 241, 250, 152, 34, 18, 170, 39, 202, 236, 226, 58, 39, 8, 235, 60, 137, 54, 225, 50, 185, 253, 130, 197, 174, 226, 170, 75, 6, 145, 123, 87, 19];
- let val2 = [4, 91, 65, 155, 222, 192, 210, 187, 193, 108, 232, 174, 20, 79, 248, 232, 37, 18, 63, 208, 203, 62, 54, 208, 7, 91, 109, 141, 229, 170, 181, 51, 136, 172, 143, 180, 194, 138, 138, 56, 67, 243, 7, 60, 218, 164, 12, 148, 63, 116, 115, 127, 192, 206, 164, 169, 95, 135, 119, 138, 255, 172, 115, 129, 144];
- let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55];
+ let val1 = bytesn!(&ctx.env, 0x04deca512d5cb87673b23ab10c3e3572e30a2b5dc78cd500bf84bf066275c0bb320cb6cd266aa179b41323b5a18ab4a170248ed89b436b5559bab38c816ce12209);
+ let val2 = bytesn!(&ctx.env, 0x04f9379b2955d759a9532f8daa0c4a25da0ae706dd057de02af7754adb4b956ec9b8bf7a8a5a6686bc74dff736442a874c6bae5dcbcdb7113e24fbfa2337c63a01);
+ let val3 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f);
+ let val4 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f);
let mut validators = Vec::new(&ctx.env);
- validators.push_back(BytesN::from_array(&ctx.env, &val1));
- validators.push_back(BytesN::from_array(&ctx.env, &val2));
- validators.push_back(BytesN::from_array(&ctx.env, &val3));
+ validators.push_back(val1);
+ validators.push_back(val2);
+ validators.push_back(val3);
+ validators.push_back(val4);
client.update_validators(&validators, &3_u32);
assert_eq!(
@@ -395,14 +397,16 @@ fn test_set_threshold() {
ctx.init_context(&client);
- let val1 = [4, 174, 54, 168, 191, 216, 207, 101, 134, 243, 76, 104, 133, 40, 137, 72, 53, 245, 231, 193, 157, 54, 104, 155, 172, 84, 96, 101, 107, 97, 60, 94, 171, 241, 250, 152, 34, 18, 170, 39, 202, 236, 226, 58, 39, 8, 235, 60, 137, 54, 225, 50, 185, 253, 130, 197, 174, 226, 170, 75, 6, 145, 123, 87, 19];
- let val2 = [4, 91, 65, 155, 222, 192, 210, 187, 193, 108, 232, 174, 20, 79, 248, 232, 37, 18, 63, 208, 203, 62, 54, 208, 7, 91, 109, 141, 229, 170, 181, 51, 136, 172, 143, 180, 194, 138, 138, 56, 67, 243, 7, 60, 218, 164, 12, 148, 63, 116, 115, 127, 192, 206, 164, 169, 95, 135, 119, 138, 255, 172, 115, 129, 144];
- let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55];
+ let val1 = bytesn!(&ctx.env, 0x04deca512d5cb87673b23ab10c3e3572e30a2b5dc78cd500bf84bf066275c0bb320cb6cd266aa179b41323b5a18ab4a170248ed89b436b5559bab38c816ce12209);
+ let val2 = bytesn!(&ctx.env, 0x04f9379b2955d759a9532f8daa0c4a25da0ae706dd057de02af7754adb4b956ec9b8bf7a8a5a6686bc74dff736442a874c6bae5dcbcdb7113e24fbfa2337c63a01);
+ let val3 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f);
+ let val4 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f);
let mut validators = Vec::new(&ctx.env);
- validators.push_back(BytesN::from_array(&ctx.env, &val1));
- validators.push_back(BytesN::from_array(&ctx.env, &val2));
- validators.push_back(BytesN::from_array(&ctx.env, &val3));
+ validators.push_back(val1);
+ validators.push_back(val2);
+ validators.push_back(val3);
+ validators.push_back(val4);
client.update_validators(&validators, &3_u32);
let threshold: u32 = 2_u32;
@@ -437,22 +441,25 @@ fn test_receive_message() {
ctx.init_context(&client);
- let val1 = [4, 174, 54, 168, 191, 216, 207, 101, 134, 243, 76, 104, 133, 40, 137, 72, 53, 245, 231, 193, 157, 54, 104, 155, 172, 84, 96, 101, 107, 97, 60, 94, 171, 241, 250, 152, 34, 18, 170, 39, 202, 236, 226, 58, 39, 8, 235, 60, 137, 54, 225, 50, 185, 253, 130, 197, 174, 226, 170, 75, 6, 145, 123, 87, 19];
- let val2 = [4, 91, 65, 155, 222, 192, 210, 187, 193, 108, 232, 174, 20, 79, 248, 232, 37, 18, 63, 208, 203, 62, 54, 208, 7, 91, 109, 141, 229, 170, 181, 51, 136, 172, 143, 180, 194, 138, 138, 56, 67, 243, 7, 60, 218, 164, 12, 148, 63, 116, 115, 127, 192, 206, 164, 169, 95, 135, 119, 138, 255, 172, 115, 129, 144];
- let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55];
+ let val1 = bytesn!(&ctx.env, 0x04deca512d5cb87673b23ab10c3e3572e30a2b5dc78cd500bf84bf066275c0bb320cb6cd266aa179b41323b5a18ab4a170248ed89b436b5559bab38c816ce12209);
+ let val2 = bytesn!(&ctx.env, 0x04f9379b2955d759a9532f8daa0c4a25da0ae706dd057de02af7754adb4b956ec9b8bf7a8a5a6686bc74dff736442a874c6bae5dcbcdb7113e24fbfa2337c63a01);
+ let val3 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f);
+ let val4 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f);
let mut validators = Vec::new(&ctx.env);
- validators.push_back(BytesN::from_array(&ctx.env, &val1));
- validators.push_back(BytesN::from_array(&ctx.env, &val2));
- validators.push_back(BytesN::from_array(&ctx.env, &val3));
- client.update_validators(&validators, &1_u32);
+ validators.push_back(val1);
+ validators.push_back(val2);
+ validators.push_back(val3);
+ validators.push_back(val4);
+ client.update_validators(&validators, &2_u32);
- let conn_sn = 456456_u128;
+ let conn_sn = 128_u128;
let msg = Bytes::from_array(&ctx.env,&[104, 101, 108, 108, 111]);
let src_network = String::from_str(&ctx.env, "0x2.icon");
let mut signatures = Vec::new(&ctx.env);
- signatures.push_back(BytesN::from_array(&ctx.env, &[35, 247, 49, 199, 251, 53, 83, 51, 115, 148, 35, 48, 85, 203, 185, 236, 5, 171, 221, 29, 247, 203, 190, 195, 208, 218, 204, 237, 88, 191, 91, 75, 48, 87, 108, 161, 75, 234, 147, 234, 65, 134, 233, 32, 249, 159, 43, 159, 86, 211, 1, 117, 176, 167, 53, 99, 34, 243, 165, 215, 93, 232, 67, 184, 27]));
+ signatures.push_back(bytesn!(&ctx.env, 0x660d542b3f6de9cd08f238fd44133eeebfea290b21dae7322a63b516c57b8df12c4c0a340b60ed567c8da53578346c212b27b797eb42a75fb4b7076c567a6ff91c));
+ signatures.push_back(bytesn!(&ctx.env, 0x8024de4c7b003df96bb699cfaa1bfb8a682787cd0853f555d48494c65c766f8104804848095890a9a6d15946da52dafb18e5c1d0dbe7f33fc7a5fa5cf8b1f6e21c));
client.recv_message_with_signatures(&src_network, &conn_sn, &msg, &signatures);
}
@@ -465,22 +472,24 @@ fn test_receive_message_less_signatures() {
ctx.init_context(&client);
- let val1 = [4, 174, 54, 168, 191, 216, 207, 101, 134, 243, 76, 104, 133, 40, 137, 72, 53, 245, 231, 193, 157, 54, 104, 155, 172, 84, 96, 101, 107, 97, 60, 94, 171, 241, 250, 152, 34, 18, 170, 39, 202, 236, 226, 58, 39, 8, 235, 60, 137, 54, 225, 50, 185, 253, 130, 197, 174, 226, 170, 75, 6, 145, 123, 87, 19];
- let val2 = [4, 91, 65, 155, 222, 192, 210, 187, 193, 108, 232, 174, 20, 79, 248, 232, 37, 18, 63, 208, 203, 62, 54, 208, 7, 91, 109, 141, 229, 170, 181, 51, 136, 172, 143, 180, 194, 138, 138, 56, 67, 243, 7, 60, 218, 164, 12, 148, 63, 116, 115, 127, 192, 206, 164, 169, 95, 135, 119, 138, 255, 172, 115, 129, 144];
- let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55];
+ let val1 = bytesn!(&ctx.env, 0x04deca512d5cb87673b23ab10c3e3572e30a2b5dc78cd500bf84bf066275c0bb320cb6cd266aa179b41323b5a18ab4a170248ed89b436b5559bab38c816ce12209);
+ let val2 = bytesn!(&ctx.env, 0x04f9379b2955d759a9532f8daa0c4a25da0ae706dd057de02af7754adb4b956ec9b8bf7a8a5a6686bc74dff736442a874c6bae5dcbcdb7113e24fbfa2337c63a01);
+ let val3 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f);
+ let val4 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f);
let mut validators = Vec::new(&ctx.env);
- validators.push_back(BytesN::from_array(&ctx.env, &val1));
- validators.push_back(BytesN::from_array(&ctx.env, &val2));
- validators.push_back(BytesN::from_array(&ctx.env, &val3));
+ validators.push_back(val1);
+ validators.push_back(val2);
+ validators.push_back(val3);
+ validators.push_back(val4);
client.update_validators(&validators, &2_u32);
- let conn_sn = 456456_u128;
+ let conn_sn = 128_u128;
let msg = Bytes::from_array(&ctx.env,&[104, 101, 108, 108, 111]);
let src_network = String::from_str(&ctx.env, "0x2.icon");
let mut signatures = Vec::new(&ctx.env);
- signatures.push_back(BytesN::from_array(&ctx.env, &[35, 247, 49, 199, 251, 53, 83, 51, 115, 148, 35, 48, 85, 203, 185, 236, 5, 171, 221, 29, 247, 203, 190, 195, 208, 218, 204, 237, 88, 191, 91, 75, 48, 87, 108, 161, 75, 234, 147, 234, 65, 134, 233, 32, 249, 159, 43, 159, 86, 211, 1, 117, 176, 167, 53, 99, 34, 243, 165, 215, 93, 232, 67, 184, 27]));
+ signatures.push_back(bytesn!(&ctx.env, 0x660d542b3f6de9cd08f238fd44133eeebfea290b21dae7322a63b516c57b8df12c4c0a340b60ed567c8da53578346c212b27b797eb42a75fb4b7076c567a6ff91c));
client.recv_message_with_signatures(&src_network, &conn_sn, &msg, &signatures);
}
@@ -493,22 +502,25 @@ fn test_receive_message_with_invalid_signature() {
ctx.init_context(&client);
- let val1 = [4, 174, 54, 168, 191, 216, 207, 101, 134, 243, 76, 104, 133, 40, 137, 72, 53, 245, 231, 193, 157, 54, 104, 155, 172, 84, 96, 101, 107, 97, 60, 94, 171, 241, 250, 152, 34, 18, 170, 39, 202, 236, 226, 58, 39, 8, 235, 60, 137, 54, 225, 50, 185, 253, 130, 197, 174, 226, 170, 75, 6, 145, 123, 87, 19];
- let val2 = [4, 91, 65, 155, 222, 192, 210, 187, 193, 108, 232, 174, 20, 79, 248, 232, 37, 18, 63, 208, 203, 62, 54, 208, 7, 91, 109, 141, 229, 170, 181, 51, 136, 172, 143, 180, 194, 138, 138, 56, 67, 243, 7, 60, 218, 164, 12, 148, 63, 116, 115, 127, 192, 206, 164, 169, 95, 135, 119, 138, 255, 172, 115, 129, 144];
- let val3 = [4, 248, 192, 175, 198, 228, 250, 20, 158, 23, 251, 176, 244, 208, 150, 71, 151, 27, 208, 22, 41, 30, 154, 198, 109, 10, 112, 142, 200, 47, 200, 213, 210, 172, 135, 141, 129, 183, 211, 241, 211, 127, 16, 19, 67, 159, 195, 235, 88, 164, 223, 47, 128, 47, 147, 28, 121, 28, 93, 129, 176, 144, 52, 243, 55];
+ let val1 = bytesn!(&ctx.env, 0x04deca512d5cb87673b23ab10c3e3572e30a2b5dc78cd500bf84bf066275c0bb320cb6cd266aa179b41323b5a18ab4a170248ed89b436b5559bab38c816ce12209);
+ let val2 = bytesn!(&ctx.env, 0x04f9379b2955d759a9532f8daa0c4a25da0ae706dd057de02af7754adb4b956ec9b8bf7a8a5a6686bc74dff736442a874c6bae5dcbcdb7113e24fbfa2337c63a01);
+ let val3 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f);
+ let val4 = bytesn!(&ctx.env, 0x041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f);
let mut validators = Vec::new(&ctx.env);
- validators.push_back(BytesN::from_array(&ctx.env, &val1));
- validators.push_back(BytesN::from_array(&ctx.env, &val2));
- validators.push_back(BytesN::from_array(&ctx.env, &val3));
- client.update_validators(&validators, &1_u32);
+ validators.push_back(val1);
+ validators.push_back(val2);
+ validators.push_back(val3);
+ validators.push_back(val4);
+ client.update_validators(&validators, &2_u32);
let conn_sn = 456456_u128;
let msg = Bytes::from_array(&ctx.env,&[104, 100, 108, 108, 111]);
let src_network = String::from_str(&ctx.env, "0x2.icon");
let mut signatures = Vec::new(&ctx.env);
- signatures.push_back(BytesN::from_array(&ctx.env, &[35, 247, 49, 199, 251, 53, 83, 51, 115, 148, 35, 48, 85, 203, 185, 236, 5, 171, 221, 29, 247, 203, 190, 195, 208, 218, 204, 237, 88, 191, 91, 75, 48, 87, 108, 161, 75, 234, 147, 234, 65, 134, 233, 32, 249, 159, 43, 159, 86, 211, 1, 117, 176, 167, 53, 99, 34, 243, 165, 215, 93, 232, 67, 184, 27]));
+ signatures.push_back(bytesn!(&ctx.env, 0x660d542b3f6de9cd08f238fd44133eeebfea290b21dae7322a63b516c57b8df12c4c0a340b60ed567c8da53578346c212b27b797eb42a75fb4b7076c567a6ff91c));
+ signatures.push_back(bytesn!(&ctx.env, 0x660d542b3f6de9cd08f238fd44133eeebfea290b21dae7322a63b516c57b8df12c4c0a340b60ed567c8da53578346c212b27b797eb42a75fb4b7076c567a6ff91c));
client.recv_message_with_signatures(&src_network, &conn_sn, &msg, &signatures);
}
diff --git a/contracts/soroban/contracts/xcall/src/contract.rs b/contracts/soroban/contracts/xcall/src/contract.rs
index 8d81f6ac2..6c5affce0 100644
--- a/contracts/soroban/contracts/xcall/src/contract.rs
+++ b/contracts/soroban/contracts/xcall/src/contract.rs
@@ -162,4 +162,9 @@ impl Xcall {
pub fn version(env: Env) -> u32 {
storage::get_contract_version(&env)
}
+
+ pub fn extend_instance_storage(env: Env) -> Result<(), ContractError> {
+ storage::extend_instance(&env);
+ Ok(())
+ }
}
diff --git a/contracts/soroban/contracts/xcall/src/storage.rs b/contracts/soroban/contracts/xcall/src/storage.rs
index cfa43a988..1fb56adda 100644
--- a/contracts/soroban/contracts/xcall/src/storage.rs
+++ b/contracts/soroban/contracts/xcall/src/storage.rs
@@ -18,8 +18,8 @@ const LEDGER_BUMP_INSTANCE: u32 = LEDGER_THRESHOLD_INSTANCE + DAY_IN_LEDGERS; //
const LEDGER_THRESHOLD_PERSISTENT: u32 = DAY_IN_LEDGERS * 30; // ~ 30 days
const LEDGER_BUMP_PERSISTENT: u32 = LEDGER_THRESHOLD_PERSISTENT + DAY_IN_LEDGERS; // ~ 31 days
-const LEDGER_THRESHOLD_REQUEST: u32 = DAY_IN_LEDGERS * 7; // ~ 7 days
-const LEDGER_BUMP_REQUEST: u32 = LEDGER_THRESHOLD_REQUEST + DAY_IN_LEDGERS; // ~ 8 days
+const LEDGER_THRESHOLD_REQUEST: u32 = DAY_IN_LEDGERS * 3; // ~ 3 days
+const LEDGER_BUMP_REQUEST: u32 = LEDGER_THRESHOLD_REQUEST + DAY_IN_LEDGERS; // ~ 4 days
pub const MAX_ROLLBACK_SIZE: u64 = 1024;
pub const MAX_DATA_SIZE: u64 = 2048;
@@ -72,10 +72,9 @@ pub fn default_connection(e: &Env, nid: String) -> Result Result bool {
let key = StorageKey::SuccessfulResponses(sn);
let res = e.storage().persistent().get(&key).unwrap_or(false);
- if res {
- extend_persistent(e, &key)
- }
-
res
}
@@ -114,31 +107,21 @@ pub fn get_proxy_request(e: &Env, req_id: u128) -> Result) -> Vec {
let key = StorageKey::PendingRequests(hash);
- let pending_request = e.storage().persistent().get(&key).unwrap_or(Vec::new(&e));
- if pending_request.len() > 0 {
- extend_persistent_request(e, &key);
- }
-
+ let pending_request = e.storage().temporary().get(&key).unwrap_or(Vec::new(&e));
pending_request
}
pub fn get_pending_response(e: &Env, hash: BytesN<32>) -> Vec {
let key = StorageKey::PendingResponses(hash);
- let pending_response = e.storage().persistent().get(&key).unwrap_or(Vec::new(&e));
- if pending_response.len() > 0 {
- extend_persistent_request(e, &key);
- }
-
+ let pending_response = e.storage().temporary().get(&key).unwrap_or(Vec::new(&e));
pending_response
}
@@ -196,53 +179,52 @@ pub fn store_protocol_fee(e: &Env, fee: u128) {
pub fn store_default_connection(e: &Env, nid: String, address: &Address) {
let key = StorageKey::DefaultConnections(nid);
- e.storage().persistent().set(&key, &address);
- extend_persistent(e, &key);
+ e.storage().instance().set(&key, &address);
}
pub fn store_rollback(e: &Env, sn: u128, rollback: &Rollback) {
let key = StorageKey::Rollback(sn);
- e.storage().persistent().set(&key, rollback);
- extend_persistent_request(e, &key)
+ e.storage().temporary().set(&key, rollback);
+ extend_temporary_request(e, &key)
}
pub fn remove_rollback(e: &Env, sn: u128) {
- e.storage().persistent().remove(&StorageKey::Rollback(sn));
+ e.storage().temporary().remove(&StorageKey::Rollback(sn));
}
pub fn store_proxy_request(e: &Env, req_id: u128, request: &CSMessageRequest) {
let key = StorageKey::ProxyRequest(req_id);
- e.storage().persistent().set(&key, request);
- extend_persistent_request(e, &key)
+ e.storage().temporary().set(&key, request);
+ extend_temporary_request(e, &key)
}
pub fn remove_proxy_request(e: &Env, req_id: u128) {
e.storage()
- .persistent()
+ .temporary()
.remove(&StorageKey::ProxyRequest(req_id))
}
pub fn store_pending_request(e: &Env, hash: BytesN<32>, sources: &Vec) {
let key = StorageKey::PendingRequests(hash.clone());
- e.storage().persistent().set(&key, sources);
- extend_persistent_request(e, &key)
+ e.storage().temporary().set(&key, sources);
+ extend_temporary_request(e, &key)
}
pub fn remove_pending_request(e: &Env, hash: BytesN<32>) {
e.storage()
- .persistent()
+ .temporary()
.remove(&StorageKey::PendingRequests(hash))
}
pub fn store_pending_response(e: &Env, hash: BytesN<32>, sources: &Vec) {
let key = StorageKey::PendingResponses(hash);
- e.storage().persistent().set(&key, sources);
- extend_persistent_request(e, &key)
+ e.storage().temporary().set(&key, sources);
+ extend_temporary_request(e, &key)
}
pub fn remove_pending_response(e: &Env, hash: BytesN<32>) {
e.storage()
- .persistent()
+ .temporary()
.remove(&StorageKey::PendingResponses(hash))
}
@@ -275,8 +257,9 @@ pub fn extend_persistent(e: &Env, key: &StorageKey) {
.extend_ttl(key, LEDGER_THRESHOLD_PERSISTENT, LEDGER_BUMP_PERSISTENT);
}
-pub fn extend_persistent_request(e: &Env, key: &StorageKey) {
+pub fn extend_temporary_request(e: &Env, key: &StorageKey) {
e.storage()
- .persistent()
+ .temporary()
.extend_ttl(key, LEDGER_THRESHOLD_REQUEST, LEDGER_BUMP_REQUEST);
}
+
diff --git a/contracts/soroban/libs/soroban-rlp/src/decoder.rs b/contracts/soroban/libs/soroban-rlp/src/decoder.rs
index 37b83405b..9d05760db 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 b359078ca..403cac527 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 {
diff --git a/contracts/sui/xcall/sources/cluster_connection/cluster_entry.move b/contracts/sui/xcall/sources/cluster_connection/cluster_entry.move
index 1fab2e8f6..0b5f9d5e4 100644
--- a/contracts/sui/xcall/sources/cluster_connection/cluster_entry.move
+++ b/contracts/sui/xcall/sources/cluster_connection/cluster_entry.move
@@ -56,8 +56,9 @@ module xcall::cluster_entry{
}
entry fun recieve_message_with_signatures(xcall:&mut XCallState,cap:&ConnCap,src_net_id:String,sn:u128,msg:vector,signatures:vector>,ctx: &mut TxContext){
+ let dst_net_id=xcall_state::get_net_id(xcall);
let state=get_state_mut(xcall_state::get_connection_states_mut(xcall),cap.connection_id());
- cluster_state::verify_signatures(state, src_net_id, sn, msg, signatures);
+ cluster_state::verify_signatures(state, src_net_id, sn, msg, dst_net_id, signatures);
cluster_state::check_save_receipt(state, src_net_id, sn);
xcall::handle_message(xcall, cap,src_net_id, msg,ctx);
}
diff --git a/contracts/sui/xcall/sources/cluster_connection/cluster_state.move b/contracts/sui/xcall/sources/cluster_connection/cluster_state.move
index 07742c14e..67125903f 100644
--- a/contracts/sui/xcall/sources/cluster_connection/cluster_state.move
+++ b/contracts/sui/xcall/sources/cluster_connection/cluster_state.move
@@ -12,9 +12,9 @@ module xcall::cluster_state {
use 0x2::ecdsa_k1::{secp256k1_ecrecover, decompress_pubkey};
//ERRORS
- const VerifiedSignaturesLessThanThreshold: u64 = 100;
const NotEnoughSignatures: u64 = 101;
const InvalidThreshold: u64 = 102;
+ const VerifiedSignaturesLessThanThreshold: u64 = 104;
const ValidatorCountMustBeGreaterThanThreshold: u64 = 105;
const InvalidAdminCap: u64 = 106;
@@ -139,9 +139,10 @@ module xcall::cluster_state {
src_net_id: String,
sn: u128,
msg: vector,
+ dst_net_id: String,
signatures: vector>
) {
- let message_hash = utils::get_message_hash(src_net_id, sn, msg);
+ let message_hash = utils::get_message_hash(src_net_id, sn, msg, dst_net_id);
let threshold = self.get_validator_threshold();
let validators = self.get_validators();
@@ -241,24 +242,40 @@ module xcall::cluster_state_tests {
let mut state = xcall::cluster_state::create_state();
let validators = vector[
- x"045b419bdec0d2bbc16ce8ae144ff8e825123fd0cb3e36d0075b6d8de5aab53388ac8fb4c28a8a3843f3073cdaa40c943f74737fc0cea4a95f87778affac738190",
- x"04ae36a8bfd8cf6586f34c688528894835f5e7c19d36689bac5460656b613c5eabf1fa982212aa27caece23a2708eb3c8936e132b9fd82c5aee2aa4b06917b5713",
- x"04f8c0afc6e4fa149e17fbb0f4d09647971bd016291e9ac66d0a708ec82fc8d5d2ac878d81b7d3f1d37f1013439fc3eb58a4df2f802f931c791c5d81b09034f337",
- x"046bc928ee4932efd619ec4c00e0591e932cf2cfef13a59f6027da1c6cba36b35d91238b54aece19825025a9c7cb0bc58a60d5c49e7fc8e5b39fcc4c2193f5feb2"
+ x"04deca512d5cb87673b23ab10c3e3572e30a2b5dc78cd500bf84bf066275c0bb320cb6cd266aa179b41323b5a18ab4a170248ed89b436b5559bab38c816ce12209",
+ x"04f9379b2955d759a9532f8daa0c4a25da0ae706dd057de02af7754adb4b956ec9b8bf7a8a5a6686bc74dff736442a874c6bae5dcbcdb7113e24fbfa2337c63a01",
+ x"041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f",
+ x"041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f"
];
- set_validators(&mut state, validators, 2);
+ set_validators(&mut state, validators, 3);
let validators = get_validators(&state);
- assert!((validators.length() == 4));
+ assert!((validators.length() == 3));
- set_validator_threshold(&mut state, 3);
- assert!(get_validator_threshold(&state)==3);
+ set_validator_threshold(&mut state, 2);
+ assert!(get_validator_threshold(&state)==2);
state
}
+ #[test]
+ #[expected_failure(abort_code = 105)]
+ fun test_add_validator_less_than_threshold(): State {
+ let mut state = xcall::cluster_state::create_state();
+
+ let validators = vector[
+ x"04deca512d5cb87673b23ab10c3e3572e30a2b5dc78cd500bf84bf066275c0bb320cb6cd266aa179b41323b5a18ab4a170248ed89b436b5559bab38c816ce12209",
+ x"04f9379b2955d759a9532f8daa0c4a25da0ae706dd057de02af7754adb4b956ec9b8bf7a8a5a6686bc74dff736442a874c6bae5dcbcdb7113e24fbfa2337c63a01",
+ x"041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f",
+ x"041d7fa5b41fe40ae85130c4cc334f7852c25c19e7f326a916d49f6b9c3f35a1216bf53c805d177c28f7bedc2d2521cb0f13dc832ef689797965274d26df50cd0f"
+ ];
+
+ set_validators(&mut state, validators, 4);
+ state
+ }
+
#[test]
fun test_set_get_threshold(): State {
@@ -325,41 +342,46 @@ module xcall::cluster_state_tests {
let state = test_add_validator();
let msg: vector = x"68656c6c6f";
let src_net_id = b"0x2.icon".to_string();
+ let dst_net_id = b"archway".to_string();
let conn_sn = 456456;
- let signatures = vector[x"23f731c7fb3553337394233055cbb9ec05abdd1df7cbbec3d0dacced58bf5b4b30576ca14bea93ea4186e920f99f2b9f56d30175b0a7356322f3a5d75de843b81b",
+ let signatures = vector[x"660d542b3f6de9cd08f238fd44133eeebfea290b21dae7322a63b516c57b8df12c4c0a340b60ed567c8da53578346c212b27b797eb42a75fb4b7076c567a6ff91c",
];
- xcall::cluster_state::verify_signatures(&state,src_net_id, conn_sn, msg, signatures);
+ xcall::cluster_state::verify_signatures(&state,src_net_id, conn_sn, msg, dst_net_id, signatures);
state
}
#[test]
- #[expected_failure(abort_code = 100)]
+ #[expected_failure(abort_code = 104)]
fun test_verify_signatures_invalid(): State {
- let state = test_set_get_threshold();
+ let state = test_add_validator();
let msg: vector = x"68656c6c6f";
let src_net_id = b"0x2.icon".to_string();
- let conn_sn = 456456;
+ let dst_net_id = b"archway".to_string();
+ let conn_sn = 128;
- let signatures = vector[x"23f731c7fb3553337394233055cbb9ec05abdd1df7cbbec3d0dacced58bf5b4b30576ca14bea93ea4186e920f99f2b9f56d30175b0a7356322f3a5d75de843b81c",
+ let signatures = vector[x"660d542b3f6de9cd08f238fd44133eeebfea290b21dae7322a63b516c57b8df12c4c0a340b60ed567c8da53578346c212b27b797eb42a75fb4b7076c567a6ff91c",
+ x"6a219f99495d3c093641648b96e0f4be4baba36e37f3054fb61ada7b82ed79c66a192af03314b8edfaecf6f541e1410d8b61f78649432f5b51b333f8b5ca40321b",
];
- xcall::cluster_state::verify_signatures(&state,src_net_id, conn_sn, msg, signatures);
+ xcall::cluster_state::verify_signatures(&state,src_net_id, conn_sn, msg, dst_net_id, signatures);
state
}
#[test]
fun test_verify_signatures(): State {
- let state = test_set_get_threshold();
+ let state = test_add_validator();
let msg: vector = x"68656c6c6f";
let src_net_id = b"0x2.icon".to_string();
- let conn_sn = 456456;
+ let dst_net_id = b"archway".to_string();
+ let conn_sn = 128;
- let signatures = vector[x"23f731c7fb3553337394233055cbb9ec05abdd1df7cbbec3d0dacced58bf5b4b30576ca14bea93ea4186e920f99f2b9f56d30175b0a7356322f3a5d75de843b81b",
+ let signatures = vector[x"660d542b3f6de9cd08f238fd44133eeebfea290b21dae7322a63b516c57b8df12c4c0a340b60ed567c8da53578346c212b27b797eb42a75fb4b7076c567a6ff91c",
+ x"8024de4c7b003df96bb699cfaa1bfb8a682787cd0853f555d48494c65c766f8104804848095890a9a6d15946da52dafb18e5c1d0dbe7f33fc7a5fa5cf8b1f6e21c"
];
- xcall::cluster_state::verify_signatures(&state,src_net_id, conn_sn, msg, signatures);
+ xcall::cluster_state::verify_signatures(&state,src_net_id, conn_sn, msg, dst_net_id, signatures);
state
}
diff --git a/contracts/sui/xcall/sources/utils.move b/contracts/sui/xcall/sources/utils.move
index 489a44819..4fd9b1daf 100644
--- a/contracts/sui/xcall/sources/utils.move
+++ b/contracts/sui/xcall/sources/utils.move
@@ -26,12 +26,13 @@ module xcall::xcall_utils {
}
}
- public fun get_message_hash(src_net_id: String, sn: u128, msg: vector): vector {
- let mut list=vector::empty>();
- vector::push_back(&mut list, encoder::encode_string(&src_net_id));
- vector::push_back(&mut list, encoder::encode_u128(sn));
- vector::push_back(&mut list, encoder::encode(&msg));
- let encoded=encoder::encode_list(&list,false);
+ public fun get_message_hash(src_net_id: String, sn: u128, msg: vector, dst_net_id: String): vector {
+
+ let mut encoded=vector::empty();
+ vector::append(&mut encoded, src_net_id.into_bytes());
+ vector::append(&mut encoded, (sn.to_string()).into_bytes());
+ vector::append(&mut encoded, msg);
+ vector::append(&mut encoded, dst_net_id.into_bytes());
encoded
}
diff --git a/scripts/optimize-stellar.sh b/scripts/optimize-stellar.sh
index 691c6e4bd..b527d71f3 100755
--- a/scripts/optimize-stellar.sh
+++ b/scripts/optimize-stellar.sh
@@ -11,7 +11,7 @@ cargo build --target wasm32-unknown-unknown --release
for WASM in $build_directory/*.wasm; do
NAME=$(basename "$WASM" .wasm)${SUFFIX}.wasm
echo "Optimizing $NAME ... $WASM"
- /usr/local/bin/stellar2 contract optimize --wasm "$WASM"
+ stellar contract optimize --wasm "$WASM"
done
cd -