From 1b3fa5c806f07286f794c916fdb8e2f1170538c6 Mon Sep 17 00:00:00 2001 From: catbref Date: Thu, 14 Mar 2019 13:12:20 +0000 Subject: [PATCH] Automatically set/unset account's defaultGroupId + bugfix FIX: somehow GET /groups/member/{address} HSQLDB's query broke --- src/main/java/org/qora/account/Account.java | 2 + .../transaction/GroupBanTransactionData.java | 18 ++++- .../GroupInviteTransactionData.java | 19 ++++- .../transaction/GroupKickTransactionData.java | 18 ++++- .../transaction/JoinGroupTransactionData.java | 18 ++++- .../LeaveGroupTransactionData.java | 19 ++++- src/main/java/org/qora/group/Group.java | 69 +++++++++++++++++++ .../hsqldb/HSQLDBDatabaseUpdates.java | 10 +++ .../hsqldb/HSQLDBGroupRepository.java | 2 +- .../HSQLDBGroupBanTransactionRepository.java | 10 ++- ...SQLDBGroupInviteTransactionRepository.java | 11 ++- .../HSQLDBGroupKickTransactionRepository.java | 11 ++- .../HSQLDBJoinGroupTransactionRepository.java | 11 ++- ...HSQLDBLeaveGroupTransactionRepository.java | 10 ++- .../transaction/JoinGroupTransaction.java | 1 + 15 files changed, 203 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/qora/account/Account.java b/src/main/java/org/qora/account/Account.java index 8a153321..a3b64f54 100644 --- a/src/main/java/org/qora/account/Account.java +++ b/src/main/java/org/qora/account/Account.java @@ -215,6 +215,8 @@ public class Account { AccountData accountData = this.buildAccountData(); accountData.setDefaultGroupId(defaultGroupId); this.repository.getAccountRepository().setDefaultGroupId(accountData); + + LOGGER.trace(String.format("Account %s defaultGroupId now %d", accountData.getAddress(), defaultGroupId)); } } diff --git a/src/main/java/org/qora/data/transaction/GroupBanTransactionData.java b/src/main/java/org/qora/data/transaction/GroupBanTransactionData.java index d6710b12..23089374 100644 --- a/src/main/java/org/qora/data/transaction/GroupBanTransactionData.java +++ b/src/main/java/org/qora/data/transaction/GroupBanTransactionData.java @@ -58,6 +58,11 @@ public class GroupBanTransactionData extends TransactionData { @XmlTransient @Schema(hidden = true) private byte[] joinInviteReference; + /** Offender's previous defaultGroupId, set only if this transaction changed it to NO_GROUP. */ + // No need to expose this via API + @XmlTransient + @Schema(hidden = true) + private Integer previousGroupId; // Constructors @@ -71,7 +76,7 @@ public class GroupBanTransactionData extends TransactionData { } public GroupBanTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String member, - String reason, int timeToLive, byte[] memberReference, byte[] adminReference, byte[] joinInviteReference, BigDecimal fee, byte[] signature) { + String reason, int timeToLive, byte[] memberReference, byte[] adminReference, byte[] joinInviteReference, Integer previousGroupId, BigDecimal fee, byte[] signature) { super(TransactionType.GROUP_BAN, timestamp, txGroupId, reference, adminPublicKey, fee, signature); this.adminPublicKey = adminPublicKey; @@ -82,12 +87,13 @@ public class GroupBanTransactionData extends TransactionData { this.memberReference = memberReference; this.adminReference = adminReference; this.joinInviteReference = joinInviteReference; + this.previousGroupId = previousGroupId; } /** Constructor typically used after deserialization */ public GroupBanTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String offender, String reason, int timeToLive, BigDecimal fee, byte[] signature) { - this(timestamp, txGroupId, reference, adminPublicKey, groupId, offender, reason, timeToLive, null, null, null, fee, signature); + this(timestamp, txGroupId, reference, adminPublicKey, groupId, offender, reason, timeToLive, null, null, null, null, fee, signature); } // Getters / setters @@ -136,4 +142,12 @@ public class GroupBanTransactionData extends TransactionData { this.joinInviteReference = reference; } + public Integer getPreviousGroupId() { + return this.previousGroupId; + } + + public void setPreviousGroupId(Integer previousGroupId) { + this.previousGroupId = previousGroupId; + } + } diff --git a/src/main/java/org/qora/data/transaction/GroupInviteTransactionData.java b/src/main/java/org/qora/data/transaction/GroupInviteTransactionData.java index ef9bdbda..f3dabe13 100644 --- a/src/main/java/org/qora/data/transaction/GroupInviteTransactionData.java +++ b/src/main/java/org/qora/data/transaction/GroupInviteTransactionData.java @@ -30,6 +30,11 @@ public class GroupInviteTransactionData extends TransactionData { @XmlTransient @Schema(hidden = true) private byte[] joinReference; + /** Invitee's previous defaultGroupId, set only if this transaction changed it from NO_GROUP. */ + // No need to expose this via API + @XmlTransient + @Schema(hidden = true) + private Integer previousGroupId; // Constructors @@ -42,7 +47,8 @@ public class GroupInviteTransactionData extends TransactionData { this.creatorPublicKey = this.adminPublicKey; } - public GroupInviteTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String invitee, int timeToLive, byte[] joinReference, BigDecimal fee, byte[] signature) { + public GroupInviteTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String invitee, int timeToLive, byte[] joinReference, Integer previousGroupId, + BigDecimal fee, byte[] signature) { super(TransactionType.GROUP_INVITE, timestamp, txGroupId, reference, adminPublicKey, fee, signature); this.adminPublicKey = adminPublicKey; @@ -50,11 +56,12 @@ public class GroupInviteTransactionData extends TransactionData { this.invitee = invitee; this.timeToLive = timeToLive; this.joinReference = joinReference; + this.previousGroupId = previousGroupId; } /** Constructor typically used after deserialization */ public GroupInviteTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String invitee, int timeToLive, BigDecimal fee, byte[] signature) { - this(timestamp, txGroupId, reference, adminPublicKey, groupId, invitee, timeToLive, null, fee, signature); + this(timestamp, txGroupId, reference, adminPublicKey, groupId, invitee, timeToLive, null, null, fee, signature); } // Getters / setters @@ -83,4 +90,12 @@ public class GroupInviteTransactionData extends TransactionData { this.joinReference = joinReference; } + public Integer getPreviousGroupId() { + return this.previousGroupId; + } + + public void setPreviousGroupId(Integer previousGroupId) { + this.previousGroupId = previousGroupId; + } + } \ No newline at end of file diff --git a/src/main/java/org/qora/data/transaction/GroupKickTransactionData.java b/src/main/java/org/qora/data/transaction/GroupKickTransactionData.java index 9aa44119..82255fc6 100644 --- a/src/main/java/org/qora/data/transaction/GroupKickTransactionData.java +++ b/src/main/java/org/qora/data/transaction/GroupKickTransactionData.java @@ -55,6 +55,11 @@ public class GroupKickTransactionData extends TransactionData { @XmlTransient @Schema(hidden = true) private byte[] joinReference; + /** Offender's previous defaultGroupId, set only if this transaction changed it to NO_GROUP. */ + // No need to expose this via API + @XmlTransient + @Schema(hidden = true) + private Integer previousGroupId; // Constructors @@ -68,7 +73,7 @@ public class GroupKickTransactionData extends TransactionData { } public GroupKickTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String member, - String reason, byte[] memberReference, byte[] adminReference, byte[] joinReference, BigDecimal fee, byte[] signature) { + String reason, byte[] memberReference, byte[] adminReference, byte[] joinReference, Integer previousGroupId, BigDecimal fee, byte[] signature) { super(TransactionType.GROUP_KICK, timestamp, txGroupId, reference, adminPublicKey, fee, signature); this.adminPublicKey = adminPublicKey; @@ -78,12 +83,13 @@ public class GroupKickTransactionData extends TransactionData { this.memberReference = memberReference; this.adminReference = adminReference; this.joinReference = joinReference; + this.previousGroupId = previousGroupId; } /** Constructor typically used after deserialization */ public GroupKickTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] adminPublicKey, int groupId, String member, String reason, BigDecimal fee, byte[] signature) { - this(timestamp, txGroupId, reference, adminPublicKey, groupId, member, reason, null, null, null, fee, signature); + this(timestamp, txGroupId, reference, adminPublicKey, groupId, member, reason, null, null, null, null, fee, signature); } // Getters / setters @@ -128,4 +134,12 @@ public class GroupKickTransactionData extends TransactionData { this.joinReference = joinReference; } + public Integer getPreviousGroupId() { + return this.previousGroupId; + } + + public void setPreviousGroupId(Integer previousGroupId) { + this.previousGroupId = previousGroupId; + } + } diff --git a/src/main/java/org/qora/data/transaction/JoinGroupTransactionData.java b/src/main/java/org/qora/data/transaction/JoinGroupTransactionData.java index 6059b090..98b37af1 100644 --- a/src/main/java/org/qora/data/transaction/JoinGroupTransactionData.java +++ b/src/main/java/org/qora/data/transaction/JoinGroupTransactionData.java @@ -26,6 +26,11 @@ public class JoinGroupTransactionData extends TransactionData { @XmlTransient @Schema(hidden = true) private byte[] inviteReference; + /** Joiner's previous defaultGroupId, set only if this transaction changed it from NO_GROUP. */ + // No need to expose this via API + @XmlTransient + @Schema(hidden = true) + private Integer previousGroupId; // Constructors @@ -38,17 +43,18 @@ public class JoinGroupTransactionData extends TransactionData { this.creatorPublicKey = this.joinerPublicKey; } - public JoinGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] joinerPublicKey, int groupId, byte[] inviteReference, BigDecimal fee, byte[] signature) { + public JoinGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] joinerPublicKey, int groupId, byte[] inviteReference, Integer previousGroupId, BigDecimal fee, byte[] signature) { super(TransactionType.JOIN_GROUP, timestamp, txGroupId, reference, joinerPublicKey, fee, signature); this.joinerPublicKey = joinerPublicKey; this.groupId = groupId; this.inviteReference = inviteReference; + this.previousGroupId = previousGroupId; } /** Constructor typically used after deserialization */ public JoinGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] joinerPublicKey, int groupId, BigDecimal fee, byte[] signature) { - this(timestamp, txGroupId, reference, joinerPublicKey, groupId, null, fee, signature); + this(timestamp, txGroupId, reference, joinerPublicKey, groupId, null, null, fee, signature); } // Getters / setters @@ -69,4 +75,12 @@ public class JoinGroupTransactionData extends TransactionData { this.inviteReference = inviteReference; } + public Integer getPreviousGroupId() { + return this.previousGroupId; + } + + public void setPreviousGroupId(Integer previousGroupId) { + this.previousGroupId = previousGroupId; + } + } diff --git a/src/main/java/org/qora/data/transaction/LeaveGroupTransactionData.java b/src/main/java/org/qora/data/transaction/LeaveGroupTransactionData.java index 34b1c601..7a823444 100644 --- a/src/main/java/org/qora/data/transaction/LeaveGroupTransactionData.java +++ b/src/main/java/org/qora/data/transaction/LeaveGroupTransactionData.java @@ -31,6 +31,11 @@ public class LeaveGroupTransactionData extends TransactionData { @XmlTransient @Schema(hidden = true) private byte[] adminReference; + /** Leaver's previous defaultGroupId, set only if this transaction changed it to NO_GROUP. */ + // No need to expose this via API + @XmlTransient + @Schema(hidden = true) + private Integer previousGroupId; // Constructors @@ -43,18 +48,20 @@ public class LeaveGroupTransactionData extends TransactionData { this.creatorPublicKey = this.leaverPublicKey; } - public LeaveGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] leaverPublicKey, int groupId, byte[] memberReference, byte[] adminReference, BigDecimal fee, byte[] signature) { + public LeaveGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] leaverPublicKey, int groupId, byte[] memberReference, byte[] adminReference, Integer previousGroupId, + BigDecimal fee, byte[] signature) { super(TransactionType.LEAVE_GROUP, timestamp, txGroupId, reference, leaverPublicKey, fee, signature); this.leaverPublicKey = leaverPublicKey; this.groupId = groupId; this.memberReference = memberReference; this.adminReference = adminReference; + this.previousGroupId = previousGroupId; } /** Constructor typically used after deserialization */ public LeaveGroupTransactionData(long timestamp, int txGroupId, byte[] reference, byte[] leaverPublicKey, int groupId, BigDecimal fee, byte[] signature) { - this(timestamp, txGroupId, reference, leaverPublicKey, groupId, null, null, fee, signature); + this(timestamp, txGroupId, reference, leaverPublicKey, groupId, null, null, null, fee, signature); } // Getters / setters @@ -83,4 +90,12 @@ public class LeaveGroupTransactionData extends TransactionData { this.adminReference = adminReference; } + public Integer getPreviousGroupId() { + return this.previousGroupId; + } + + public void setPreviousGroupId(Integer previousGroupId) { + this.previousGroupId = previousGroupId; + } + } diff --git a/src/main/java/org/qora/group/Group.java b/src/main/java/org/qora/group/Group.java index 45b62b18..cee0456d 100644 --- a/src/main/java/org/qora/group/Group.java +++ b/src/main/java/org/qora/group/Group.java @@ -467,6 +467,14 @@ public class Group { // Kicked, so no longer a member this.deleteMember(member); + + // If member had this group set as their defaultGroupId then change it to NO_GROUP + Account memberAccount = new Account(this.repository, member); + if (memberAccount.getDefaultGroupId() == groupKickTransactionData.getGroupId()) { + memberAccount.setDefaultGroupId(Group.NO_GROUP); + // Reflect that this has happened in joinGroupTransactionData + groupKickTransactionData.setPreviousGroupId(groupKickTransactionData.getGroupId()); + } } public void unkick(GroupKickTransactionData groupKickTransactionData) throws DataException { @@ -484,6 +492,13 @@ public class Group { // Rebuild member entry using stored transaction reference this.rebuildMember(member, groupKickTransactionData.getMemberReference()); + // Revert member's defaultGroupId if necessary + Integer previousDefaultGroupId = groupKickTransactionData.getPreviousGroupId(); + if (previousDefaultGroupId != null) { + Account memberAccount = new Account(this.repository, member); + memberAccount.setDefaultGroupId(previousDefaultGroupId); + } + if (groupKickTransactionData.getAdminReference() != null) // Rebuild admin entry using stored transaction reference this.rebuildAdmin(member, groupKickTransactionData.getAdminReference()); @@ -516,6 +531,14 @@ public class Group { // Kicked, so no longer a member this.deleteMember(offender); + + // If offender had this group set as their defaultGroupId then change it to NO_GROUP + Account offenderAccount = new Account(this.repository, offender); + if (offenderAccount.getDefaultGroupId() == groupBanTransactionData.getGroupId()) { + offenderAccount.setDefaultGroupId(Group.NO_GROUP); + // Reflect that this has happened in joinGroupTransactionData + groupBanTransactionData.setPreviousGroupId(groupBanTransactionData.getGroupId()); + } } else { // If there is a pending join request then this is a essentially a deny response so delete join request GroupJoinRequestData groupJoinRequestData = this.getJoinRequest(offender); @@ -570,6 +593,13 @@ public class Group { if (groupBanTransactionData.getAdminReference() != null) // Rebuild admin entry using stored transaction reference this.rebuildAdmin(offender, groupBanTransactionData.getAdminReference()); + + // Revert offender's defaultGroupId if necessary + Integer previousDefaultGroupId = groupBanTransactionData.getPreviousGroupId(); + if (previousDefaultGroupId != null) { + Account offenderAccount = new Account(this.repository, offender); + offenderAccount.setDefaultGroupId(previousDefaultGroupId); + } } else { // Do we need to reinstate pending invite or join-request? byte[] groupReference = groupBanTransactionData.getJoinInviteReference(); @@ -626,6 +656,14 @@ public class Group { // Save reference to transaction that created join request so we can rebuild join request during orphaning. groupInviteTransactionData.setJoinReference(groupJoinRequestData.getReference()); + // If invitee's defaultGroupId is NO_GROUP then set it to joined group + Account inviteeAccount = new Account(this.repository, invitee); + if (inviteeAccount.getDefaultGroupId() == Group.NO_GROUP) { + inviteeAccount.setDefaultGroupId(groupInviteTransactionData.getGroupId()); + // Reflect that this has happened in groupInviteTransactionData + groupInviteTransactionData.setPreviousGroupId(Group.NO_GROUP); + } + // Delete join request this.deleteJoinRequest(invitee); @@ -643,6 +681,13 @@ public class Group { // Rebuild join request using cached reference to transaction that created join request. this.rebuildJoinRequest(invitee, groupInviteTransactionData.getJoinReference()); + // Revert invitee's defaultGroupId if necessary + Integer previousDefaultGroupId = groupInviteTransactionData.getPreviousGroupId(); + if (previousDefaultGroupId != null) { + Account inviteeAccount = new Account(this.repository, invitee); + inviteeAccount.setDefaultGroupId(previousDefaultGroupId); + } + // Delete member this.deleteMember(invitee); @@ -706,6 +751,13 @@ public class Group { // Actually add new member to group this.addMember(joiner.getAddress(), joinGroupTransactionData); + + // If joiner's defaultGroupId is NO_GROUP then set it to joined group + if (joiner.getDefaultGroupId() == Group.NO_GROUP) { + joiner.setDefaultGroupId(joinGroupTransactionData.getGroupId()); + // Reflect that this has happened in joinGroupTransactionData + joinGroupTransactionData.setPreviousGroupId(Group.NO_GROUP); + } } public void unjoin(JoinGroupTransactionData joinGroupTransactionData) throws DataException { @@ -733,6 +785,11 @@ public class Group { // Delete member this.deleteMember(joiner.getAddress()); + + // Revert joiner's defaultGroupId if necessary + Integer previousDefaultGroupId = joinGroupTransactionData.getPreviousGroupId(); + if (previousDefaultGroupId != null) + joiner.setDefaultGroupId(previousDefaultGroupId); } public void leave(LeaveGroupTransactionData leaveGroupTransactionData) throws DataException { @@ -761,6 +818,13 @@ public class Group { // Remove as member this.deleteMember(leaver.getAddress()); + + // If member had this group set as their defaultGroupId then change it to NO_GROUP + if (leaver.getDefaultGroupId() == leaveGroupTransactionData.getGroupId()) { + leaver.setDefaultGroupId(Group.NO_GROUP); + // Reflect that this has happened in joinGroupTransactionData + leaveGroupTransactionData.setPreviousGroupId(leaveGroupTransactionData.getGroupId()); + } } public void unleave(LeaveGroupTransactionData leaveGroupTransactionData) throws DataException { @@ -773,6 +837,11 @@ public class Group { if (adminTransactionSignature != null) // Restore adminship using cached reference to transaction that caused adminship this.rebuildAdmin(leaver.getAddress(), adminTransactionSignature); + + // Revert leaver's defaultGroupId if necessary + Integer previousDefaultGroupId = leaveGroupTransactionData.getPreviousGroupId(); + if (previousDefaultGroupId != null) + leaver.setDefaultGroupId(previousDefaultGroupId); } } diff --git a/src/main/java/org/qora/repository/hsqldb/HSQLDBDatabaseUpdates.java b/src/main/java/org/qora/repository/hsqldb/HSQLDBDatabaseUpdates.java index eb79f296..e879a92c 100644 --- a/src/main/java/org/qora/repository/hsqldb/HSQLDBDatabaseUpdates.java +++ b/src/main/java/org/qora/repository/hsqldb/HSQLDBDatabaseUpdates.java @@ -612,6 +612,16 @@ public class HSQLDBDatabaseUpdates { + "ON Assets.asset_id = Updates.asset_id WHEN MATCHED THEN UPDATE SET Assets.reference = Updates.signature"); break; + case 39: + // Support for automatically setting joiner's default groupID when they join a group (by JOIN_GROUP or corresponding admin's INVITE_GROUP) + stmt.execute("ALTER TABLE JoinGroupTransactions ADD previous_group_id INTEGER"); + stmt.execute("ALTER TABLE GroupInviteTransactions ADD previous_group_id INTEGER"); + // Ditto for leaving + stmt.execute("ALTER TABLE LeaveGroupTransactions ADD previous_group_id INTEGER"); + stmt.execute("ALTER TABLE GroupKickTransactions ADD previous_group_id INTEGER"); + stmt.execute("ALTER TABLE GroupBanTransactions ADD previous_group_id INTEGER"); + break; + default: // nothing to do return false; diff --git a/src/main/java/org/qora/repository/hsqldb/HSQLDBGroupRepository.java b/src/main/java/org/qora/repository/hsqldb/HSQLDBGroupRepository.java index 3135ddf9..54834b05 100644 --- a/src/main/java/org/qora/repository/hsqldb/HSQLDBGroupRepository.java +++ b/src/main/java/org/qora/repository/hsqldb/HSQLDBGroupRepository.java @@ -196,7 +196,7 @@ public class HSQLDBGroupRepository implements GroupRepository { @Override public List getGroupsWithMember(String member, Integer limit, Integer offset, Boolean reverse) throws DataException { - String sql = "SELECT group_id, owner, group_name, description, created, updated, reference, is_open, approval_threshold min_block_delay, max_block_delay, creation_group_id FROM Groups " + String sql = "SELECT group_id, owner, group_name, description, created, updated, reference, is_open, approval_threshold, min_block_delay, max_block_delay, creation_group_id FROM Groups " + "JOIN GroupMembers USING (group_id) WHERE address = ? ORDER BY group_name"; if (reverse != null && reverse) sql += " DESC"; diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupBanTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupBanTransactionRepository.java index 37825ee2..740bb7cd 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupBanTransactionRepository.java +++ b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupBanTransactionRepository.java @@ -18,7 +18,7 @@ public class HSQLDBGroupBanTransactionRepository extends HSQLDBTransactionReposi TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException { try (ResultSet resultSet = this.repository.checkedExecute( - "SELECT group_id, address, reason, time_to_live, member_reference, admin_reference, join_invite_reference FROM GroupBanTransactions WHERE signature = ?", + "SELECT group_id, address, reason, time_to_live, member_reference, admin_reference, join_invite_reference, previous_group_id FROM GroupBanTransactions WHERE signature = ?", signature)) { if (resultSet == null) return null; @@ -31,8 +31,12 @@ public class HSQLDBGroupBanTransactionRepository extends HSQLDBTransactionReposi byte[] adminReference = resultSet.getBytes(6); byte[] joinInviteReference = resultSet.getBytes(7); + Integer previousGroupId = resultSet.getInt(8); + if (resultSet.wasNull()) + previousGroupId = null; + return new GroupBanTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, offender, reason, timeToLive, - memberReference, adminReference, joinInviteReference, fee, signature); + memberReference, adminReference, joinInviteReference, previousGroupId, fee, signature); } catch (SQLException e) { throw new DataException("Unable to fetch group ban transaction from repository", e); } @@ -48,7 +52,7 @@ public class HSQLDBGroupBanTransactionRepository extends HSQLDBTransactionReposi .bind("group_id", groupBanTransactionData.getGroupId()).bind("address", groupBanTransactionData.getOffender()) .bind("reason", groupBanTransactionData.getReason()).bind("time_to_live", groupBanTransactionData.getTimeToLive()) .bind("member_reference", groupBanTransactionData.getMemberReference()).bind("admin_reference", groupBanTransactionData.getAdminReference()) - .bind("join_invite_reference", groupBanTransactionData.getJoinInviteReference()); + .bind("join_invite_reference", groupBanTransactionData.getJoinInviteReference()).bind("previous_group_id", groupBanTransactionData.getPreviousGroupId()); try { saveHelper.execute(this.repository); diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupInviteTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupInviteTransactionRepository.java index b2a3a9a4..dfce7eeb 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupInviteTransactionRepository.java +++ b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupInviteTransactionRepository.java @@ -18,7 +18,7 @@ public class HSQLDBGroupInviteTransactionRepository extends HSQLDBTransactionRep TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException { try (ResultSet resultSet = this.repository - .checkedExecute("SELECT group_id, invitee, time_to_live, join_reference FROM GroupInviteTransactions WHERE signature = ?", signature)) { + .checkedExecute("SELECT group_id, invitee, time_to_live, join_reference, previous_group_id FROM GroupInviteTransactions WHERE signature = ?", signature)) { if (resultSet == null) return null; @@ -27,7 +27,11 @@ public class HSQLDBGroupInviteTransactionRepository extends HSQLDBTransactionRep int timeToLive = resultSet.getInt(3); byte[] joinReference = resultSet.getBytes(4); - return new GroupInviteTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, invitee, timeToLive, joinReference, fee, signature); + Integer previousGroupId = resultSet.getInt(5); + if (resultSet.wasNull()) + previousGroupId = null; + + return new GroupInviteTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, invitee, timeToLive, joinReference, previousGroupId, fee, signature); } catch (SQLException e) { throw new DataException("Unable to fetch group invite transaction from repository", e); } @@ -41,7 +45,8 @@ public class HSQLDBGroupInviteTransactionRepository extends HSQLDBTransactionRep saveHelper.bind("signature", groupInviteTransactionData.getSignature()).bind("admin", groupInviteTransactionData.getAdminPublicKey()) .bind("group_id", groupInviteTransactionData.getGroupId()).bind("invitee", groupInviteTransactionData.getInvitee()) - .bind("time_to_live", groupInviteTransactionData.getTimeToLive()).bind("join_reference", groupInviteTransactionData.getJoinReference()); + .bind("time_to_live", groupInviteTransactionData.getTimeToLive()).bind("join_reference", groupInviteTransactionData.getJoinReference()) + .bind("previous_group_id", groupInviteTransactionData.getPreviousGroupId()); try { saveHelper.execute(this.repository); diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupKickTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupKickTransactionRepository.java index dbe194de..9f1bf535 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupKickTransactionRepository.java +++ b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBGroupKickTransactionRepository.java @@ -18,7 +18,7 @@ public class HSQLDBGroupKickTransactionRepository extends HSQLDBTransactionRepos TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException { try (ResultSet resultSet = this.repository.checkedExecute( - "SELECT group_id, address, reason, member_reference, admin_reference, join_reference FROM GroupKickTransactions WHERE signature = ?", + "SELECT group_id, address, reason, member_reference, admin_reference, join_reference, previous_group_id FROM GroupKickTransactions WHERE signature = ?", signature)) { if (resultSet == null) return null; @@ -30,8 +30,12 @@ public class HSQLDBGroupKickTransactionRepository extends HSQLDBTransactionRepos byte[] adminReference = resultSet.getBytes(5); byte[] joinReference = resultSet.getBytes(6); + Integer previousGroupId = resultSet.getInt(7); + if (resultSet.wasNull()) + previousGroupId = null; + return new GroupKickTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, member, reason, memberReference, adminReference, - joinReference, fee, signature); + joinReference, previousGroupId, fee, signature); } catch (SQLException e) { throw new DataException("Unable to fetch group kick transaction from repository", e); } @@ -46,7 +50,8 @@ public class HSQLDBGroupKickTransactionRepository extends HSQLDBTransactionRepos saveHelper.bind("signature", groupKickTransactionData.getSignature()).bind("admin", groupKickTransactionData.getAdminPublicKey()) .bind("group_id", groupKickTransactionData.getGroupId()).bind("address", groupKickTransactionData.getMember()) .bind("reason", groupKickTransactionData.getReason()).bind("member_reference", groupKickTransactionData.getMemberReference()) - .bind("admin_reference", groupKickTransactionData.getAdminReference()).bind("join_reference", groupKickTransactionData.getJoinReference()); + .bind("admin_reference", groupKickTransactionData.getAdminReference()).bind("join_reference", groupKickTransactionData.getJoinReference()) + .bind("previous_group_id", groupKickTransactionData.getPreviousGroupId()); try { saveHelper.execute(this.repository); diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBJoinGroupTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBJoinGroupTransactionRepository.java index 98dce60d..ef95aa5d 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBJoinGroupTransactionRepository.java +++ b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBJoinGroupTransactionRepository.java @@ -17,7 +17,7 @@ public class HSQLDBJoinGroupTransactionRepository extends HSQLDBTransactionRepos } TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException { - try (ResultSet resultSet = this.repository.checkedExecute("SELECT group_id, invite_reference FROM JoinGroupTransactions WHERE signature = ?", + try (ResultSet resultSet = this.repository.checkedExecute("SELECT group_id, invite_reference, previous_group_id FROM JoinGroupTransactions WHERE signature = ?", signature)) { if (resultSet == null) return null; @@ -25,7 +25,11 @@ public class HSQLDBJoinGroupTransactionRepository extends HSQLDBTransactionRepos int groupId = resultSet.getInt(1); byte[] inviteReference = resultSet.getBytes(2); - return new JoinGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, inviteReference, fee, signature); + Integer previousGroupId = resultSet.getInt(3); + if (resultSet.wasNull()) + previousGroupId = null; + + return new JoinGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, inviteReference, previousGroupId, fee, signature); } catch (SQLException e) { throw new DataException("Unable to fetch join group transaction from repository", e); } @@ -38,7 +42,8 @@ public class HSQLDBJoinGroupTransactionRepository extends HSQLDBTransactionRepos HSQLDBSaver saveHelper = new HSQLDBSaver("JoinGroupTransactions"); saveHelper.bind("signature", joinGroupTransactionData.getSignature()).bind("joiner", joinGroupTransactionData.getJoinerPublicKey()) - .bind("group_id", joinGroupTransactionData.getGroupId()).bind("invite_reference", joinGroupTransactionData.getInviteReference()); + .bind("group_id", joinGroupTransactionData.getGroupId()).bind("invite_reference", joinGroupTransactionData.getInviteReference()) + .bind("previous_group_id", joinGroupTransactionData.getPreviousGroupId()); try { saveHelper.execute(this.repository); diff --git a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBLeaveGroupTransactionRepository.java b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBLeaveGroupTransactionRepository.java index 470fb6a0..fd48906b 100644 --- a/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBLeaveGroupTransactionRepository.java +++ b/src/main/java/org/qora/repository/hsqldb/transaction/HSQLDBLeaveGroupTransactionRepository.java @@ -18,7 +18,7 @@ public class HSQLDBLeaveGroupTransactionRepository extends HSQLDBTransactionRepo TransactionData fromBase(long timestamp, int txGroupId, byte[] reference, byte[] creatorPublicKey, BigDecimal fee, byte[] signature) throws DataException { try (ResultSet resultSet = this.repository - .checkedExecute("SELECT group_id, member_reference, admin_reference FROM LeaveGroupTransactions WHERE signature = ?", signature)) { + .checkedExecute("SELECT group_id, member_reference, admin_reference, previous_group_id FROM LeaveGroupTransactions WHERE signature = ?", signature)) { if (resultSet == null) return null; @@ -26,7 +26,11 @@ public class HSQLDBLeaveGroupTransactionRepository extends HSQLDBTransactionRepo byte[] memberReference = resultSet.getBytes(2); byte[] adminReference = resultSet.getBytes(3); - return new LeaveGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, memberReference, adminReference, fee, signature); + Integer previousGroupId = resultSet.getInt(4); + if (resultSet.wasNull()) + previousGroupId = null; + + return new LeaveGroupTransactionData(timestamp, txGroupId, reference, creatorPublicKey, groupId, memberReference, adminReference, previousGroupId, fee, signature); } catch (SQLException e) { throw new DataException("Unable to fetch leave group transaction from repository", e); } @@ -40,7 +44,7 @@ public class HSQLDBLeaveGroupTransactionRepository extends HSQLDBTransactionRepo saveHelper.bind("signature", leaveGroupTransactionData.getSignature()).bind("leaver", leaveGroupTransactionData.getLeaverPublicKey()) .bind("group_id", leaveGroupTransactionData.getGroupId()).bind("member_reference", leaveGroupTransactionData.getMemberReference()) - .bind("admin_reference", leaveGroupTransactionData.getAdminReference()); + .bind("admin_reference", leaveGroupTransactionData.getAdminReference()).bind("previous_group_id", leaveGroupTransactionData.getPreviousGroupId()); try { saveHelper.execute(this.repository); diff --git a/src/main/java/org/qora/transaction/JoinGroupTransaction.java b/src/main/java/org/qora/transaction/JoinGroupTransaction.java index f9278a61..7cf0c4cd 100644 --- a/src/main/java/org/qora/transaction/JoinGroupTransaction.java +++ b/src/main/java/org/qora/transaction/JoinGroupTransaction.java @@ -113,6 +113,7 @@ public class JoinGroupTransaction extends Transaction { // Update joiner's reference joiner.setLastReference(joinGroupTransactionData.getSignature()); + } @Override