From 21e555192ce88e7513c3b03ca98ab150f7e05131 Mon Sep 17 00:00:00 2001
From: Luke Parker <lukeparker5132@gmail.com>
Date: Mon, 18 Jul 2022 02:53:45 -0400
Subject: [PATCH] Add subsequent_vote test

This is the contracts/extension that triggered a Rust ICE, as noted in
my issue there.
---
 contracts/extension/src/lib.rs | 20 +++++++++++--------
 contracts/multisig/lib.rs      | 35 +++++++++++++++++++++++++++++++---
 2 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/contracts/extension/src/lib.rs b/contracts/extension/src/lib.rs
index ab1e4d24..a0832abc 100644
--- a/contracts/extension/src/lib.rs
+++ b/contracts/extension/src/lib.rs
@@ -34,6 +34,16 @@ impl Environment for SeraiEnvironment {
   type ChainExtension = SeraiExtension;
 }
 
+pub fn test_validators() -> Vec<AccountId> {
+  vec![
+    AccountId::from([1; 32]),
+    AccountId::from([2; 32]),
+    AccountId::from([3; 32]),
+    AccountId::from([4; 32]),
+    AccountId::from([5; 32]),
+  ]
+}
+
 pub fn test_register() {
   struct ExtensionLen;
   impl ink_env::test::ChainExtension for ExtensionLen {
@@ -42,7 +52,7 @@ pub fn test_register() {
     }
 
     fn call(&mut self, _: &[u8], output: &mut Vec<u8>) -> u32 {
-      scale::Encode::encode_to(&5u16, output);
+      scale::Encode::encode_to(&u16::try_from(test_validators().len()).unwrap(), output);
       0
     }
   }
@@ -72,13 +82,7 @@ pub fn test_register() {
       let potential = AccountId::decode(&mut &input[1 ..]).unwrap(); // TODO: Why is this 1 ..?
 
       let mut presence = false;
-      for validator in [
-        AccountId::from([1; 32]),
-        AccountId::from([2; 32]),
-        AccountId::from([3; 32]),
-        AccountId::from([4; 32]),
-        AccountId::from([5; 32])
-      ].clone() {
+      for validator in test_validators() {
         if potential == validator {
           presence = true;
         }
diff --git a/contracts/multisig/lib.rs b/contracts/multisig/lib.rs
index bbf62802..9e176a5d 100644
--- a/contracts/multisig/lib.rs
+++ b/contracts/multisig/lib.rs
@@ -220,20 +220,22 @@ mod multisig {
       assert_eq!(multisig.validator_set(), [0; 32]);
     }
 
+    /// Non-existent curves error accordingly.
     #[ink::test]
     fn non_existent_curve() {
       assert_eq!(Multisig::new().key(0), Err(Error::NonExistentCurve));
     }
 
+    /// Validators can vote on keys.
     #[ink::test]
     fn vote() {
       serai_extension::test_register();
-      ink_env::test::set_caller::<ink_env::DefaultEnvironment>(AccountId::from([1; 32]));
-
+      let keys = vec![vec![0, 1], vec![2, 3]];
       let mut multisig = Multisig::new();
 
-      let keys = vec![vec![0, 1], vec![2, 3]];
+      ink_env::test::set_caller::<ink_env::DefaultEnvironment>(AccountId::from([1; 32]));
       multisig.vote(keys.clone()).unwrap();
+
       let emitted_events = ink_env::test::recorded_events().collect::<Vec<_>>();
       assert_eq!(emitted_events.len(), 1);
       assert_vote(
@@ -248,5 +250,32 @@ mod multisig {
         Some(keys),
       );
     }
+
+    /// Subsequent votes don't re-emit the full keys.
+    #[ink::test]
+    fn subsequent_vote() {
+      serai_extension::test_register();
+      let keys = vec![vec![0, 1], vec![2, 3]];
+      let mut multisig = Multisig::new();
+
+      ink_env::test::set_caller::<ink_env::DefaultEnvironment>(AccountId::from([1; 32]));
+      multisig.vote(keys.clone()).unwrap();
+      ink_env::test::set_caller::<ink_env::DefaultEnvironment>(AccountId::from([2; 32]));
+      multisig.vote(keys.clone()).unwrap();
+
+      let emitted_events = ink_env::test::recorded_events().collect::<Vec<_>>();
+      assert_eq!(emitted_events.len(), 2);
+      assert_vote(
+        &emitted_events[1],
+        AccountId::from([2; 32]),
+        [0xff; 32],
+        {
+          let mut hash = [0; 32];
+          ink_env::hash_encoded::<Blake2x256, _>(&keys, &mut hash);
+          hash
+        },
+        None,
+      );
+    }
   }
 }