Implemented ethereum event listeners for remote service.
This commit is contained in:
parent
e3ca3aa951
commit
bc91b5f13b
|
@ -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() {
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -6,5 +6,7 @@ import android.os.Message;
|
|||
public interface ConnectorHandler {
|
||||
|
||||
boolean handleMessage(Message message);
|
||||
void onConnectorConnected();
|
||||
void onConnectorDisconnected();
|
||||
String getID();
|
||||
}
|
||||
|
|
|
@ -72,7 +72,6 @@ public class EthereumAidlService extends EthereumService {
|
|||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void broadcastMessage(String message) {
|
||||
|
||||
for (IListener listener: clientListeners) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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())));
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue