Disallow duplicate eth addresses

This commit is contained in:
benbierens 2023-10-25 10:25:00 +02:00
parent 6d44a0ccfc
commit 6e82d6b1e6
No known key found for this signature in database
GPG Key ID: FE44815D96D0A1AA
3 changed files with 45 additions and 7 deletions

View File

@ -27,8 +27,17 @@ namespace BiblioTech.Commands
return; return;
} }
Program.UserRepo.AssociateUserWithAddress(userId, data); // private commands
await context.Command.FollowupAsync("Done! Thank you for joining the test net!");
var result = Program.UserRepo.AssociateUserWithAddress(userId, data);
if (result)
{
await context.Command.FollowupAsync("Done! Thank you for joining the test net!");
}
else
{
await context.Command.FollowupAsync("That didn't work.");
}
} }
} }
} }

View File

@ -29,8 +29,8 @@ namespace BiblioTech.Options
} }
if (!AddressUtil.Current.IsValidAddressLength(ethAddressStr) || if (!AddressUtil.Current.IsValidAddressLength(ethAddressStr) ||
!AddressUtil.Current.IsValidEthereumAddressHexFormat(ethAddressStr) || !AddressUtil.Current.IsValidEthereumAddressHexFormat(ethAddressStr))
!AddressUtil.Current.IsChecksumAddress(ethAddressStr)) // !AddressUtil.Current.IsChecksumAddress(ethAddressStr)) - this might make a good option later, but for now it might just annoy users.
{ {
await context.Command.FollowupAsync("EthAddress is not valid."); await context.Command.FollowupAsync("EthAddress is not valid.");
return null; return null;

View File

@ -8,11 +8,11 @@ namespace BiblioTech
{ {
private readonly object repoLock = new object(); private readonly object repoLock = new object();
public void AssociateUserWithAddress(ulong discordId, EthAddress address) public bool AssociateUserWithAddress(ulong discordId, EthAddress address)
{ {
lock (repoLock) lock (repoLock)
{ {
SetUserAddress(discordId, address); return SetUserAddress(discordId, address);
} }
} }
@ -79,12 +79,18 @@ namespace BiblioTech
return result.ToArray(); return result.ToArray();
} }
private void SetUserAddress(ulong discordId, EthAddress? address) private bool SetUserAddress(ulong discordId, EthAddress? address)
{ {
if (IsAddressUsed(address))
{
return false;
}
var user = GetOrCreate(discordId); var user = GetOrCreate(discordId);
user.CurrentAddress = address; user.CurrentAddress = address;
user.AssociateEvents.Add(new UserAssociateAddressEvent(DateTime.UtcNow, address)); user.AssociateEvents.Add(new UserAssociateAddressEvent(DateTime.UtcNow, address));
SaveUser(user); SaveUser(user);
return true;
} }
private User GetOrCreate(ulong discordId) private User GetOrCreate(ulong discordId)
@ -104,6 +110,29 @@ namespace BiblioTech
return newUser; return newUser;
} }
private bool IsAddressUsed(EthAddress? address)
{
if (address == null) return false;
// If this becomes a performance problem, switch to in-memory cached list.
var files = Directory.GetFiles(Program.Config.UserDataPath);
foreach (var file in files)
{
try
{
var user = JsonConvert.DeserializeObject<User>(File.ReadAllText(file))!;
if (user.CurrentAddress != null &&
user.CurrentAddress.Address == address.Address)
{
return true;
}
}
catch { }
}
return false;
}
private void SaveUser(User user) private void SaveUser(User user)
{ {
var filename = GetFilename(user.DiscordId); var filename = GetFilename(user.DiscordId);