Rename GV2 "version" to "revision".

This commit is contained in:
Alan Evans 2020-05-29 14:35:40 -03:00 committed by Greyson Parrelli
parent c634c24afb
commit a99c0d438e
20 changed files with 137 additions and 138 deletions

View File

@ -336,7 +336,7 @@ public final class GroupDatabase extends Database {
} }
groupId.requireV2(); groupId.requireV2();
contentValues.put(V2_MASTER_KEY, groupMasterKey.serialize()); contentValues.put(V2_MASTER_KEY, groupMasterKey.serialize());
contentValues.put(V2_REVISION, groupState.getVersion()); contentValues.put(V2_REVISION, groupState.getRevision());
contentValues.put(V2_DECRYPTED_GROUP, groupState.toByteArray()); contentValues.put(V2_DECRYPTED_GROUP, groupState.toByteArray());
contentValues.put(MEMBERS, serializeV2GroupMembers(groupState)); contentValues.put(MEMBERS, serializeV2GroupMembers(groupState));
} else { } else {
@ -394,7 +394,7 @@ public final class GroupDatabase extends Database {
UUID uuid = Recipient.self().getUuid().get(); UUID uuid = Recipient.self().getUuid().get();
contentValues.put(TITLE, title); contentValues.put(TITLE, title);
contentValues.put(V2_REVISION, decryptedGroup.getVersion()); contentValues.put(V2_REVISION, decryptedGroup.getRevision());
contentValues.put(V2_DECRYPTED_GROUP, decryptedGroup.toByteArray()); contentValues.put(V2_DECRYPTED_GROUP, decryptedGroup.toByteArray());
contentValues.put(MEMBERS, serializeV2GroupMembers(decryptedGroup)); contentValues.put(MEMBERS, serializeV2GroupMembers(decryptedGroup));
contentValues.put(ACTIVE, DecryptedGroupUtil.findMemberByUuid(decryptedGroup.getMembersList(), uuid).isPresent() || contentValues.put(ACTIVE, DecryptedGroupUtil.findMemberByUuid(decryptedGroup.getMembersList(), uuid).isPresent() ||

View File

@ -56,7 +56,7 @@ final class GroupsV2UpdateMessageProducer {
return context.getString(R.string.MessageRecord_s_invited_you_to_the_group, describe(selfPending.get().getAddedByUuid())); return context.getString(R.string.MessageRecord_s_invited_you_to_the_group, describe(selfPending.get().getAddedByUuid()));
} }
if (group.getVersion() == 0) { if (group.getRevision() == 0) {
Optional<DecryptedMember> foundingMember = DecryptedGroupUtil.firstMember(group.getMembersList()); Optional<DecryptedMember> foundingMember = DecryptedGroupUtil.firstMember(group.getMembersList());
if (foundingMember.isPresent()) { if (foundingMember.isPresent()) {
ByteString foundingMemberUuid = foundingMember.get().getUuid(); ByteString foundingMemberUuid = foundingMember.get().getUuid();

View File

@ -157,7 +157,7 @@ public abstract class MessageRecord extends DisplayRecord {
DecryptedGroupV2Context decryptedGroupV2Context = DecryptedGroupV2Context.parseFrom(decoded); DecryptedGroupV2Context decryptedGroupV2Context = DecryptedGroupV2Context.parseFrom(decoded);
GroupsV2UpdateMessageProducer updateMessageProducer = new GroupsV2UpdateMessageProducer(context, descriptionStrategy, Recipient.self().getUuid().get()); GroupsV2UpdateMessageProducer updateMessageProducer = new GroupsV2UpdateMessageProducer(context, descriptionStrategy, Recipient.self().getUuid().get());
if (decryptedGroupV2Context.hasChange() && decryptedGroupV2Context.getGroupState().getVersion() > 0) { if (decryptedGroupV2Context.hasChange() && decryptedGroupV2Context.getGroupState().getRevision() > 0) {
DecryptedGroupChange change = decryptedGroupV2Context.getChange(); DecryptedGroupChange change = decryptedGroupV2Context.getChange();
List<String> strings = updateMessageProducer.describeChange(change); List<String> strings = updateMessageProducer.describeChange(change);
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();

View File

@ -147,13 +147,13 @@ public final class GroupManager {
@WorkerThread @WorkerThread
public static void updateGroupFromServer(@NonNull Context context, public static void updateGroupFromServer(@NonNull Context context,
@NonNull GroupMasterKey groupMasterKey, @NonNull GroupMasterKey groupMasterKey,
int version, int revision,
long timestamp, long timestamp,
@Nullable byte[] signedGroupChange) @Nullable byte[] signedGroupChange)
throws GroupChangeBusyException, IOException, GroupNotAMemberException throws GroupChangeBusyException, IOException, GroupNotAMemberException
{ {
try (GroupManagerV2.GroupUpdater updater = new GroupManagerV2(context).updater(groupMasterKey)) { try (GroupManagerV2.GroupUpdater updater = new GroupManagerV2(context).updater(groupMasterKey)) {
updater.updateLocalToServerVersion(version, timestamp, signedGroupChange); updater.updateLocalToServerRevision(revision, timestamp, signedGroupChange);
} }
} }

View File

@ -375,7 +375,7 @@ final class GroupManagerV2 {
final GroupDatabase.GroupRecord groupRecord = groupDatabase.requireGroup(groupId); final GroupDatabase.GroupRecord groupRecord = groupDatabase.requireGroup(groupId);
final GroupDatabase.V2GroupProperties v2GroupProperties = groupRecord.requireV2GroupProperties(); final GroupDatabase.V2GroupProperties v2GroupProperties = groupRecord.requireV2GroupProperties();
final int nextRevision = v2GroupProperties.getGroupRevision() + 1; final int nextRevision = v2GroupProperties.getGroupRevision() + 1;
final GroupChange.Actions changeActions = change.setVersion(nextRevision).build(); final GroupChange.Actions changeActions = change.setRevision(nextRevision).build();
final DecryptedGroupChange decryptedChange; final DecryptedGroupChange decryptedChange;
final DecryptedGroup decryptedGroupState; final DecryptedGroup decryptedGroupState;
@ -427,11 +427,11 @@ final class GroupManagerV2 {
} }
@WorkerThread @WorkerThread
void updateLocalToServerVersion(int version, long timestamp, @Nullable byte[] signedGroupChange) void updateLocalToServerRevision(int revision, long timestamp, @Nullable byte[] signedGroupChange)
throws IOException, GroupNotAMemberException throws IOException, GroupNotAMemberException
{ {
new GroupsV2StateProcessor(context).forGroup(groupMasterKey) new GroupsV2StateProcessor(context).forGroup(groupMasterKey)
.updateLocalGroupToRevision(version, timestamp, getDecryptedGroupChange(signedGroupChange)); .updateLocalGroupToRevision(revision, timestamp, getDecryptedGroupChange(signedGroupChange));
} }
private DecryptedGroupChange getDecryptedGroupChange(@Nullable byte[] signedGroupChange) { private DecryptedGroupChange getDecryptedGroupChange(@Nullable byte[] signedGroupChange) {

View File

@ -15,11 +15,11 @@ import org.signal.storageservice.protos.groups.local.DecryptedMember;
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember; import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
import org.signal.zkgroup.groups.GroupMasterKey; import org.signal.zkgroup.groups.GroupMasterKey;
import org.signal.zkgroup.util.UUIDUtil; import org.signal.zkgroup.util.UUIDUtil;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.whispersystems.signalservice.api.util.UuidUtil;
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
import org.thoughtcrime.securesms.database.model.databaseprotos.DecryptedGroupV2Context; import org.thoughtcrime.securesms.database.model.databaseprotos.DecryptedGroupV2Context;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
import org.whispersystems.signalservice.api.util.UuidUtil;
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@ -29,19 +29,19 @@ public final class GroupProtoUtil {
private GroupProtoUtil() { private GroupProtoUtil() {
} }
public static int findVersionWeWereAdded(@NonNull DecryptedGroup group, @NonNull UUID uuid) public static int findRevisionWeWereAdded(@NonNull DecryptedGroup group, @NonNull UUID uuid)
throws GroupNotAMemberException throws GroupNotAMemberException
{ {
ByteString bytes = UuidUtil.toByteString(uuid); ByteString bytes = UuidUtil.toByteString(uuid);
for (DecryptedMember decryptedMember : group.getMembersList()) { for (DecryptedMember decryptedMember : group.getMembersList()) {
if (decryptedMember.getUuid().equals(bytes)) { if (decryptedMember.getUuid().equals(bytes)) {
return decryptedMember.getJoinedAtVersion(); return decryptedMember.getJoinedAtRevision();
} }
} }
for (DecryptedPendingMember decryptedMember : group.getPendingMembersList()) { for (DecryptedPendingMember decryptedMember : group.getPendingMembersList()) {
if (decryptedMember.getUuid().equals(bytes)) { if (decryptedMember.getUuid().equals(bytes)) {
// Assume latest, we don't have any information about when pending members were invited // Assume latest, we don't have any information about when pending members were invited
return group.getVersion(); return group.getRevision();
} }
} }
throw new GroupNotAMemberException(); throw new GroupNotAMemberException();
@ -52,10 +52,10 @@ public final class GroupProtoUtil {
@Nullable DecryptedGroupChange plainGroupChange, @Nullable DecryptedGroupChange plainGroupChange,
@Nullable GroupChange signedServerChange) @Nullable GroupChange signedServerChange)
{ {
int version = plainGroupChange != null ? plainGroupChange.getVersion() : decryptedGroup.getVersion(); int revision = plainGroupChange != null ? plainGroupChange.getRevision() : decryptedGroup.getRevision();
SignalServiceProtos.GroupContextV2.Builder contextBuilder = SignalServiceProtos.GroupContextV2.newBuilder() SignalServiceProtos.GroupContextV2.Builder contextBuilder = SignalServiceProtos.GroupContextV2.newBuilder()
.setMasterKey(ByteString.copyFrom(masterKey.serialize())) .setMasterKey(ByteString.copyFrom(masterKey.serialize()))
.setRevision(version); .setRevision(revision);
if (signedServerChange != null) { if (signedServerChange != null) {
contextBuilder.setGroupChange(signedServerChange.toByteString()); contextBuilder.setGroupChange(signedServerChange.toByteString());

View File

@ -31,13 +31,13 @@ final class GlobalGroupState {
return history; return history;
} }
int getLatestVersionNumber() { int getLatestRevisionNumber() {
if (history.isEmpty()) { if (history.isEmpty()) {
if (localState == null) { if (localState == null) {
throw new AssertionError(); throw new AssertionError();
} }
return localState.getVersion(); return localState.getRevision();
} }
return history.get(history.size() - 1).getGroup().getVersion(); return history.get(history.size() - 1).getGroup().getRevision();
} }
} }

View File

@ -17,7 +17,7 @@ final class GroupLogEntry {
@Nullable private final DecryptedGroupChange change; @Nullable private final DecryptedGroupChange change;
GroupLogEntry(@NonNull DecryptedGroup group, @Nullable DecryptedGroupChange change) { GroupLogEntry(@NonNull DecryptedGroup group, @Nullable DecryptedGroupChange change) {
if (change != null && group.getVersion() != change.getVersion()) { if (change != null && group.getRevision() != change.getRevision()) {
throw new AssertionError(); throw new AssertionError();
} }

View File

@ -12,20 +12,20 @@ final class GroupStateMapper {
static final int LATEST = Integer.MAX_VALUE; static final int LATEST = Integer.MAX_VALUE;
private static final Comparator<GroupLogEntry> BY_VERSION = (o1, o2) -> Integer.compare(o1.getGroup().getVersion(), o2.getGroup().getVersion()); private static final Comparator<GroupLogEntry> BY_REVISION = (o1, o2) -> Integer.compare(o1.getGroup().getRevision(), o2.getGroup().getRevision());
private GroupStateMapper() { private GroupStateMapper() {
} }
/** /**
* Given an input {@link GlobalGroupState} and a {@param maximumVersionToApply}, returns a result * Given an input {@link GlobalGroupState} and a {@param maximumRevisionToApply}, returns a result
* containing what the new local group state should be, and any remaining version history to apply. * containing what the new local group state should be, and any remaining revision history to apply.
* <p> * <p>
* Function is pure. * Function is pure.
* @param maximumVersionToApply Use {@link #LATEST} to apply the very latest. * @param maximumRevisionToApply Use {@link #LATEST} to apply the very latest.
*/ */
static @NonNull AdvanceGroupStateResult partiallyAdvanceGroupState(@NonNull GlobalGroupState inputState, static @NonNull AdvanceGroupStateResult partiallyAdvanceGroupState(@NonNull GlobalGroupState inputState,
int maximumVersionToApply) int maximumRevisionToApply)
{ {
final ArrayList<GroupLogEntry> statesToApplyNow = new ArrayList<>(inputState.getHistory().size()); final ArrayList<GroupLogEntry> statesToApplyNow = new ArrayList<>(inputState.getHistory().size());
final ArrayList<GroupLogEntry> statesToApplyLater = new ArrayList<>(inputState.getHistory().size()); final ArrayList<GroupLogEntry> statesToApplyLater = new ArrayList<>(inputState.getHistory().size());
@ -34,20 +34,20 @@ final class GroupStateMapper {
for (GroupLogEntry entry : inputState.getHistory()) { for (GroupLogEntry entry : inputState.getHistory()) {
if (inputState.getLocalState() != null && if (inputState.getLocalState() != null &&
inputState.getLocalState().getVersion() >= entry.getGroup().getVersion()) inputState.getLocalState().getRevision() >= entry.getGroup().getRevision())
{ {
continue; continue;
} }
if (entry.getGroup().getVersion() > maximumVersionToApply) { if (entry.getGroup().getRevision() > maximumRevisionToApply) {
statesToApplyLater.add(entry); statesToApplyLater.add(entry);
} else { } else {
statesToApplyNow.add(entry); statesToApplyNow.add(entry);
} }
} }
Collections.sort(statesToApplyNow, BY_VERSION); Collections.sort(statesToApplyNow, BY_REVISION);
Collections.sort(statesToApplyLater, BY_VERSION); Collections.sort(statesToApplyLater, BY_REVISION);
if (statesToApplyNow.size() > 0) { if (statesToApplyNow.size() > 0) {
newLocalState = statesToApplyNow.get(statesToApplyNow.size() - 1) newLocalState = statesToApplyNow.get(statesToApplyNow.size() - 1)

View File

@ -13,7 +13,6 @@ import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
import org.signal.zkgroup.VerificationFailedException; import org.signal.zkgroup.VerificationFailedException;
import org.signal.zkgroup.groups.GroupMasterKey; import org.signal.zkgroup.groups.GroupMasterKey;
import org.signal.zkgroup.groups.GroupSecretParams; import org.signal.zkgroup.groups.GroupSecretParams;
import org.signal.zkgroup.util.UUIDUtil;
import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.MmsDatabase;
@ -150,8 +149,8 @@ public final class GroupsV2StateProcessor {
if (signedGroupChange != null && if (signedGroupChange != null &&
localState != null && localState != null &&
localState.getVersion() + 1 == signedGroupChange.getVersion() && localState.getRevision() + 1 == signedGroupChange.getRevision() &&
revision == signedGroupChange.getVersion()) revision == signedGroupChange.getRevision())
{ {
try { try {
Log.i(TAG, "Applying P2P group change"); Log.i(TAG, "Applying P2P group change");
@ -188,7 +187,7 @@ public final class GroupsV2StateProcessor {
GlobalGroupState remainingWork = advanceGroupStateResult.getNewGlobalGroupState(); GlobalGroupState remainingWork = advanceGroupStateResult.getNewGlobalGroupState();
if (remainingWork.getHistory().size() > 0) { if (remainingWork.getHistory().size() > 0) {
Log.i(TAG, String.format(Locale.US, "There are more versions on the server for this group, not applying at this time, V[%d..%d]", newLocalState.getVersion() + 1, remainingWork.getLatestVersionNumber())); Log.i(TAG, String.format(Locale.US, "There are more revisions on the server for this group, not applying at this time, V[%d..%d]", newLocalState.getRevision() + 1, remainingWork.getLatestRevisionNumber()));
} }
return new GroupUpdateResult(GroupState.GROUP_UPDATED, newLocalState); return new GroupUpdateResult(GroupState.GROUP_UPDATED, newLocalState);
@ -206,10 +205,10 @@ public final class GroupsV2StateProcessor {
.requireV2GroupProperties() .requireV2GroupProperties()
.getDecryptedGroup(); .getDecryptedGroup();
DecryptedGroup simulatedGroupState = DecryptedGroupUtil.removeMember(decryptedGroup, selfUuid, decryptedGroup.getVersion() + 1); DecryptedGroup simulatedGroupState = DecryptedGroupUtil.removeMember(decryptedGroup, selfUuid, decryptedGroup.getRevision() + 1);
DecryptedGroupChange simulatedGroupChange = DecryptedGroupChange.newBuilder() DecryptedGroupChange simulatedGroupChange = DecryptedGroupChange.newBuilder()
.setEditor(UuidUtil.toByteString(UuidUtil.UNKNOWN_UUID)) .setEditor(UuidUtil.toByteString(UuidUtil.UNKNOWN_UUID))
.setVersion(simulatedGroupState.getVersion()) .setRevision(simulatedGroupState.getRevision())
.addDeleteMembers(UuidUtil.toByteString(selfUuid)) .addDeleteMembers(UuidUtil.toByteString(selfUuid))
.build(); .build();
@ -315,8 +314,8 @@ public final class GroupsV2StateProcessor {
if (latestOnly || !GroupProtoUtil.isMember(selfUuid, latestServerGroup.getMembersList())) { if (latestOnly || !GroupProtoUtil.isMember(selfUuid, latestServerGroup.getMembersList())) {
history = Collections.singletonList(new GroupLogEntry(latestServerGroup, null)); history = Collections.singletonList(new GroupLogEntry(latestServerGroup, null));
} else { } else {
int versionWeWereAdded = GroupProtoUtil.findVersionWeWereAdded(latestServerGroup, selfUuid); int revisionWeWereAdded = GroupProtoUtil.findRevisionWeWereAdded(latestServerGroup, selfUuid);
int logsNeededFrom = localState != null ? Math.max(localState.getVersion(), versionWeWereAdded) : versionWeWereAdded; int logsNeededFrom = localState != null ? Math.max(localState.getRevision(), revisionWeWereAdded) : revisionWeWereAdded;
history = getFullMemberHistory(selfUuid, logsNeededFrom); history = getFullMemberHistory(selfUuid, logsNeededFrom);
} }
@ -324,9 +323,9 @@ public final class GroupsV2StateProcessor {
return new GlobalGroupState(localState, history); return new GlobalGroupState(localState, history);
} }
private List<GroupLogEntry> getFullMemberHistory(@NonNull UUID selfUuid, int logsNeededFrom) throws IOException { private List<GroupLogEntry> getFullMemberHistory(@NonNull UUID selfUuid, int logsNeededFromRevision) throws IOException {
try { try {
Collection<DecryptedGroupHistoryEntry> groupStatesFromRevision = groupsV2Api.getGroupHistory(groupSecretParams, logsNeededFrom, groupsV2Authorization.getAuthorizationForToday(selfUuid, groupSecretParams)); Collection<DecryptedGroupHistoryEntry> groupStatesFromRevision = groupsV2Api.getGroupHistory(groupSecretParams, logsNeededFromRevision, groupsV2Authorization.getAuthorizationForToday(selfUuid, groupSecretParams));
ArrayList<GroupLogEntry> history = new ArrayList<>(groupStatesFromRevision.size()); ArrayList<GroupLogEntry> history = new ArrayList<>(groupStatesFromRevision.size());
for (DecryptedGroupHistoryEntry entry : groupStatesFromRevision) { for (DecryptedGroupHistoryEntry entry : groupStatesFromRevision) {

View File

@ -545,9 +545,9 @@ public final class GroupsV2UpdateMessageProducerTest {
private final DecryptedGroup.Builder builder; private final DecryptedGroup.Builder builder;
GroupStateBuilder(@NonNull UUID foundingMember, int version) { GroupStateBuilder(@NonNull UUID foundingMember, int revision) {
builder = DecryptedGroup.newBuilder() builder = DecryptedGroup.newBuilder()
.setVersion(version) .setRevision(revision)
.addMembers(DecryptedMember.newBuilder() .addMembers(DecryptedMember.newBuilder()
.setUuid(UuidUtil.toByteString(foundingMember))); .setUuid(UuidUtil.toByteString(foundingMember)));
} }

View File

@ -14,32 +14,32 @@ public final class GlobalGroupStateTest {
public void cannot_ask_latestVersionNumber_of_empty_state() { public void cannot_ask_latestVersionNumber_of_empty_state() {
GlobalGroupState emptyState = new GlobalGroupState(null, emptyList()); GlobalGroupState emptyState = new GlobalGroupState(null, emptyList());
emptyState.getLatestVersionNumber(); emptyState.getLatestRevisionNumber();
} }
@Test @Test
public void latestVersionNumber_of_state_and_empty_list() { public void latestRevisionNumber_of_state_and_empty_list() {
GlobalGroupState emptyState = new GlobalGroupState(state(10), emptyList()); GlobalGroupState emptyState = new GlobalGroupState(state(10), emptyList());
assertEquals(10, emptyState.getLatestVersionNumber()); assertEquals(10, emptyState.getLatestRevisionNumber());
} }
@Test @Test
public void latestVersionNumber_of_state_and_list() { public void latestRevisionNumber_of_state_and_list() {
GlobalGroupState emptyState = new GlobalGroupState(state(2), asList(logEntry(3), logEntry(4))); GlobalGroupState emptyState = new GlobalGroupState(state(2), asList(logEntry(3), logEntry(4)));
assertEquals(4, emptyState.getLatestVersionNumber()); assertEquals(4, emptyState.getLatestRevisionNumber());
} }
private static GroupLogEntry logEntry(int version) { private static GroupLogEntry logEntry(int revision) {
return new GroupLogEntry(state(version), change(version)); return new GroupLogEntry(state(revision), change(revision));
} }
private static DecryptedGroup state(int version) { private static DecryptedGroup state(int revision) {
return DecryptedGroup.newBuilder().setVersion(version).build(); return DecryptedGroup.newBuilder().setRevision(revision).build();
} }
private static DecryptedGroupChange change(int version) { private static DecryptedGroupChange change(int revision) {
return DecryptedGroupChange.newBuilder().setVersion(version).build(); return DecryptedGroupChange.newBuilder().setRevision(revision).build();
} }
} }

View File

@ -115,7 +115,7 @@ public final class GroupStateMapperTest {
} }
@Test @Test
public void apply_maximum_group_versions() { public void apply_maximum_group_revisions() {
DecryptedGroup currentState = state(Integer.MAX_VALUE - 2); DecryptedGroup currentState = state(Integer.MAX_VALUE - 2);
GroupLogEntry log1 = logEntry(Integer.MAX_VALUE - 1); GroupLogEntry log1 = logEntry(Integer.MAX_VALUE - 1);
GroupLogEntry log2 = logEntry(Integer.MAX_VALUE); GroupLogEntry log2 = logEntry(Integer.MAX_VALUE);
@ -132,15 +132,15 @@ public final class GroupStateMapperTest {
assertThat(actual.getHistory(), is(expected.getHistory())); assertThat(actual.getHistory(), is(expected.getHistory()));
} }
private static GroupLogEntry logEntry(int version) { private static GroupLogEntry logEntry(int revision) {
return new GroupLogEntry(state(version), change(version)); return new GroupLogEntry(state(revision), change(revision));
} }
private static DecryptedGroup state(int version) { private static DecryptedGroup state(int revision) {
return DecryptedGroup.newBuilder().setVersion(version).build(); return DecryptedGroup.newBuilder().setRevision(revision).build();
} }
private static DecryptedGroupChange change(int version) { private static DecryptedGroupChange change(int revision) {
return DecryptedGroupChange.newBuilder().setVersion(version).build(); return DecryptedGroupChange.newBuilder().setRevision(revision).build();
} }
} }

View File

@ -12,7 +12,7 @@ public final class DecryptedGroupHistoryEntry {
private final DecryptedGroupChange change; private final DecryptedGroupChange change;
DecryptedGroupHistoryEntry(DecryptedGroup group, DecryptedGroupChange change) { DecryptedGroupHistoryEntry(DecryptedGroup group, DecryptedGroupChange change) {
if (group.getVersion() != change.getVersion()) { if (group.getRevision() != change.getRevision()) {
throw new AssertionError(); throw new AssertionError();
} }

View File

@ -171,7 +171,7 @@ public final class DecryptedGroupUtil {
if (removed) { if (removed) {
return builder.clearMembers() return builder.clearMembers()
.addAllMembers(decryptedMembers) .addAllMembers(decryptedMembers)
.setVersion(revision) .setRevision(revision)
.build(); .build();
} else { } else {
return group; return group;
@ -181,7 +181,7 @@ public final class DecryptedGroupUtil {
public static DecryptedGroup apply(DecryptedGroup group, DecryptedGroupChange change) public static DecryptedGroup apply(DecryptedGroup group, DecryptedGroupChange change)
throws NotAbleToApplyChangeException throws NotAbleToApplyChangeException
{ {
if (change.getVersion() != group.getVersion() + 1) { if (change.getRevision() != group.getRevision() + 1) {
throw new NotAbleToApplyChangeException(); throw new NotAbleToApplyChangeException();
} }
@ -266,7 +266,7 @@ public final class DecryptedGroupUtil {
.build()); .build());
} }
return builder.setVersion(change.getVersion()).build(); return builder.setRevision(change.getRevision()).build();
} }
private static int indexOfUuid(List<DecryptedMember> memberList, ByteString uuid) { private static int indexOfUuid(List<DecryptedMember> memberList, ByteString uuid) {

View File

@ -103,7 +103,7 @@ public final class GroupsV2Api {
DecryptedGroup decryptedGroup = groupOperations.decryptGroup(change.getGroupState()); DecryptedGroup decryptedGroup = groupOperations.decryptGroup(change.getGroupState());
DecryptedGroupChange decryptedChange = groupOperations.decryptChange(change.getGroupChange(), false); DecryptedGroupChange decryptedChange = groupOperations.decryptChange(change.getGroupChange(), false);
if (decryptedChange.getVersion() != decryptedGroup.getVersion()) { if (decryptedChange.getRevision() != decryptedGroup.getRevision()) {
throw new InvalidGroupStateException(); throw new InvalidGroupStateException();
} }

View File

@ -83,7 +83,7 @@ public final class GroupsV2Operations {
final GroupOperations groupOperations = forGroup(groupSecretParams); final GroupOperations groupOperations = forGroup(groupSecretParams);
Group.Builder group = Group.newBuilder() Group.Builder group = Group.newBuilder()
.setVersion(0) .setRevision(0)
.setPublicKey(ByteString.copyFrom(groupSecretParams.getPublicParams().serialize())) .setPublicKey(ByteString.copyFrom(groupSecretParams.getPublicParams().serialize()))
.setTitle(groupOperations.encryptTitle(title)) .setTitle(groupOperations.encryptTitle(title))
.setDisappearingMessagesTimer(groupOperations.encryptTimer(0)) .setDisappearingMessagesTimer(groupOperations.encryptTimer(0))
@ -281,7 +281,7 @@ public final class GroupsV2Operations {
.setTitle(decryptTitle(group.getTitle())) .setTitle(decryptTitle(group.getTitle()))
.setAvatar(group.getAvatar()) .setAvatar(group.getAvatar())
.setAccessControl(group.getAccessControl()) .setAccessControl(group.getAccessControl())
.setVersion(group.getVersion()) .setRevision(group.getRevision())
.addAllMembers(decryptedMembers) .addAllMembers(decryptedMembers)
.addAllPendingMembers(decryptedPendingMembers) .addAllPendingMembers(decryptedPendingMembers)
.setDisappearingMessagesTimer(DecryptedTimer.newBuilder().setDuration(decryptDisappearingMessagesTimer(group.getDisappearingMessagesTimer()))) .setDisappearingMessagesTimer(DecryptedTimer.newBuilder().setDuration(decryptDisappearingMessagesTimer(group.getDisappearingMessagesTimer())))
@ -322,12 +322,12 @@ public final class GroupsV2Operations {
} }
// Field 2 // Field 2
builder.setVersion(actions.getVersion()); builder.setRevision(actions.getRevision());
// Field 3 // Field 3
for (GroupChange.Actions.AddMemberAction addMemberAction : actions.getAddMembersList()) { for (GroupChange.Actions.AddMemberAction addMemberAction : actions.getAddMembersList()) {
try { try {
builder.addNewMembers(decryptMember(addMemberAction.getAdded()).setJoinedAtVersion(actions.getVersion())); builder.addNewMembers(decryptMember(addMemberAction.getAdded()).setJoinedAtRevision(actions.getRevision()));
} catch (InvalidInputException e) { } catch (InvalidInputException e) {
throw new InvalidGroupStateException(e); throw new InvalidGroupStateException(e);
} }
@ -354,7 +354,7 @@ public final class GroupsV2Operations {
UUID uuid = decryptUuid(ByteString.copyFrom(presentation.getUuidCiphertext().serialize())); UUID uuid = decryptUuid(ByteString.copyFrom(presentation.getUuidCiphertext().serialize()));
builder.addModifiedProfileKeys(DecryptedMember.newBuilder() builder.addModifiedProfileKeys(DecryptedMember.newBuilder()
.setRole(Member.Role.UNKNOWN) .setRole(Member.Role.UNKNOWN)
.setJoinedAtVersion(-1) .setJoinedAtRevision(-1)
.setUuid(UuidUtil.toByteString(uuid)) .setUuid(UuidUtil.toByteString(uuid))
.setProfileKey(ByteString.copyFrom(decryptProfileKey(ByteString.copyFrom(presentation.getProfileKeyCiphertext().serialize()), uuid).serialize()))); .setProfileKey(ByteString.copyFrom(decryptProfileKey(ByteString.copyFrom(presentation.getProfileKeyCiphertext().serialize()), uuid).serialize())));
} catch (InvalidInputException e) { } catch (InvalidInputException e) {
@ -398,7 +398,7 @@ public final class GroupsV2Operations {
UUID uuid = clientZkGroupCipher.decryptUuid(profileKeyCredentialPresentation.getUuidCiphertext()); UUID uuid = clientZkGroupCipher.decryptUuid(profileKeyCredentialPresentation.getUuidCiphertext());
ProfileKey profileKey = clientZkGroupCipher.decryptProfileKey(profileKeyCredentialPresentation.getProfileKeyCiphertext(), uuid); ProfileKey profileKey = clientZkGroupCipher.decryptProfileKey(profileKeyCredentialPresentation.getProfileKeyCiphertext(), uuid);
builder.addPromotePendingMembers(DecryptedMember.newBuilder() builder.addPromotePendingMembers(DecryptedMember.newBuilder()
.setJoinedAtVersion(-1) .setJoinedAtRevision(-1)
.setRole(Member.Role.DEFAULT) .setRole(Member.Role.DEFAULT)
.setUuid(UuidUtil.toByteString(uuid)) .setUuid(UuidUtil.toByteString(uuid))
.setProfileKey(ByteString.copyFrom(profileKey.serialize()))); .setProfileKey(ByteString.copyFrom(profileKey.serialize())));
@ -441,7 +441,7 @@ public final class GroupsV2Operations {
return DecryptedMember.newBuilder() return DecryptedMember.newBuilder()
.setUuid(UuidUtil.toByteString(uuid)) .setUuid(UuidUtil.toByteString(uuid))
.setJoinedAtVersion(member.getJoinedAtVersion()) .setJoinedAtRevision(member.getJoinedAtRevision())
.setProfileKey(decryptProfileKeyToByteString(member.getProfileKey(), uuid)) .setProfileKey(decryptProfileKeyToByteString(member.getProfileKey(), uuid))
.setRole(member.getRole()); .setRole(member.getRole());
} else { } else {
@ -451,7 +451,7 @@ public final class GroupsV2Operations {
return DecryptedMember.newBuilder() return DecryptedMember.newBuilder()
.setUuid(UuidUtil.toByteString(uuid)) .setUuid(UuidUtil.toByteString(uuid))
.setJoinedAtVersion(member.getJoinedAtVersion()) .setJoinedAtRevision(member.getJoinedAtRevision())
.setProfileKey(ByteString.copyFrom(profileKey.serialize())) .setProfileKey(ByteString.copyFrom(profileKey.serialize()))
.setRole(member.getRole()); .setRole(member.getRole());
} }

View File

@ -13,10 +13,10 @@ import "Groups.proto";
// Decrypted version of Member // Decrypted version of Member
// Keep field numbers in step // Keep field numbers in step
message DecryptedMember { message DecryptedMember {
bytes uuid = 1; bytes uuid = 1;
Member.Role role = 2; Member.Role role = 2;
bytes profileKey = 3; bytes profileKey = 3;
uint32 joinedAtVersion = 5; uint32 joinedAtRevision = 5;
} }
message DecryptedPendingMember { message DecryptedPendingMember {
@ -44,7 +44,7 @@ message DecryptedGroup {
string avatar = 3; string avatar = 3;
DecryptedTimer disappearingMessagesTimer = 4; DecryptedTimer disappearingMessagesTimer = 4;
AccessControl accessControl = 5; AccessControl accessControl = 5;
uint32 version = 6; uint32 revision = 6;
repeated DecryptedMember members = 7; repeated DecryptedMember members = 7;
repeated DecryptedPendingMember pendingMembers = 8; repeated DecryptedPendingMember pendingMembers = 8;
} }
@ -53,7 +53,7 @@ message DecryptedGroup {
// Keep field numbers in step // Keep field numbers in step
message DecryptedGroupChange { message DecryptedGroupChange {
bytes editor = 1; bytes editor = 1;
uint32 version = 2; uint32 revision = 2;
repeated DecryptedMember newMembers = 3; repeated DecryptedMember newMembers = 3;
repeated bytes deleteMembers = 4; repeated bytes deleteMembers = 4;
repeated DecryptedModifyMemberRole modifyMemberRoles = 5; repeated DecryptedModifyMemberRole modifyMemberRoles = 5;

View File

@ -25,11 +25,11 @@ message Member {
ADMINISTRATOR = 2; ADMINISTRATOR = 2;
} }
bytes userId = 1; bytes userId = 1;
Role role = 2; Role role = 2;
bytes profileKey = 3; bytes profileKey = 3;
bytes presentation = 4; bytes presentation = 4;
uint32 joinedAtVersion = 5; uint32 joinedAtRevision = 5;
} }
message PendingMember { message PendingMember {
@ -56,7 +56,7 @@ message Group {
string avatar = 3; string avatar = 3;
bytes disappearingMessagesTimer = 4; bytes disappearingMessagesTimer = 4;
AccessControl accessControl = 5; AccessControl accessControl = 5;
uint32 version = 6; uint32 revision = 6;
repeated Member members = 7; repeated Member members = 7;
repeated PendingMember pendingMembers = 8; repeated PendingMember pendingMembers = 8;
} }
@ -115,7 +115,7 @@ message GroupChange {
} }
bytes sourceUuid = 1; bytes sourceUuid = 1;
uint32 version = 2; uint32 revision = 2;
repeated AddMemberAction addMembers = 3; repeated AddMemberAction addMembers = 3;
repeated DeleteMemberAction deleteMembers = 4; repeated DeleteMemberAction deleteMembers = 4;
repeated ModifyMemberRoleAction modifyMemberRoles = 5; repeated ModifyMemberRoleAction modifyMemberRoles = 5;

View File

@ -27,15 +27,15 @@ import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.withP
public final class DecryptedGroupUtil_apply_Test { public final class DecryptedGroupUtil_apply_Test {
@Test @Test
public void apply_version() throws DecryptedGroupUtil.NotAbleToApplyChangeException { public void apply_revision() throws DecryptedGroupUtil.NotAbleToApplyChangeException {
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setVersion(9) .setRevision(9)
.build(), .build(),
DecryptedGroupChange.newBuilder() DecryptedGroupChange.newBuilder()
.setVersion(10) .setRevision(10)
.build()); .build());
assertEquals(10, newGroup.getVersion()); assertEquals(10, newGroup.getRevision());
} }
@Test @Test
@ -44,16 +44,16 @@ public final class DecryptedGroupUtil_apply_Test {
DecryptedMember member2 = member(UUID.randomUUID()); DecryptedMember member2 = member(UUID.randomUUID());
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setVersion(10) .setRevision(10)
.addMembers(member1) .addMembers(member1)
.build(), .build(),
DecryptedGroupChange.newBuilder() DecryptedGroupChange.newBuilder()
.setVersion(11) .setRevision(11)
.addNewMembers(member2) .addNewMembers(member2)
.build()); .build());
assertEquals(DecryptedGroup.newBuilder() assertEquals(DecryptedGroup.newBuilder()
.setVersion(11) .setRevision(11)
.addMembers(member1) .addMembers(member1)
.addMembers(member2) .addMembers(member2)
.build(), .build(),
@ -66,17 +66,17 @@ public final class DecryptedGroupUtil_apply_Test {
DecryptedMember member2 = member(UUID.randomUUID()); DecryptedMember member2 = member(UUID.randomUUID());
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setVersion(13) .setRevision(13)
.addMembers(member1) .addMembers(member1)
.addMembers(member2) .addMembers(member2)
.build(), .build(),
DecryptedGroupChange.newBuilder() DecryptedGroupChange.newBuilder()
.setVersion(14) .setRevision(14)
.addDeleteMembers(member1.getUuid()) .addDeleteMembers(member1.getUuid())
.build()); .build());
assertEquals(DecryptedGroup.newBuilder() assertEquals(DecryptedGroup.newBuilder()
.setVersion(14) .setRevision(14)
.addMembers(member2) .addMembers(member2)
.build(), .build(),
newGroup); newGroup);
@ -88,18 +88,18 @@ public final class DecryptedGroupUtil_apply_Test {
DecryptedMember member2 = member(UUID.randomUUID()); DecryptedMember member2 = member(UUID.randomUUID());
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setVersion(13) .setRevision(13)
.addMembers(member1) .addMembers(member1)
.addMembers(member2) .addMembers(member2)
.build(), .build(),
DecryptedGroupChange.newBuilder() DecryptedGroupChange.newBuilder()
.setVersion(14) .setRevision(14)
.addDeleteMembers(member1.getUuid()) .addDeleteMembers(member1.getUuid())
.addDeleteMembers(member2.getUuid()) .addDeleteMembers(member2.getUuid())
.build()); .build());
assertEquals(DecryptedGroup.newBuilder() assertEquals(DecryptedGroup.newBuilder()
.setVersion(14) .setRevision(14)
.build(), .build(),
newGroup); newGroup);
} }
@ -110,11 +110,11 @@ public final class DecryptedGroupUtil_apply_Test {
DecryptedMember member2 = member(UUID.randomUUID()); DecryptedMember member2 = member(UUID.randomUUID());
DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setVersion(13) .setRevision(13)
.addMembers(member1) .addMembers(member1)
.build(), .build(),
DecryptedGroupChange.newBuilder() DecryptedGroupChange.newBuilder()
.setVersion(14) .setRevision(14)
.addDeleteMembers(member2.getUuid()) .addDeleteMembers(member2.getUuid())
.build()); .build());
} }
@ -125,18 +125,18 @@ public final class DecryptedGroupUtil_apply_Test {
DecryptedMember member2 = admin(UUID.randomUUID()); DecryptedMember member2 = admin(UUID.randomUUID());
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setVersion(13) .setRevision(13)
.addMembers(member1) .addMembers(member1)
.addMembers(member2) .addMembers(member2)
.build(), .build(),
DecryptedGroupChange.newBuilder() DecryptedGroupChange.newBuilder()
.setVersion(14) .setRevision(14)
.addModifyMemberRoles(DecryptedModifyMemberRole.newBuilder().setUuid(member1.getUuid()).setRole(Member.Role.ADMINISTRATOR)) .addModifyMemberRoles(DecryptedModifyMemberRole.newBuilder().setUuid(member1.getUuid()).setRole(Member.Role.ADMINISTRATOR))
.addModifyMemberRoles(DecryptedModifyMemberRole.newBuilder().setUuid(member2.getUuid()).setRole(Member.Role.DEFAULT)) .addModifyMemberRoles(DecryptedModifyMemberRole.newBuilder().setUuid(member2.getUuid()).setRole(Member.Role.DEFAULT))
.build()); .build());
assertEquals(DecryptedGroup.newBuilder() assertEquals(DecryptedGroup.newBuilder()
.setVersion(14) .setRevision(14)
.addMembers(asAdmin(member1)) .addMembers(asAdmin(member1))
.addMembers(asMember(member2)) .addMembers(asMember(member2))
.build(), .build(),
@ -153,17 +153,17 @@ public final class DecryptedGroupUtil_apply_Test {
DecryptedMember member2b = withProfileKey(member2a, profileKey2b); DecryptedMember member2b = withProfileKey(member2a, profileKey2b);
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setVersion(13) .setRevision(13)
.addMembers(member1) .addMembers(member1)
.addMembers(member2a) .addMembers(member2a)
.build(), .build(),
DecryptedGroupChange.newBuilder() DecryptedGroupChange.newBuilder()
.setVersion(14) .setRevision(14)
.addModifiedProfileKeys(member2b) .addModifiedProfileKeys(member2b)
.build()); .build());
assertEquals(DecryptedGroup.newBuilder() assertEquals(DecryptedGroup.newBuilder()
.setVersion(14) .setRevision(14)
.addMembers(member1) .addMembers(member1)
.addMembers(member2b) .addMembers(member2b)
.build(), .build(),
@ -176,16 +176,16 @@ public final class DecryptedGroupUtil_apply_Test {
DecryptedPendingMember pending = pendingMember(UUID.randomUUID()); DecryptedPendingMember pending = pendingMember(UUID.randomUUID());
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setVersion(10) .setRevision(10)
.addMembers(member1) .addMembers(member1)
.build(), .build(),
DecryptedGroupChange.newBuilder() DecryptedGroupChange.newBuilder()
.setVersion(11) .setRevision(11)
.addNewPendingMembers(pending) .addNewPendingMembers(pending)
.build()); .build());
assertEquals(DecryptedGroup.newBuilder() assertEquals(DecryptedGroup.newBuilder()
.setVersion(11) .setRevision(11)
.addMembers(member1) .addMembers(member1)
.addPendingMembers(pending) .addPendingMembers(pending)
.build(), .build(),
@ -199,19 +199,19 @@ public final class DecryptedGroupUtil_apply_Test {
DecryptedPendingMember pending = pendingMember(pendingUuid); DecryptedPendingMember pending = pendingMember(pendingUuid);
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setVersion(10) .setRevision(10)
.addMembers(member1) .addMembers(member1)
.addPendingMembers(pending) .addPendingMembers(pending)
.build(), .build(),
DecryptedGroupChange.newBuilder() DecryptedGroupChange.newBuilder()
.setVersion(11) .setRevision(11)
.addDeletePendingMembers(DecryptedPendingMemberRemoval.newBuilder() .addDeletePendingMembers(DecryptedPendingMemberRemoval.newBuilder()
.setUuidCipherText(ProtoTestUtils.encrypt(pendingUuid)) .setUuidCipherText(ProtoTestUtils.encrypt(pendingUuid))
.build()) .build())
.build()); .build());
assertEquals(DecryptedGroup.newBuilder() assertEquals(DecryptedGroup.newBuilder()
.setVersion(11) .setRevision(11)
.addMembers(member1) .addMembers(member1)
.build(), .build(),
newGroup); newGroup);
@ -226,17 +226,17 @@ public final class DecryptedGroupUtil_apply_Test {
DecryptedMember member2 = member(pending2Uuid, profileKey2); DecryptedMember member2 = member(pending2Uuid, profileKey2);
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setVersion(10) .setRevision(10)
.addMembers(member1) .addMembers(member1)
.addPendingMembers(pending2) .addPendingMembers(pending2)
.build(), .build(),
DecryptedGroupChange.newBuilder() DecryptedGroupChange.newBuilder()
.setVersion(11) .setRevision(11)
.addPromotePendingMembers(member2) .addPromotePendingMembers(member2)
.build()); .build());
assertEquals(DecryptedGroup.newBuilder() assertEquals(DecryptedGroup.newBuilder()
.setVersion(11) .setRevision(11)
.addMembers(member1) .addMembers(member1)
.addMembers(member2) .addMembers(member2)
.build(), .build(),
@ -252,17 +252,17 @@ public final class DecryptedGroupUtil_apply_Test {
DecryptedMember member2 = withProfileKey(admin(pending2Uuid), profileKey2); DecryptedMember member2 = withProfileKey(admin(pending2Uuid), profileKey2);
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setVersion(10) .setRevision(10)
.addMembers(member1) .addMembers(member1)
.addPendingMembers(pending2) .addPendingMembers(pending2)
.build(), .build(),
DecryptedGroupChange.newBuilder() DecryptedGroupChange.newBuilder()
.setVersion(11) .setRevision(11)
.addPromotePendingMembers(member2) .addPromotePendingMembers(member2)
.build()); .build());
assertEquals(DecryptedGroup.newBuilder() assertEquals(DecryptedGroup.newBuilder()
.setVersion(11) .setRevision(11)
.addMembers(member1) .addMembers(member1)
.addMembers(member2) .addMembers(member2)
.build(), .build(),
@ -272,16 +272,16 @@ public final class DecryptedGroupUtil_apply_Test {
@Test @Test
public void title() throws DecryptedGroupUtil.NotAbleToApplyChangeException { public void title() throws DecryptedGroupUtil.NotAbleToApplyChangeException {
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setVersion(10) .setRevision(10)
.setTitle("Old title") .setTitle("Old title")
.build(), .build(),
DecryptedGroupChange.newBuilder() DecryptedGroupChange.newBuilder()
.setVersion(11) .setRevision(11)
.setNewTitle(DecryptedString.newBuilder().setValue("New title").build()) .setNewTitle(DecryptedString.newBuilder().setValue("New title").build())
.build()); .build());
assertEquals(DecryptedGroup.newBuilder() assertEquals(DecryptedGroup.newBuilder()
.setVersion(11) .setRevision(11)
.setTitle("New title") .setTitle("New title")
.build(), .build(),
newGroup); newGroup);
@ -290,16 +290,16 @@ public final class DecryptedGroupUtil_apply_Test {
@Test @Test
public void avatar() throws DecryptedGroupUtil.NotAbleToApplyChangeException { public void avatar() throws DecryptedGroupUtil.NotAbleToApplyChangeException {
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setVersion(10) .setRevision(10)
.setAvatar("https://cnd/oldavatar") .setAvatar("https://cnd/oldavatar")
.build(), .build(),
DecryptedGroupChange.newBuilder() DecryptedGroupChange.newBuilder()
.setVersion(11) .setRevision(11)
.setNewAvatar(DecryptedString.newBuilder().setValue("https://cnd/newavatar").build()) .setNewAvatar(DecryptedString.newBuilder().setValue("https://cnd/newavatar").build())
.build()); .build());
assertEquals(DecryptedGroup.newBuilder() assertEquals(DecryptedGroup.newBuilder()
.setVersion(11) .setRevision(11)
.setAvatar("https://cnd/newavatar") .setAvatar("https://cnd/newavatar")
.build(), .build(),
newGroup); newGroup);
@ -308,16 +308,16 @@ public final class DecryptedGroupUtil_apply_Test {
@Test @Test
public void timer() throws DecryptedGroupUtil.NotAbleToApplyChangeException { public void timer() throws DecryptedGroupUtil.NotAbleToApplyChangeException {
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setVersion(10) .setRevision(10)
.setDisappearingMessagesTimer(DecryptedTimer.newBuilder().setDuration(100)) .setDisappearingMessagesTimer(DecryptedTimer.newBuilder().setDuration(100))
.build(), .build(),
DecryptedGroupChange.newBuilder() DecryptedGroupChange.newBuilder()
.setVersion(11) .setRevision(11)
.setNewTimer(DecryptedTimer.newBuilder().setDuration(2000)) .setNewTimer(DecryptedTimer.newBuilder().setDuration(2000))
.build()); .build());
assertEquals(DecryptedGroup.newBuilder() assertEquals(DecryptedGroup.newBuilder()
.setVersion(11) .setRevision(11)
.setDisappearingMessagesTimer(DecryptedTimer.newBuilder().setDuration(2000)) .setDisappearingMessagesTimer(DecryptedTimer.newBuilder().setDuration(2000))
.build(), .build(),
newGroup); newGroup);
@ -326,19 +326,19 @@ public final class DecryptedGroupUtil_apply_Test {
@Test @Test
public void attribute_access() throws DecryptedGroupUtil.NotAbleToApplyChangeException { public void attribute_access() throws DecryptedGroupUtil.NotAbleToApplyChangeException {
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setVersion(10) .setRevision(10)
.setAccessControl(AccessControl.newBuilder() .setAccessControl(AccessControl.newBuilder()
.setAttributes(AccessControl.AccessRequired.ADMINISTRATOR) .setAttributes(AccessControl.AccessRequired.ADMINISTRATOR)
.setMembers(AccessControl.AccessRequired.MEMBER) .setMembers(AccessControl.AccessRequired.MEMBER)
.build()) .build())
.build(), .build(),
DecryptedGroupChange.newBuilder() DecryptedGroupChange.newBuilder()
.setVersion(11) .setRevision(11)
.setNewAttributeAccess(AccessControl.AccessRequired.MEMBER) .setNewAttributeAccess(AccessControl.AccessRequired.MEMBER)
.build()); .build());
assertEquals(DecryptedGroup.newBuilder() assertEquals(DecryptedGroup.newBuilder()
.setVersion(11) .setRevision(11)
.setAccessControl(AccessControl.newBuilder() .setAccessControl(AccessControl.newBuilder()
.setAttributes(AccessControl.AccessRequired.MEMBER) .setAttributes(AccessControl.AccessRequired.MEMBER)
.setMembers(AccessControl.AccessRequired.MEMBER) .setMembers(AccessControl.AccessRequired.MEMBER)
@ -350,19 +350,19 @@ public final class DecryptedGroupUtil_apply_Test {
@Test @Test
public void membership_access() throws DecryptedGroupUtil.NotAbleToApplyChangeException { public void membership_access() throws DecryptedGroupUtil.NotAbleToApplyChangeException {
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setVersion(10) .setRevision(10)
.setAccessControl(AccessControl.newBuilder() .setAccessControl(AccessControl.newBuilder()
.setAttributes(AccessControl.AccessRequired.ADMINISTRATOR) .setAttributes(AccessControl.AccessRequired.ADMINISTRATOR)
.setMembers(AccessControl.AccessRequired.MEMBER) .setMembers(AccessControl.AccessRequired.MEMBER)
.build()) .build())
.build(), .build(),
DecryptedGroupChange.newBuilder() DecryptedGroupChange.newBuilder()
.setVersion(11) .setRevision(11)
.setNewMemberAccess(AccessControl.AccessRequired.ADMINISTRATOR) .setNewMemberAccess(AccessControl.AccessRequired.ADMINISTRATOR)
.build()); .build());
assertEquals(DecryptedGroup.newBuilder() assertEquals(DecryptedGroup.newBuilder()
.setVersion(11) .setRevision(11)
.setAccessControl(AccessControl.newBuilder() .setAccessControl(AccessControl.newBuilder()
.setAttributes(AccessControl.AccessRequired.ADMINISTRATOR) .setAttributes(AccessControl.AccessRequired.ADMINISTRATOR)
.setMembers(AccessControl.AccessRequired.ADMINISTRATOR) .setMembers(AccessControl.AccessRequired.ADMINISTRATOR)
@ -374,20 +374,20 @@ public final class DecryptedGroupUtil_apply_Test {
@Test @Test
public void change_both_access_levels() throws DecryptedGroupUtil.NotAbleToApplyChangeException { public void change_both_access_levels() throws DecryptedGroupUtil.NotAbleToApplyChangeException {
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setVersion(10) .setRevision(10)
.setAccessControl(AccessControl.newBuilder() .setAccessControl(AccessControl.newBuilder()
.setAttributes(AccessControl.AccessRequired.ADMINISTRATOR) .setAttributes(AccessControl.AccessRequired.ADMINISTRATOR)
.setMembers(AccessControl.AccessRequired.MEMBER) .setMembers(AccessControl.AccessRequired.MEMBER)
.build()) .build())
.build(), .build(),
DecryptedGroupChange.newBuilder() DecryptedGroupChange.newBuilder()
.setVersion(11) .setRevision(11)
.setNewAttributeAccess(AccessControl.AccessRequired.MEMBER) .setNewAttributeAccess(AccessControl.AccessRequired.MEMBER)
.setNewMemberAccess(AccessControl.AccessRequired.ADMINISTRATOR) .setNewMemberAccess(AccessControl.AccessRequired.ADMINISTRATOR)
.build()); .build());
assertEquals(DecryptedGroup.newBuilder() assertEquals(DecryptedGroup.newBuilder()
.setVersion(11) .setRevision(11)
.setAccessControl(AccessControl.newBuilder() .setAccessControl(AccessControl.newBuilder()
.setAttributes(AccessControl.AccessRequired.MEMBER) .setAttributes(AccessControl.AccessRequired.MEMBER)
.setMembers(AccessControl.AccessRequired.ADMINISTRATOR) .setMembers(AccessControl.AccessRequired.ADMINISTRATOR)