Implemented ethereum event listeners for remote service.

This commit is contained in:
Adrian Tiberius 2015-06-28 20:57:25 +02:00
parent e3ca3aa951
commit bc91b5f13b
23 changed files with 864 additions and 70 deletions

View File

@ -7,7 +7,7 @@ import org.ethereum.android.service.EthereumConnector;
public class EthereumApplication extends MultiDexApplication {
EthereumConnector ethereum = null;
public EthereumConnector ethereum = null;
@Override public void onCreate() {

View File

@ -1,5 +1,6 @@
package org.ethereum.android_app;
import android.os.Message;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
@ -7,16 +8,36 @@ import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import org.ethereum.android.service.ConnectorHandler;
import org.ethereum.android.service.EthereumClientMessage;
import org.ethereum.android.service.events.BlockEventData;
import org.ethereum.android.service.events.EventData;
import org.ethereum.android.service.events.EventFlag;
import org.ethereum.android.service.events.MessageEventData;
import org.ethereum.android.service.events.PeerDisconnectEventData;
import org.ethereum.android.service.events.PendingTransactionsEventData;
import org.ethereum.android.service.events.TraceEventData;
import org.ethereum.android.service.events.VMTraceCreatedEventData;
import org.ethereum.config.SystemProperties;
import org.ethereum.net.p2p.HelloMessage;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.EnumSet;
import java.util.UUID;
public class RemoteMainActivity extends ActionBarActivity implements ActivityInterface {
public class RemoteMainActivity extends ActionBarActivity implements ActivityInterface, ConnectorHandler {
private Toolbar toolbar;
private ViewPager viewPager;
private SlidingTabLayout tabs;
private TabsPagerAdapter adapter;
protected ArrayList<FragmentInterface> fragments = new ArrayList<>();
protected String handlerIdentifier = UUID.randomUUID().toString();
static DateFormat formatter = new SimpleDateFormat("HH:mm:ss:SSS");
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -34,6 +55,8 @@ public class RemoteMainActivity extends ActionBarActivity implements ActivityInt
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true);
tabs.setViewPager(viewPager);
EthereumApplication app = (EthereumApplication)getApplication();
app.ethereum.registerHandler(this);
}
@Override
@ -66,4 +89,92 @@ public class RemoteMainActivity extends ActionBarActivity implements ActivityInt
fragments.add(fragment);
}
}
@Override
public boolean handleMessage(Message message) {
boolean isClaimed = true;
switch(message.what) {
case EthereumClientMessage.MSG_EVENT:
Bundle data = message.getData();
data.setClassLoader(EventFlag.class.getClassLoader());
EventFlag event = (EventFlag)data.getSerializable("event");
EventData eventData;
MessageEventData messageEventData;
switch(event) {
case EVENT_BLOCK:
BlockEventData blockEventData = data.getParcelable("data");
addLogEntry(blockEventData.registeredTime, "Added block with " + blockEventData.receipts.size() + " transaction receipts.");
break;
case EVENT_HANDSHAKE_PEER:
messageEventData = data.getParcelable("data");
addLogEntry(messageEventData.registeredTime, "Peer " + new HelloMessage(messageEventData.message).getPeerId() + " said hello");
break;
case EVENT_NO_CONNECTIONS:
eventData = data.getParcelable("data");
addLogEntry(eventData.registeredTime, "No connections");
break;
case EVENT_PEER_DISCONNECT:
PeerDisconnectEventData peerDisconnectEventData = data.getParcelable("data");
addLogEntry(peerDisconnectEventData.registeredTime, "Peer " + peerDisconnectEventData.host + ":" + peerDisconnectEventData.port + " disconnected.");
break;
case EVENT_PENDING_TRANSACTIONS_RECEIVED:
PendingTransactionsEventData pendingTransactionsEventData = data.getParcelable("data");
addLogEntry(pendingTransactionsEventData.registeredTime, "Received " + pendingTransactionsEventData.transactions.size() + " pending transactions");
break;
case EVENT_RECEIVE_MESSAGE:
messageEventData = data.getParcelable("data");
addLogEntry(messageEventData.registeredTime, "Received message: " + messageEventData.messageClass.getName());
break;
case EVENT_SEND_MESSAGE:
messageEventData = data.getParcelable("data");
addLogEntry(messageEventData.registeredTime, "Sent message: " + messageEventData.messageClass.getName());
break;
case EVENT_SYNC_DONE:
eventData = data.getParcelable("data");
addLogEntry(eventData.registeredTime, "Sync done");
break;
case EVENT_VM_TRACE_CREATED:
VMTraceCreatedEventData vmTraceCreatedEventData = data.getParcelable("data");
addLogEntry(vmTraceCreatedEventData.registeredTime, "CM trace created: " + vmTraceCreatedEventData.transactionHash + " - " + vmTraceCreatedEventData.trace);
break;
case EVENT_TRACE:
TraceEventData traceEventData = data.getParcelable("data");
addLogEntry(traceEventData.registeredTime, traceEventData.message);
break;
}
break;
default:
isClaimed = false;
}
return isClaimed;
}
protected void addLogEntry(long timestamp, String message) {
Date date = new Date(timestamp);
for(FragmentInterface fragment: fragments) {
fragment.onMessage(formatter.format(date) + " -> " + message + "\n");
}
}
@Override
public String getID() {
return handlerIdentifier;
}
@Override
public void onConnectorConnected() {
EthereumApplication app = (EthereumApplication)getApplication();
app.ethereum.addListener(handlerIdentifier, EnumSet.allOf(EventFlag.class));
app.ethereum.connect(SystemProperties.CONFIG.activePeerIP(), SystemProperties.CONFIG.activePeerPort(), SystemProperties.CONFIG.activePeerNodeid());
}
@Override
public void onConnectorDisconnected() {
}
}

