Fixing a problem caused by the lack of extension byte in the serialization of the AccountOption class
This commit is contained in:
parent
a848c66fb9
commit
88ca47c378
6 changed files with 150 additions and 5 deletions
|
@ -1,14 +1,20 @@
|
||||||
package de.bitsharesmunich.graphenej;
|
package de.bitsharesmunich.graphenej;
|
||||||
|
|
||||||
import com.google.common.primitives.Bytes;
|
import com.google.common.primitives.Bytes;
|
||||||
import com.google.gson.*;
|
import com.google.gson.JsonArray;
|
||||||
import de.bitsharesmunich.graphenej.errors.MalformedAddressException;
|
import com.google.gson.JsonDeserializationContext;
|
||||||
import de.bitsharesmunich.graphenej.interfaces.GrapheneSerializable;
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.bitsharesmunich.graphenej.errors.MalformedAddressException;
|
||||||
|
import de.bitsharesmunich.graphenej.interfaces.GrapheneSerializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by nelson on 12/5/16.
|
* Created by nelson on 12/5/16.
|
||||||
*/
|
*/
|
||||||
|
@ -107,6 +113,9 @@ public class AccountOptions implements GrapheneSerializable {
|
||||||
//TODO: Check this serialization
|
//TODO: Check this serialization
|
||||||
byteArray.addAll(Bytes.asList(vote.toBytes()));
|
byteArray.addAll(Bytes.asList(vote.toBytes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Account options's extensions
|
||||||
|
byteArray.addAll(Bytes.asList(extensions.toBytes()));
|
||||||
}else{
|
}else{
|
||||||
byteArray.add((byte) 0);
|
byteArray.add((byte) 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,10 +110,28 @@ public class BrainKey {
|
||||||
return wif.toString();
|
return wif.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the public address derived from this brain key
|
||||||
|
* @param prefix: The prefix to use in this address.
|
||||||
|
* @return An instance of the {@link Address} class
|
||||||
|
*/
|
||||||
|
public Address getPublicAddress(String prefix){
|
||||||
|
return new Address(ECKey.fromPublicOnly(getPublicKey()), prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Brain key words getter
|
||||||
|
* @return: The word sequence that comprises this brain key
|
||||||
|
*/
|
||||||
public String getBrainKey(){
|
public String getBrainKey(){
|
||||||
return mBrainKey;
|
return mBrainKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sequence number getter
|
||||||
|
* @return: The sequence number used alongside with the brain key words in order
|
||||||
|
* to derive the private key
|
||||||
|
*/
|
||||||
public int getSequenceNumber(){
|
public int getSequenceNumber(){
|
||||||
return sequenceNumber;
|
return sequenceNumber;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,19 @@
|
||||||
package de.bitsharesmunich.graphenej;
|
package de.bitsharesmunich.graphenej;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
|
|
||||||
|
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
|
||||||
import de.bitsharesmunich.graphenej.interfaces.GrapheneSerializable;
|
import de.bitsharesmunich.graphenej.interfaces.GrapheneSerializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used whenever we have an optional field.
|
* Container template class used whenever we have an optional field.
|
||||||
|
*
|
||||||
|
* The idea here is that the binary serialization of this field should be performed
|
||||||
|
* in a specific way determined by the field implementing the {@link ByteSerializable}
|
||||||
|
* interface, more specifically using the {@link ByteSerializable#toBytes()} method.
|
||||||
|
*
|
||||||
|
* However, if the field is missing, the Optional class should be able to know how
|
||||||
|
* to serialize it, as this is always done by placing an zero byte.
|
||||||
*/
|
*/
|
||||||
public class Optional<T extends GrapheneSerializable> implements GrapheneSerializable {
|
public class Optional<T extends GrapheneSerializable> implements GrapheneSerializable {
|
||||||
private T optionalField;
|
private T optionalField;
|
||||||
|
|
|
@ -24,7 +24,6 @@ public class AccountUpdateOperation extends BaseOperation {
|
||||||
private Optional<Authority> owner;
|
private Optional<Authority> owner;
|
||||||
private Optional<Authority> active;
|
private Optional<Authority> active;
|
||||||
private Optional<AccountOptions> new_options;
|
private Optional<AccountOptions> new_options;
|
||||||
private Extensions extensions;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Account update operation constructor.
|
* Account update operation constructor.
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package de.bitsharesmunich.graphenej;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by nelson on 4/18/17.
|
||||||
|
*/
|
||||||
|
public class BrainKeyTest {
|
||||||
|
// public final String TEST_BRAINKEY = "SOAPILY GASSING FIFIE OZONATE WHYO TOPLINE PRISMY ZEUGMA GLOTTIC DAVEN CORODY PFUI";
|
||||||
|
public final String TEST_BRAINKEY = "BARIC BICKERN LITZ TIPFUL JINGLED POOL TUMBAK PURIST APOPYLE DURAIN SATLIJK FAUCAL";
|
||||||
|
private BrainKey mBrainKey;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup(){
|
||||||
|
mBrainKey = new BrainKey(TEST_BRAINKEY, BrainKey.DEFAULT_SEQUENCE_NUMBER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddress(){
|
||||||
|
Address address = mBrainKey.getPublicAddress(Address.BITSHARES_PREFIX);
|
||||||
|
// Assert.assertEquals("Assert that the address created is the expected one",
|
||||||
|
// "BTS7yT2vnjGAxPocqsnDfoJv3DHUtCNGWwqvc7mWRikkqwuhKtT5s",
|
||||||
|
// address.toString());
|
||||||
|
Assert.assertEquals("Assert that the address created is the expected one",
|
||||||
|
"BTS61UqqgE3ARuTGcckzARsdQm4EMFdBEwYyi1pbwyHrZZWrCDhT2",
|
||||||
|
address.toString());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package de.bitsharesmunich.graphenej.operations;
|
||||||
|
|
||||||
|
import com.google.common.primitives.UnsignedLong;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.ECKey;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import de.bitsharesmunich.graphenej.AccountOptions;
|
||||||
|
import de.bitsharesmunich.graphenej.Address;
|
||||||
|
import de.bitsharesmunich.graphenej.Asset;
|
||||||
|
import de.bitsharesmunich.graphenej.AssetAmount;
|
||||||
|
import de.bitsharesmunich.graphenej.Authority;
|
||||||
|
import de.bitsharesmunich.graphenej.BaseOperation;
|
||||||
|
import de.bitsharesmunich.graphenej.BlockData;
|
||||||
|
import de.bitsharesmunich.graphenej.BrainKey;
|
||||||
|
import de.bitsharesmunich.graphenej.PublicKey;
|
||||||
|
import de.bitsharesmunich.graphenej.Transaction;
|
||||||
|
import de.bitsharesmunich.graphenej.UserAccount;
|
||||||
|
import de.bitsharesmunich.graphenej.Util;
|
||||||
|
import de.bitsharesmunich.graphenej.errors.MalformedAddressException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by nelson on 4/18/17.
|
||||||
|
*/
|
||||||
|
public class AccountUpdateOperationTest {
|
||||||
|
|
||||||
|
private static final String BILTHON_16_BRAIN_KEY = "SOAPILY GASSING FIFIE OZONATE WHYO TOPLINE PRISMY ZEUGMA GLOTTIC DAVEN CORODY PFUI";
|
||||||
|
public final String ADDRESS = "BTS8RYD5ehEMtTrfmeWRVKJzvLK2AqunxRh2XhXyXVxKtDjeAhYs1";
|
||||||
|
|
||||||
|
private final Asset CORE = new Asset("1.3.0");
|
||||||
|
|
||||||
|
private Authority active;
|
||||||
|
private AccountOptions options;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup(){
|
||||||
|
try{
|
||||||
|
HashMap<Address, Integer> keyAuth = new HashMap<>();
|
||||||
|
keyAuth.put(new Address(ADDRESS), 1);
|
||||||
|
active = new Authority();
|
||||||
|
active.setKeyAuthorities(keyAuth);
|
||||||
|
|
||||||
|
options = new AccountOptions();
|
||||||
|
options.setMemoKey(new PublicKey(ECKey.fromPublicOnly(new Address(ADDRESS).getPublicKey().toBytes())));
|
||||||
|
options.setNumWitness(0);
|
||||||
|
options.setNum_comittee(0);
|
||||||
|
options.setVotingAccount(new UserAccount("1.2.5"));
|
||||||
|
}catch(MalformedAddressException e){
|
||||||
|
System.out.println("MalformedAddressException. Msg: "+e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOperationSerialization(){
|
||||||
|
AccountUpdateOperationBuilder builder = new AccountUpdateOperationBuilder()
|
||||||
|
.setAccount(new UserAccount("1.2.143569"))
|
||||||
|
.setFee(new AssetAmount(UnsignedLong.valueOf(14676), CORE))
|
||||||
|
.setActive(active)
|
||||||
|
.setOptions(options);
|
||||||
|
|
||||||
|
AccountUpdateOperation operation = builder.build();
|
||||||
|
|
||||||
|
ArrayList<BaseOperation> operations = new ArrayList<>();
|
||||||
|
operations.add(operation);
|
||||||
|
ECKey privateKey = new BrainKey(BILTHON_16_BRAIN_KEY, 0).getPrivateKey();
|
||||||
|
BlockData blockData = new BlockData(3703, 2015738269, 1492551764);
|
||||||
|
|
||||||
|
Transaction tx = new Transaction(privateKey, blockData, operations);
|
||||||
|
|
||||||
|
// String json = tx.toJsonString();
|
||||||
|
byte[] serialized = tx.toBytes();
|
||||||
|
|
||||||
|
// System.out.println("json: "+json);
|
||||||
|
System.out.println("serialized: "+ Util.bytesToHex(serialized));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue