Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #20 Support for Account properties #46

Merged
merged 5 commits into from
Jun 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions schemas/flatbuffers/schema_account_properties_transaction.fbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace io.proximax.sdk.gen.buffers;

table PropertyModificationBuffer {
modificationType: ubyte;
/// In case of address it is 25 bytes array. In case of mosaic it is 8 byte array(or 2 uint32 array).
/// In case of transaction it is 2 byte array(ushort)
value: [ubyte];
}

table AccountPropertiesTransactionBuffer {
size: uint;
signature: [ubyte];
signer: [ubyte];
version: ushort;
type: ushort;
maxFee: [uint];
deadline:[uint];
propertyType: ubyte;
modificationCount: ubyte;
modifications: [PropertyModificationBuffer];
}

root_type AccountPropertiesTransactionBuffer;
181 changes: 178 additions & 3 deletions src/e2e/java/io/proximax/sdk/E2EAccountTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
Expand All @@ -31,11 +32,22 @@
import org.slf4j.LoggerFactory;

import io.proximax.core.crypto.KeyPair;
import io.proximax.sdk.gen.model.UInt64DTO;
import io.proximax.sdk.infrastructure.QueryParams;
import io.proximax.sdk.model.account.Account;
import io.proximax.sdk.model.account.AccountInfo;
import io.proximax.sdk.model.account.Address;
import io.proximax.sdk.model.account.props.AccountProperties;
import io.proximax.sdk.model.account.props.AccountProperty;
import io.proximax.sdk.model.account.props.AccountPropertyModification;
import io.proximax.sdk.model.account.props.AccountPropertyModificationType;
import io.proximax.sdk.model.account.props.AccountPropertyType;
import io.proximax.sdk.model.mosaic.MosaicId;
import io.proximax.sdk.model.mosaic.NetworkCurrencyMosaic;
import io.proximax.sdk.model.transaction.ModifyAccountPropertyTransaction;
import io.proximax.sdk.model.transaction.Transaction;
import io.proximax.sdk.model.transaction.TransactionType;
import io.proximax.sdk.utils.dto.UInt64Utils;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class E2EAccountTest extends E2EBaseTest {
Expand All @@ -47,14 +59,177 @@ class E2EAccountTest extends E2EBaseTest {
@BeforeAll
void addListener() {
logger.info("Sending transactions to {}", simpleAccount);
listener.status(simpleAccount.getAddress()).doOnNext(err -> logger.info("Error on recipient: {}", err))
.doOnError(exception -> logger.error("Failure on recipient: {}", exception))
.doOnComplete(() -> logger.info("done with recipient {}", simpleAccount));
signup(simpleAccount.getAddress());
// make transfer to and from the test account to make sure it has public key announced
sendSomeCash(seedAccount, simpleAccount.getAddress(), 1);
sendSomeCash(simpleAccount, seedAccount.getAddress(), 1);
}


@Test
void addBlockAccountProperty() {
Account acct = new Account(new KeyPair(), getNetworkType());
Account blocked = new Account(new KeyPair(), getNetworkType());
signup(acct.getAddress());
signup(blocked.getAddress());
logger.info("going to block {} by {}", blocked.getPublicAccount(), acct.getPublicAccount());
ModifyAccountPropertyTransaction<Address> trans = ModifyAccountPropertyTransaction.createForAddress(getDeadline(),
BigInteger.ZERO,
AccountPropertyType.BLOCK_ADDRESS,
Arrays.asList(new AccountPropertyModification<>(AccountPropertyModificationType.ADD, blocked.getAddress())),
getNetworkType());
// announce the transaction
transactionHttp.announce(trans.signWith(acct)).blockingFirst();
logger.info("Waiting for confirmation");
listener.confirmed(acct.getAddress()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst();
// now check for the block via GET
AccountProperties aps = accountHttp.getAccountProperties(acct.getAddress())
.timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst();
testAccountProperties(aps, blocked.getAddress());
// check for block via POST
List<AccountProperties> apsList = accountHttp.getAccountProperties(Arrays.asList(acct.getAddress()))
.timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst();
assertEquals(1, apsList.size());
testAccountProperties(apsList.get(0), blocked.getAddress());
}

@Test
void addAllowMosaicProperty() {
Account acct = new Account(new KeyPair(), getNetworkType());
signup(acct.getAddress());
MosaicId allowedMosaic = NetworkCurrencyMosaic.ID;
logger.info("going to allow {} by {}", allowedMosaic, acct.getPublicAccount());
ModifyAccountPropertyTransaction<MosaicId> trans = ModifyAccountPropertyTransaction.createForMosaic(getDeadline(),
BigInteger.ZERO,
AccountPropertyType.ALLOW_MOSAIC,
Arrays.asList(AccountPropertyModification.add(allowedMosaic)),
getNetworkType());
// announce the transaction
transactionHttp.announce(trans.signWith(acct)).blockingFirst();
logger.info("Waiting for confirmation");
listener.confirmed(acct.getAddress()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst();
// now check for the block via GET
AccountProperties aps = accountHttp.getAccountProperties(acct.getAddress())
.timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst();
testAccountPropertiesOnSimpleAccount(aps, allowedMosaic);
// check for block via POST
List<AccountProperties> apsList = accountHttp.getAccountProperties(Arrays.asList(acct.getAddress()))
.timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst();
assertEquals(1, apsList.size());
testAccountPropertiesOnSimpleAccount(apsList.get(0), allowedMosaic);
}

@Test
void addAllowEntityTypeProperty() {
Account acct = new Account(new KeyPair(), getNetworkType());
signup(acct.getAddress());
TransactionType allowedTransType = TransactionType.ACCOUNT_PROPERTIES_ENTITY_TYPE;
logger.info("going to allow {} by {}", allowedTransType, acct.getPublicAccount());
ModifyAccountPropertyTransaction<TransactionType> trans = ModifyAccountPropertyTransaction.createForEntityType(getDeadline(),
BigInteger.ZERO,
AccountPropertyType.ALLOW_TRANSACTION,
Arrays.asList(AccountPropertyModification.add(allowedTransType)),
getNetworkType());
// announce the transaction
transactionHttp.announce(trans.signWith(acct)).blockingFirst();
logger.info("Waiting for confirmation");
listener.confirmed(acct.getAddress()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst();
// now check for the block via GET
AccountProperties aps = accountHttp.getAccountProperties(acct.getAddress())
.timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst();
testAccountPropertiesOnSimpleAccount(aps, allowedTransType);
// check for block via POST
List<AccountProperties> apsList = accountHttp.getAccountProperties(Arrays.asList(acct.getAddress()))
.timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst();
assertEquals(1, apsList.size());
testAccountPropertiesOnSimpleAccount(apsList.get(0), allowedTransType);
}

/**
* check that address block is as expected
*
* @param aps account properties
* @param blockedAddress address that is blocked
*/
private void testAccountProperties(AccountProperties aps, Address blockedAddress) {
boolean gotMatch = false;
for (AccountProperty ap: aps.getProperties()) {
if (ap.getPropertyType().equals(AccountPropertyType.BLOCK_ADDRESS)) {
for (Object value: ap.getValues()) {
// value should be string and should represent encoded address of the blocked account
if (value instanceof String && blockedAddress.equals(Address.createFromEncoded((String)value))) {
gotMatch = true;
}
}

}
}
assertTrue(gotMatch);
}

/**
* check that simple account has block as expected
*
* @param aps account properties
* @param blockedAddress address that is blocked
*/
private void testAccountPropertiesOnSimpleAccount(AccountProperties aps, MosaicId allowedMosaic) {
boolean gotMatch = false;
for (AccountProperty ap: aps.getProperties()) {
if (ap.getPropertyType().equals(AccountPropertyType.ALLOW_MOSAIC)) {
for (Object value: ap.getValues()) {
logger.info("{}", value);
// value should be string and should represent encoded address of the blocked account
if (value instanceof List) {
UInt64DTO dto = new UInt64DTO();
dto.addAll((List<Long>)value);
MosaicId retrievedMosaic = new MosaicId(UInt64Utils.toBigInt(dto));
if (retrievedMosaic.equals(allowedMosaic)) {
gotMatch = true;
}
}
}

}
}
assertTrue(gotMatch);
}

/**
* check that simple account has block as expected
*
* @param aps account properties
* @param blockedAddress address that is blocked
*/
private void testAccountPropertiesOnSimpleAccount(AccountProperties aps, TransactionType allowedTransactionType) {
boolean gotMatch = false;
for (AccountProperty ap: aps.getProperties()) {
if (ap.getPropertyType().equals(AccountPropertyType.ALLOW_TRANSACTION)) {
for (Object value : ap.getValues()) {
try {
if (value instanceof Long && isValidTransactionTypeCode(((Long) value).intValue())) {
assertEquals(TransactionType.ACCOUNT_PROPERTIES_ENTITY_TYPE, TransactionType.rawValueOf(((Long) value).intValue()));
gotMatch = true;
}
} catch (RuntimeException e) {
// do nothing just ignore
}
}

}
}
assertTrue(gotMatch);
}

private static boolean isValidTransactionTypeCode(int code) {
try {
TransactionType.rawValueOf(code);
return true;
} catch (RuntimeException e) {
return false;
}
}

@Test
void getAccountInfo() throws ExecutionException, InterruptedException {
AccountInfo accountInfo = accountHttp
Expand Down
9 changes: 1 addition & 8 deletions src/e2e/java/io/proximax/sdk/E2EAliasTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import org.slf4j.LoggerFactory;

import io.proximax.core.crypto.KeyPair;
import io.proximax.sdk.gen.model.UInt64DTO;
import io.proximax.sdk.model.account.Account;
import io.proximax.sdk.model.alias.AliasAction;
import io.proximax.sdk.model.mosaic.MosaicId;
Expand All @@ -45,7 +44,6 @@
import io.proximax.sdk.model.transaction.RegisterNamespaceTransaction;
import io.proximax.sdk.model.transaction.SignedTransaction;
import io.proximax.sdk.model.transaction.Transaction;
import io.proximax.sdk.utils.dto.UInt64Utils;
import io.reactivex.Observable;

/**
Expand Down Expand Up @@ -76,18 +74,13 @@ void initStuff() {
mosaicNonce = MosaicNonce.createRandom();
mosaicId = new MosaicId(mosaicNonce, seedAccount.getPublicKey());
signup(seedAccount.getAddress());
UInt64DTO dto = new UInt64DTO();
dto.add(244048598l);
dto.add(73533943l);
System.out.println(new MosaicId(UInt64Utils.toBigInt(dto)).getIdAsHex());
// fail();
}

@AfterAll
void closeDown() {

}

@Test
void test01PrepareData() {
NamespaceId rootId = new NamespaceId(ROOT_NAME);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// automatically generated by the FlatBuffers compiler, do not modify

package io.proximax.sdk.gen.buffers;

import java.nio.*;
import java.lang.*;
import java.util.*;
import com.google.flatbuffers.*;

@SuppressWarnings("unused")
public final class AccountPropertiesTransactionBuffer extends Table {
public static AccountPropertiesTransactionBuffer getRootAsAccountPropertiesTransactionBuffer(ByteBuffer _bb) { return getRootAsAccountPropertiesTransactionBuffer(_bb, new AccountPropertiesTransactionBuffer()); }
public static AccountPropertiesTransactionBuffer getRootAsAccountPropertiesTransactionBuffer(ByteBuffer _bb, AccountPropertiesTransactionBuffer obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); }
public AccountPropertiesTransactionBuffer __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }

public long size() { int o = __offset(4); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0L; }
public int signature(int j) { int o = __offset(6); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
public int signatureLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; }
public ByteBuffer signatureAsByteBuffer() { return __vector_as_bytebuffer(6, 1); }
public ByteBuffer signatureInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 1); }
public int signer(int j) { int o = __offset(8); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
public int signerLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; }
public ByteBuffer signerAsByteBuffer() { return __vector_as_bytebuffer(8, 1); }
public ByteBuffer signerInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 1); }
public int version() { int o = __offset(10); return o != 0 ? bb.getShort(o + bb_pos) & 0xFFFF : 0; }
public int type() { int o = __offset(12); return o != 0 ? bb.getShort(o + bb_pos) & 0xFFFF : 0; }
public long maxFee(int j) { int o = __offset(14); return o != 0 ? (long)bb.getInt(__vector(o) + j * 4) & 0xFFFFFFFFL : 0; }
public int maxFeeLength() { int o = __offset(14); return o != 0 ? __vector_len(o) : 0; }
public ByteBuffer maxFeeAsByteBuffer() { return __vector_as_bytebuffer(14, 4); }
public ByteBuffer maxFeeInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 14, 4); }
public long deadline(int j) { int o = __offset(16); return o != 0 ? (long)bb.getInt(__vector(o) + j * 4) & 0xFFFFFFFFL : 0; }
public int deadlineLength() { int o = __offset(16); return o != 0 ? __vector_len(o) : 0; }
public ByteBuffer deadlineAsByteBuffer() { return __vector_as_bytebuffer(16, 4); }
public ByteBuffer deadlineInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 16, 4); }
public int propertyType() { int o = __offset(18); return o != 0 ? bb.get(o + bb_pos) & 0xFF : 0; }
public int modificationCount() { int o = __offset(20); return o != 0 ? bb.get(o + bb_pos) & 0xFF : 0; }
public PropertyModificationBuffer modifications(int j) { return modifications(new PropertyModificationBuffer(), j); }
public PropertyModificationBuffer modifications(PropertyModificationBuffer obj, int j) { int o = __offset(22); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
public int modificationsLength() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; }

public static int createAccountPropertiesTransactionBuffer(FlatBufferBuilder builder,
long size,
int signatureOffset,
int signerOffset,
int version,
int type,
int maxFeeOffset,
int deadlineOffset,
int propertyType,
int modificationCount,
int modificationsOffset) {
builder.startObject(10);
AccountPropertiesTransactionBuffer.addModifications(builder, modificationsOffset);
AccountPropertiesTransactionBuffer.addDeadline(builder, deadlineOffset);
AccountPropertiesTransactionBuffer.addMaxFee(builder, maxFeeOffset);
AccountPropertiesTransactionBuffer.addSigner(builder, signerOffset);
AccountPropertiesTransactionBuffer.addSignature(builder, signatureOffset);
AccountPropertiesTransactionBuffer.addSize(builder, size);
AccountPropertiesTransactionBuffer.addType(builder, type);
AccountPropertiesTransactionBuffer.addVersion(builder, version);
AccountPropertiesTransactionBuffer.addModificationCount(builder, modificationCount);
AccountPropertiesTransactionBuffer.addPropertyType(builder, propertyType);
return AccountPropertiesTransactionBuffer.endAccountPropertiesTransactionBuffer(builder);
}

public static void startAccountPropertiesTransactionBuffer(FlatBufferBuilder builder) { builder.startObject(10); }
public static void addSize(FlatBufferBuilder builder, long size) { builder.addInt(0, (int)size, (int)0L); }
public static void addSignature(FlatBufferBuilder builder, int signatureOffset) { builder.addOffset(1, signatureOffset, 0); }
public static int createSignatureVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
public static void startSignatureVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
public static void addSigner(FlatBufferBuilder builder, int signerOffset) { builder.addOffset(2, signerOffset, 0); }
public static int createSignerVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
public static void startSignerVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
public static void addVersion(FlatBufferBuilder builder, int version) { builder.addShort(3, (short)version, (short)0); }
public static void addType(FlatBufferBuilder builder, int type) { builder.addShort(4, (short)type, (short)0); }
public static void addMaxFee(FlatBufferBuilder builder, int maxFeeOffset) { builder.addOffset(5, maxFeeOffset, 0); }
public static int createMaxFeeVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); }
public static void startMaxFeeVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
public static void addDeadline(FlatBufferBuilder builder, int deadlineOffset) { builder.addOffset(6, deadlineOffset, 0); }
public static int createDeadlineVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]); return builder.endVector(); }
public static void startDeadlineVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
public static void addPropertyType(FlatBufferBuilder builder, int propertyType) { builder.addByte(7, (byte)propertyType, (byte)0); }
public static void addModificationCount(FlatBufferBuilder builder, int modificationCount) { builder.addByte(8, (byte)modificationCount, (byte)0); }
public static void addModifications(FlatBufferBuilder builder, int modificationsOffset) { builder.addOffset(9, modificationsOffset, 0); }
public static int createModificationsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
public static void startModificationsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
public static int endAccountPropertiesTransactionBuffer(FlatBufferBuilder builder) {
int o = builder.endObject();
return o;
}
public static void finishAccountPropertiesTransactionBufferBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset); }
public static void finishSizePrefixedAccountPropertiesTransactionBufferBuffer(FlatBufferBuilder builder, int offset) { builder.finishSizePrefixed(offset); }
}

Loading