View File

@ -14,10 +14,12 @@ import org.ethereum.android.EthereumManager;
import org.ethereum.android.interop.AdminInfo;
import org.ethereum.android.service.ConnectorHandler;
import org.ethereum.android.service.EthereumClientMessage;
import org.ethereum.android.service.events.EventFlag;
import org.ethereum.config.SystemProperties;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.EnumSet;
import java.util.UUID;
import static org.ethereum.config.SystemProperties.CONFIG;
@ -129,4 +131,17 @@ public class TestsFragment extends Fragment implements ConnectorHandler {
return identifier;
}
@Override
public void onConnectorConnected() {
EthereumApplication app = (EthereumApplication)getActivity().getApplication();
app.ethereum.addListener(identifier, EnumSet.allOf(EventFlag.class));
app.ethereum.connect(SystemProperties.CONFIG.activePeerIP(), SystemProperties.CONFIG.activePeerPort(), SystemProperties.CONFIG.activePeerNodeid());
}
@Override
public void onConnectorDisconnected() {
}
}

View File

@ -10,6 +10,11 @@ public class Block extends org.ethereum.core.Block implements Parcelable {
super(rawData);
}
public Block(org.ethereum.core.Block block) {
super(block.getEncoded());
}
public Block(Parcel in) {
super(null);

View File

@ -0,0 +1,61 @@
package org.ethereum.android.interop;
import android.os.Parcel;
import android.os.Parcelable;
import org.ethereum.core.Bloom;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPElement;
import org.ethereum.util.RLPItem;
import org.ethereum.util.RLPList;
import org.ethereum.vm.LogInfo;
import java.util.Arrays;
public class TransactionReceipt extends org.ethereum.core.TransactionReceipt implements Parcelable {
public TransactionReceipt(org.ethereum.core.TransactionReceipt transactionReceipt) {
super(transactionReceipt.getEncoded());
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
byte[] rlp = getEncoded();
parcel.writeInt(rlp.length);
parcel.writeByteArray(rlp);
parcel.writeParcelable(new Transaction(getTransaction()), i);
}
public static final Parcelable.Creator<TransactionReceipt> CREATOR = new Parcelable.Creator<TransactionReceipt>() {
public TransactionReceipt createFromParcel(Parcel in) {
return new TransactionReceipt(in);
}
public TransactionReceipt[] newArray(int size) {
return new TransactionReceipt[size];
}
};
private TransactionReceipt(Parcel in) {
byte[] rlp;
int length = in.readInt();
rlp = new byte[length];
in.readByteArray(rlp);
parseRlp(rlp);
setTransaction((org.ethereum.core.Transaction)in.readParcelable(Transaction.class.getClassLoader()));
}
}

View File

@ -0,0 +1,20 @@
package org.ethereum.android.service;
import android.os.Messenger;
import java.util.BitSet;
public class ClientListener {
public BitSet flags;
public Messenger listener;
public String identifier;
public ClientListener(Messenger listener, BitSet flags, String identifier) {
this.listener = listener;
this.flags = flags;
this.identifier = identifier;
}
}

View File

@ -6,5 +6,7 @@ import android.os.Message;
public interface ConnectorHandler {
boolean handleMessage(Message message);
void onConnectorConnected();
void onConnectorDisconnected();
String getID();
}

View File

@ -72,7 +72,6 @@ public class EthereumAidlService extends EthereumService {
};
}
@Override
protected void broadcastMessage(String message) {
for (IListener listener: clientListeners) {

View File

@ -36,4 +36,9 @@ public class EthereumClientMessage {
* Send peers to the client
*/
public static final int MSG_PENDING_TRANSACTIONS = 7;
/**
* Send event to the client
*/
public static final int MSG_EVENT = 8;
}

View File

@ -5,11 +5,14 @@ import android.os.Bundle;
import android.os.Message;
import android.os.RemoteException;
import org.ethereum.android.service.events.EventFlag;
import org.ethereum.core.Transaction;
import org.ethereum.net.peerdiscovery.PeerInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.EnumSet;
public class EthereumConnector extends ServiceConnector {
@ -134,7 +137,7 @@ public class EthereumConnector extends ServiceConnector {
msg.replyTo = clientMessenger;
msg.obj = getIdentifierBundle(identifier);
Bundle data = new Bundle();
data.putParcelable("excludePeer", (org.ethereum.android.interop.PeerInfo)excludePeer);
data.putParcelable("excludePeer", (org.ethereum.android.interop.PeerInfo) excludePeer);
msg.setData(data);
try {
serviceMessenger.send(msg);
@ -261,9 +264,12 @@ public class EthereumConnector extends ServiceConnector {
* Add ethereum event listener
* @param identifier String Caller identifier used to return the response
*
* Sends message parameters: none
* Sends message parameters ( "key": type [description] ):
* {
* "flags": Serializable(EnumSet<ListenerFlag>) [sets flags to listen to specific events]
* }
*/
public void addListener(String identifier) {
public void addListener(String identifier, EnumSet<EventFlag> flags) {
if (!isBound)
return;
@ -271,7 +277,9 @@ public class EthereumConnector extends ServiceConnector {
Message msg = Message.obtain(null, EthereumServiceMessage.MSG_ADD_LISTENER, 0, 0);
msg.replyTo = clientMessenger;
msg.obj = getIdentifierBundle(identifier);
// TODO: Add event flags to message
Bundle data = new Bundle();
data.putSerializable("flags", flags);
msg.setData(data);
try {
serviceMessenger.send(msg);
} catch (RemoteException e) {
@ -279,6 +287,28 @@ public class EthereumConnector extends ServiceConnector {
}
}
/**
* Remove ethereum event listener
* @param identifier String Caller identifier used to return the response
*
* Sends message parameters: none
*/
public void removeListener(String identifier) {
if (!isBound)
return;
Message msg = Message.obtain(null, EthereumServiceMessage.MSG_REMOVE_LISTENER, 0, 0);
msg.replyTo = clientMessenger;
msg.obj = getIdentifierBundle(identifier);
try {
serviceMessenger.send(msg);
} catch (RemoteException e) {
logger.error("Exception sending message(addListener) to service: " + e.getMessage());
}
}
/**
* Closes ethereum
*

View File

@ -11,6 +11,8 @@ import android.os.RemoteException;
import org.ethereum.android.jsonrpc.JsonRpcServer;
import org.ethereum.android.manager.BlockLoader;
import org.ethereum.android.service.events.EventData;
import org.ethereum.android.service.events.EventFlag;
import org.ethereum.core.Transaction;
import org.ethereum.facade.Ethereum;
import org.ethereum.manager.AdminInfo;
@ -21,7 +23,11 @@ import org.slf4j.LoggerFactory;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -31,11 +37,14 @@ public class EthereumRemoteService extends EthereumService {
private static final Logger logger = LoggerFactory.getLogger("EthereumRemoteService");
ArrayList<Messenger> clientListeners = new ArrayList<>();
static HashMap<String, Messenger> clientListeners = new HashMap<>();
static EnumMap<EventFlag, List<String>> listenersByType = new EnumMap<EventFlag, List<String>>(EventFlag.class);
public EthereumRemoteService() {
super();
}
/** Handles incoming messages from clients. */
@ -82,6 +91,47 @@ public class EthereumRemoteService extends EthereumService {
super.onCreate();
}
protected void broadcastEvent(EventFlag event, EventData data) {
Message message = null;
List<String> listeners = listenersByType.get(event);
if (listeners != null) {
for (String identifier: listeners) {
Messenger listener = clientListeners.get(identifier);
if (listener != null) {
if (message == null) {
message = createEventMessage(event, data);
}
message.obj = getIdentifierBundle(identifier);
try {
listener.send(message);
} catch (RemoteException e) {
logger.error("Exception sending event message to client listener: " + e.getMessage());
}
}
}
}
}
protected Bundle getIdentifierBundle(String identifier) {
Bundle bundle = new Bundle();
bundle.putString("identifier", identifier);
return bundle;
}
protected Message createEventMessage(EventFlag event, EventData data) {
Message message = Message.obtain(null, EthereumClientMessage.MSG_EVENT, 0, 0);
Bundle replyData = new Bundle();
replyData.putSerializable("event", event);
replyData.putParcelable("data", data);
message.setData(replyData);
return message;
}
protected boolean handleMessage(Message message) {
switch (message.what) {
@ -122,6 +172,10 @@ public class EthereumRemoteService extends EthereumService {
addListener(message);
break;
case EthereumServiceMessage.MSG_REMOVE_LISTENER:
removeListener(message);
break;
case EthereumServiceMessage.MSG_GET_CONNECTION_STATUS:
getConnectionStatus(message);
break;
@ -377,17 +431,55 @@ public class EthereumRemoteService extends EthereumService {
/**
* Add ethereum event listener
*
* Incoming message parameters: none
* Incoming message parameters ( "key": type [description] ):
* {
* "flags": Serializable(EnumSet<ListenerFlag>) [defines flags to listen to specific events]
* }
* Sends message: none
*/
protected void addListener(Message message) {
// Register the client's messenger
clientListeners.add(message.replyTo);
// TODO: Add channel listener types flags
String identifier = ((Bundle)message.obj).getString("identifier");
clientListeners.put(identifier, message.replyTo);
Bundle data = message.getData();
data.setClassLoader(EnumSet.class.getClassLoader());
EnumSet<EventFlag> flags = (EnumSet<EventFlag>)data.getSerializable("flags");
EnumSet<EventFlag> list = (flags == null || flags.contains(EventFlag.EVENT_ALL)) ? EnumSet.allOf(EventFlag.class) : flags;
for (EventFlag flag: list) {
List<String> listeners = listenersByType.get(flag);
boolean shouldAdd = false;
if (listeners == null) {
listeners = new ArrayList<>();
shouldAdd = true;
}
if (shouldAdd || !listeners.contains(identifier)) {
listeners.add(identifier);
listenersByType.put(flag, listeners);
}
}
logger.info("Client listener registered!");
}
/**
* Remove etherum event listener
*
* Incoming message parameters: none
* Sends message: none
*/
protected void removeListener(Message message) {
String identifier = ((Bundle)message.obj).getString("identifier");
clientListeners.remove(identifier);
for (EventFlag flag: EventFlag.values()) {
List<String> listeners = listenersByType.get(flag);
if (listeners != null && listeners.contains(identifier)) {
listeners.remove(identifier);
}
}
logger.info("Client listener unregistered!");
}
/**
* Closes ethereum
*

View File

@ -6,8 +6,15 @@ import android.os.IBinder;
import org.ethereum.android.di.components.DaggerEthereumComponent;
import org.ethereum.android.di.modules.EthereumModule;
import org.ethereum.android.interop.IListener;
import org.ethereum.android.jsonrpc.JsonRpcServer;
import org.ethereum.android.service.events.BlockEventData;
import org.ethereum.android.service.events.EventData;
import org.ethereum.android.service.events.EventFlag;
import org.ethereum.android.service.events.MessageEventData;
import org.ethereum.android.service.events.PeerDisconnectEventData;
import org.ethereum.android.service.events.PendingTransactionsEventData;
import org.ethereum.android.service.events.TraceEventData;
import org.ethereum.android.service.events.VMTraceCreatedEventData;
import org.ethereum.config.SystemProperties;
import org.ethereum.core.Transaction;
import org.ethereum.core.TransactionReceipt;
@ -19,18 +26,19 @@ import java.util.Set;
public class EthereumService extends Service {
boolean isConnected = false;
static boolean isConnected = false;
boolean isInitialized = false;
static boolean isInitialized = false;
protected Ethereum ethereum = null;
static Ethereum ethereum = null;
protected JsonRpcServer jsonRpcServer;
static JsonRpcServer jsonRpcServer;
public EthereumService() {
}
protected void broadcastMessage(String message) {
protected void broadcastEvent(EventFlag event, EventData data) {
}
@ -79,61 +87,61 @@ public class EthereumService extends Service {
@Override
public void trace(String output) {
broadcastMessage(output);
broadcastEvent(EventFlag.EVENT_TRACE, new TraceEventData(output));
}
@Override
public void onBlock(org.ethereum.core.Block block, List<TransactionReceipt> receipts) {
broadcastMessage("Added block.");
broadcastEvent(EventFlag.EVENT_BLOCK, new BlockEventData(block, receipts));
}
@Override
public void onRecvMessage(org.ethereum.net.message.Message message) {
broadcastMessage("Received message: " + message.getCommand().name());
broadcastEvent(EventFlag.EVENT_RECEIVE_MESSAGE, new MessageEventData(message.getClass(), message.getEncoded()));
}
@Override
public void onSendMessage(org.ethereum.net.message.Message message) {
broadcastMessage("Sending message: " + message.getCommand().name());
broadcastEvent(EventFlag.EVENT_SEND_MESSAGE, new MessageEventData(message.getClass(), message.getEncoded()));
}
@Override
public void onPeerDisconnect(String host, long port) {
broadcastMessage("Peer disconnected: " + host + ":" + port);
broadcastEvent(EventFlag.EVENT_PEER_DISCONNECT, new PeerDisconnectEventData(host, port));
}
@Override
public void onPendingTransactionsReceived(Set<Transaction> transactions) {
broadcastMessage("Pending transactions received: " + transactions.size());
broadcastEvent(EventFlag.EVENT_PENDING_TRANSACTIONS_RECEIVED, new PendingTransactionsEventData(transactions));
}
@Override
public void onSyncDone() {
broadcastMessage("Sync done");
broadcastEvent(EventFlag.EVENT_SYNC_DONE, new EventData());
}
@Override
public void onNoConnections() {
broadcastMessage("No connections");
broadcastEvent(EventFlag.EVENT_NO_CONNECTIONS, new EventData());
}
@Override
public void onHandShakePeer(HelloMessage helloMessage) {
broadcastMessage("Peer handshaked: " + helloMessage.getCode());
broadcastEvent(EventFlag.EVENT_HANDSHAKE_PEER, new MessageEventData(helloMessage.getClass(), helloMessage.getEncoded()));
}
@Override
public void onVMTraceCreated(String transactionHash, String trace) {
broadcastMessage("Trace created: " + " - ");
broadcastEvent(EventFlag.EVENT_VM_TRACE_CREATED, new VMTraceCreatedEventData(transactionHash, trace));
}
}
}

View File

@ -45,32 +45,36 @@ public class EthereumServiceMessage {
/**
* Command to the service to add a listener
* <Not Implemented>
*/
public static final int MSG_ADD_LISTENER = 9;
/**
* Command to the service to remove a listener
*/
public static final int MSG_REMOVE_LISTENER = 10;
/**
* Command to the service to get connection status (Connected/Not Connected)
*/
public static final int MSG_GET_CONNECTION_STATUS = 10;
public static final int MSG_GET_CONNECTION_STATUS = 11;
/**
* Command to the service to close
*/
public static final int MSG_CLOSE = 11;
public static final int MSG_CLOSE = 12;
/**
* Command to the service to submit a transaction
*/
public static final int MSG_SUBMIT_TRANSACTION = 12;
public static final int MSG_SUBMIT_TRANSACTION = 13;
/**
* Command to the service to get the admin info
*/
public static final int MSG_GET_ADMIN_INFO = 13;
public static final int MSG_GET_ADMIN_INFO = 14;
/**
* Command to the service to get the pernding transactions
*/
public static final int MSG_GET_PENDING_TRANSACTIONS = 14;
public static final int MSG_GET_PENDING_TRANSACTIONS = 15;
}

View File

@ -34,15 +34,15 @@ public class ServiceConnector {
protected Class serviceClass;
/** Flag indicating if the service is bound. */
boolean isBound;
protected boolean isBound;
/** Sends messages to the service. */
Messenger serviceMessenger = null;
protected Messenger serviceMessenger = null;
/** Receives messages from the service. */
Messenger clientMessenger = null;
protected Messenger clientMessenger = null;
ArrayList<ConnectorHandler> handlers = new ArrayList<>();
protected ArrayList<ConnectorHandler> handlers = new ArrayList<>();
/** Handles incoming messages from service. */
class IncomingHandler extends Handler {
@ -74,7 +74,33 @@ public class ServiceConnector {
/**
* Class for interacting with the main interface of the service.
*/
protected ServiceConnection serviceConnection = null;
protected ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the object we can use to
// interact with the service. We are communicating with the
// service using a Messenger, so here we get a client-side
// representation of that from the raw IBinder object.
serviceMessenger = new Messenger(service);
isBound = true;
for (ConnectorHandler handler: handlers) {
handler.onConnectorConnected();
}
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
serviceMessenger = null;
isBound = false;
for (ConnectorHandler handler: handlers) {
handler.onConnectorDisconnected();
}
}
};
public ServiceConnector(Context context, Class serviceClass) {
@ -84,32 +110,6 @@ public class ServiceConnector {
handlerThread.start();
handler = new IncomingHandler(handlerThread);
clientMessenger = new Messenger(handler);
initializeServiceConnection();
}
protected void initializeServiceConnection() {
serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the object we can use to
// interact with the service. We are communicating with the
// service using a Messenger, so here we get a client-side
// representation of that from the raw IBinder object.
serviceMessenger = new Messenger(service);
isBound = true;
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
serviceMessenger = null;
isBound = false;
}
};
}
/** Bind to the service */
@ -134,7 +134,9 @@ public class ServiceConnector {
public void registerHandler(ConnectorHandler handler) {
handlers.add(handler);
if (!handlers.contains(handler)) {
handlers.add(handler);
}
}
}

View File

@ -0,0 +1,65 @@
package org.ethereum.android.service.events;
import android.os.Parcel;
import android.os.Parcelable;
import org.ethereum.core.Block;
import org.ethereum.core.TransactionReceipt;
import java.util.Arrays;
import java.util.List;
public class BlockEventData extends EventData {
public Block block;
public List<TransactionReceipt> receipts;
public BlockEventData(Block block, List<TransactionReceipt> receipts) {
super();
this.block = block;
this.receipts = receipts;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
super.writeToParcel(parcel, i);
parcel.writeParcelable(new org.ethereum.android.interop.Block(block), i);
org.ethereum.android.interop.TransactionReceipt[] transactionReceipts = new org.ethereum.android.interop.TransactionReceipt[receipts.size()];
int index = 0;
for (TransactionReceipt receipt: receipts) {
transactionReceipts[index] = new org.ethereum.android.interop.TransactionReceipt(receipt);
}
parcel.writeParcelableArray(transactionReceipts, i);
}
public static final Parcelable.Creator<BlockEventData> CREATOR = new Parcelable.Creator<BlockEventData>() {
public BlockEventData createFromParcel(Parcel in) {
return new BlockEventData(in);
}
public BlockEventData[] newArray(int size) {
return new BlockEventData[size];
}
};
protected BlockEventData(Parcel in) {
super(in);
block = in.readParcelable(org.ethereum.android.interop.Block.class.getClassLoader());
receipts = Arrays.asList((TransactionReceipt[])in.readParcelableArray(TransactionReceipt.class.getClassLoader()));
}
}

View File

@ -0,0 +1,46 @@
package org.ethereum.android.service.events;
import android.os.Parcel;
import android.os.Parcelable;
public class EventData implements Parcelable {
public long registeredTime;
public EventData() {
registeredTime = System.currentTimeMillis();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeLong(registeredTime);
}
public static final Parcelable.Creator<EventData> CREATOR = new Parcelable.Creator<EventData>() {
public EventData createFromParcel(Parcel in) {
return new EventData(in);
}
public EventData[] newArray(int size) {
return new EventData[size];
}
};
protected EventData(Parcel in) {
registeredTime = in.readLong();
}
}

View File

@ -0,0 +1,60 @@
package org.ethereum.android.service.events;
public enum EventFlag {
/**
* Listen to all events
*/
EVENT_ALL,
/**
* Trace messages event
*/
EVENT_TRACE,
/**
* onBlock event
*/
EVENT_BLOCK,
/**
* Received message event
*/
EVENT_RECEIVE_MESSAGE,
/**
* Send message event
*/
EVENT_SEND_MESSAGE,
/**
* Peer disconnect event
*/
EVENT_PEER_DISCONNECT,
/**
* Pending transactions received event
*/
EVENT_PENDING_TRANSACTIONS_RECEIVED,
/**
* Sync done event
*/
EVENT_SYNC_DONE,
/**
* No connections event
*/
EVENT_NO_CONNECTIONS,
/**
* Peer handshake event
*/
EVENT_HANDSHAKE_PEER,
/**
* VM trace created event
*/
EVENT_VM_TRACE_CREATED
}

View File

@ -0,0 +1,54 @@
package org.ethereum.android.service.events;
import android.os.Parcel;
import android.os.Parcelable;
public class MessageEventData extends EventData {
public Class messageClass;
public byte[] message;
public MessageEventData(Class messageClass, byte[] encodedMessage) {
super();
this.messageClass = messageClass;
this.message = encodedMessage;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
super.writeToParcel(parcel, i);
parcel.writeInt(message.length);
parcel.writeByteArray(message);
parcel.writeSerializable(messageClass);
}
public static final Parcelable.Creator<MessageEventData> CREATOR = new Parcelable.Creator<MessageEventData>() {
public MessageEventData createFromParcel(Parcel in) {
return new MessageEventData(in);
}
public MessageEventData[] newArray(int size) {
return new MessageEventData[size];
}
};
private MessageEventData(Parcel in) {
super(in);
message = new byte[in.readInt()];
in.readByteArray(message);
messageClass = (Class)in.readSerializable();
}
}

View File

@ -0,0 +1,52 @@
package org.ethereum.android.service.events;
import android.os.Parcel;
import android.os.Parcelable;
public class PeerDisconnectEventData extends EventData {
public String host;
public long port;
public PeerDisconnectEventData(String host, long port) {
super();
this.host = host;
this.port = port;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
super.writeToParcel(parcel, i);
parcel.writeString(host);
parcel.writeLong(port);
}
public static final Parcelable.Creator<PeerDisconnectEventData> CREATOR = new Parcelable.Creator<PeerDisconnectEventData>() {
public PeerDisconnectEventData createFromParcel(Parcel in) {
return new PeerDisconnectEventData(in);
}
public PeerDisconnectEventData[] newArray(int size) {
return new PeerDisconnectEventData[size];
}
};
private PeerDisconnectEventData(Parcel in) {
super(in);
host = in.readString();
port = in.readLong();
}
}

View File

@ -0,0 +1,60 @@
package org.ethereum.android.service.events;
import android.os.Parcel;
import android.os.Parcelable;
import org.ethereum.core.Transaction;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class PendingTransactionsEventData extends EventData {
public Set<Transaction> transactions;
public PendingTransactionsEventData(Set<Transaction> transactions) {
super();
this.transactions = transactions;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
super.writeToParcel(parcel, i);
org.ethereum.android.interop.Transaction[] txs = new org.ethereum.android.interop.Transaction[transactions.size()];
int index = 0;
for (Transaction transaction: transactions) {
txs[index] = new org.ethereum.android.interop.Transaction(transaction);
}
parcel.writeParcelableArray(txs, i);
}
public static final Parcelable.Creator<PendingTransactionsEventData> CREATOR = new Parcelable.Creator<PendingTransactionsEventData>() {
public PendingTransactionsEventData createFromParcel(Parcel in) {
return new PendingTransactionsEventData(in);
}
public PendingTransactionsEventData[] newArray(int size) {
return new PendingTransactionsEventData[size];
}
};
private PendingTransactionsEventData(Parcel in) {
super(in);
transactions = new HashSet<Transaction>(Arrays.asList((Transaction[])in.readParcelableArray(org.ethereum.android.interop.Transaction.class.getClassLoader())));
}
}

View File

@ -0,0 +1,47 @@
package org.ethereum.android.service.events;
import android.os.Parcel;
import android.os.Parcelable;
public class TraceEventData extends EventData {
public String message;
public TraceEventData(String message) {
super();
this.message = message;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
super.writeToParcel(parcel, i);
parcel.writeString(message);
}
public static final Parcelable.Creator<TraceEventData> CREATOR = new Parcelable.Creator<TraceEventData>() {
public TraceEventData createFromParcel(Parcel in) {
return new TraceEventData(in);
}
public TraceEventData[] newArray(int size) {
return new TraceEventData[size];
}
};
private TraceEventData(Parcel in) {
super(in);
message = in.readString();
}
}

View File

@ -0,0 +1,52 @@
package org.ethereum.android.service.events;
import android.os.Parcel;
import android.os.Parcelable;
public class VMTraceCreatedEventData extends EventData {
public String transactionHash;
public String trace;
public VMTraceCreatedEventData(String transactionHash, String trace) {
super();
this.transactionHash = transactionHash;
this.trace = trace;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
super.writeToParcel(parcel, i);
parcel.writeString(transactionHash);
parcel.writeString(trace);
}
public static final Parcelable.Creator<VMTraceCreatedEventData> CREATOR = new Parcelable.Creator<VMTraceCreatedEventData>() {
public VMTraceCreatedEventData createFromParcel(Parcel in) {
return new VMTraceCreatedEventData(in);
}
public VMTraceCreatedEventData[] newArray(int size) {
return new VMTraceCreatedEventData[size];
}
};
private VMTraceCreatedEventData(Parcel in) {
super(in);
transactionHash = in.readString();
trace = in.readString();
}
}

View File

@ -26,10 +26,10 @@ public class TransactionReceipt {
private Transaction transaction;
private byte[] postTxState = EMPTY_BYTE_ARRAY;
private byte[] cumulativeGas = EMPTY_BYTE_ARRAY;
private Bloom bloomFilter = new Bloom();
private List<LogInfo> logInfoList = new ArrayList<>();
protected byte[] postTxState = EMPTY_BYTE_ARRAY;
protected byte[] cumulativeGas = EMPTY_BYTE_ARRAY;
protected Bloom bloomFilter = new Bloom();
protected List<LogInfo> logInfoList = new ArrayList<>();
/* Tx Receipt in encoded form */
private byte[] rlpEncoded;
@ -39,6 +39,11 @@ public class TransactionReceipt {
public TransactionReceipt(byte[] rlp) {
parseRlp(rlp);
}
protected void parseRlp(byte[] rlp) {
RLPList params = RLP.decode2(rlp);
RLPList receipt = (RLPList) params.get(0);
@ -55,7 +60,6 @@ public class TransactionReceipt {
LogInfo logInfo = new LogInfo(log.getRLPData());
logInfoList.add(logInfo);
}
rlpEncoded = rlp;
}