/ GUNRPG.Infrastructure / Security / QuorumValidator.cs
QuorumValidator.cs
 1  namespace GUNRPG.Security;
 2  
 3  public sealed class QuorumValidator
 4  {
 5      public bool HasQuorum(
 6          SignedRunValidation validation,
 7          AuthoritySet authorities,
 8          QuorumPolicy policy)
 9      {
10          ArgumentNullException.ThrowIfNull(validation);
11          ArgumentNullException.ThrowIfNull(authorities);
12          ArgumentNullException.ThrowIfNull(policy);
13  
14          var resultHash = validation.ComputeResultHash();
15          var seenSigners = new HashSet<string>(StringComparer.Ordinal);
16          var validSignatures = 0;
17  
18          foreach (var signature in validation.Signatures)
19          {
20              if (signature is null)
21              {
22                  return false;
23              }
24  
25              if (!authorities.IsTrusted(signature.PublicKeyBytes))
26              {
27                  return false;
28              }
29  
30              var signerId = AuthoritySet.CreateKeyIdentifier(signature.PublicKeyBytes);
31              if (!seenSigners.Add(signerId))
32              {
33                  return false;
34              }
35  
36              if (!AuthorityCrypto.VerifyHashedPayload(
37                      signature.PublicKeyBytes,
38                      resultHash,
39                      signature.SignatureBytes))
40              {
41                  return false;
42              }
43  
44              validSignatures++;
45          }
46  
47          return validSignatures >= policy.RequiredSignatures;
48      }
49  }