merge
This commit is contained in:
commit
b35ffa0581
|
@ -21,6 +21,7 @@ android {
|
|||
minSdkVersion 14
|
||||
targetSdkVersion 22
|
||||
multiDexEnabled true
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
|
@ -51,10 +52,17 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':ethereumj-core-android')
|
||||
compile (project(':ethereumj-core-android')) {
|
||||
exclude group: "org.hibernate", module: "hibernate-core"
|
||||
}
|
||||
compile 'com.android.support:multidex:1.0.0'
|
||||
compile fileTree(include: ['*.jar'], dir: '../libraries')
|
||||
compile 'com.android.support:support-v4:22.1.1'
|
||||
compile 'com.android.support:appcompat-v7:22.1.1'
|
||||
compile 'com.android.support:recyclerview-v7:22.1.1'
|
||||
compile 'com.android.support:support-v4:22.2.0'
|
||||
compile 'com.android.support:appcompat-v7:22.2.0'
|
||||
compile 'com.android.support:recyclerview-v7:22.2.0'
|
||||
|
||||
androidTestCompile 'com.android.support.test:runner:0.3'
|
||||
// Set this dependency to use JUnit 4 rules
|
||||
androidTestCompile 'com.android.support.test:rules:0.3'
|
||||
|
||||
}
|
|
@ -0,0 +1,311 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
|
||||
import com.j256.ormlite.android.apptools.OpenHelperManager;
|
||||
|
||||
import org.ethereum.android.db.OrmLiteBlockStoreDatabase;
|
||||
import org.ethereum.android.util.Scanner;
|
||||
import org.ethereum.config.SystemProperties;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.db.BlockStore;
|
||||
import org.ethereum.android.db.InMemoryBlockStore;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static java.math.BigInteger.ZERO;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class InMemoryBlockStoreTest extends ActivityInstrumentationTestCase2<TestActivity> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||
|
||||
private static boolean loaded = false;
|
||||
|
||||
private TestActivity activity;
|
||||
private List<Block> blocks = new ArrayList<>();
|
||||
private OrmLiteBlockStoreDatabase database;
|
||||
|
||||
public InMemoryBlockStoreTest() {
|
||||
|
||||
super(TestActivity.class);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
super.setUp();
|
||||
loaded = false;
|
||||
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
|
||||
activity = getActivity();
|
||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getTargetContext().getAssets().open("blockstore");
|
||||
final Scanner scanner = new Scanner(inputStream);
|
||||
ThreadGroup group = new ThreadGroup("threadGroup");
|
||||
new Thread(group, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
logger.info("Loading blocks.");
|
||||
|
||||
BigInteger cumDifficulty = ZERO;
|
||||
|
||||
while (scanner.hasNext()) {
|
||||
|
||||
String blockString = scanner.nextLine();
|
||||
|
||||
logger.info("BlockString: " + blockString);
|
||||
try {
|
||||
Block block = new Block(
|
||||
Hex.decode(blockString));
|
||||
//if (block.getNumber() % 1000 == 0)
|
||||
logger.info("adding block.hash: [{}] block.number: [{}]",
|
||||
block.getShortHash(),
|
||||
block.getNumber());
|
||||
|
||||
blocks.add(block);
|
||||
cumDifficulty = cumDifficulty.add(block.getCumulativeDifficulty());
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("total difficulty: {}", cumDifficulty);
|
||||
InMemoryBlockStoreTest.loaded = true;
|
||||
}
|
||||
}, "EthereumConnect", 32768000).start();
|
||||
|
||||
|
||||
database = OpenHelperManager.getHelper(activity, OrmLiteBlockStoreDatabase.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSet0() {
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
assertThat(activity, notNullValue());
|
||||
assertThat(getInstrumentation(), notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmpty(){
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
BlockStore blockStore = new InMemoryBlockStore(database);
|
||||
assertNull(blockStore.getBestBlock());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFlush(){
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
BlockStore blockStore = new InMemoryBlockStore(database);
|
||||
|
||||
for( Block block : blocks ){
|
||||
blockStore.saveBlock(block, null);
|
||||
}
|
||||
|
||||
blockStore.flush();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleLoad(){
|
||||
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
|
||||
BlockStore blockStore = new InMemoryBlockStore(database);
|
||||
|
||||
for( Block block : blocks ){
|
||||
blockStore.saveBlock(block, null);
|
||||
}
|
||||
|
||||
blockStore.flush();
|
||||
|
||||
blockStore = new InMemoryBlockStore(database);
|
||||
|
||||
blockStore.load();
|
||||
|
||||
assertTrue(blockStore.getBestBlock().getNumber() == 8003);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFlushEach1000(){
|
||||
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
InMemoryBlockStore blockStore = new InMemoryBlockStore(database);
|
||||
|
||||
for( int i = 0; i < blocks.size(); ++i ){
|
||||
|
||||
blockStore.saveBlock(blocks.get(i), null);
|
||||
if ( i % 1000 == 0){
|
||||
blockStore.flush();
|
||||
//assertTrue(blockStore.blocks.size() == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testBlockHashByNumber(){
|
||||
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
BlockStore blockStore = new InMemoryBlockStore(database);
|
||||
|
||||
for( Block block : blocks ){
|
||||
blockStore.saveBlock(block, null);
|
||||
}
|
||||
|
||||
String hash = Hex.toHexString(blockStore.getBlockHashByNumber(7000));
|
||||
assertTrue(hash.startsWith("459a8f"));
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockHashByNumber(6000));
|
||||
assertTrue(hash.startsWith("7a577a"));
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockHashByNumber(5000));
|
||||
assertTrue(hash.startsWith("820aa7"));
|
||||
|
||||
blockStore.flush();
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockHashByNumber(7000));
|
||||
assertTrue(hash.startsWith("459a8f"));
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockHashByNumber(6000));
|
||||
assertTrue(hash.startsWith("7a577a"));
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockHashByNumber(5000));
|
||||
assertTrue(hash.startsWith("820aa7"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockByNumber(){
|
||||
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
BlockStore blockStore = new InMemoryBlockStore(database);
|
||||
|
||||
for( Block block : blocks ){
|
||||
blockStore.saveBlock(block, null);
|
||||
}
|
||||
|
||||
String hash = Hex.toHexString(blockStore.getBlockByNumber(7000).getHash());
|
||||
assertTrue(hash.startsWith("459a8f"));
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockByNumber(6000).getHash());
|
||||
assertTrue(hash.startsWith("7a577a"));
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockByNumber(5000).getHash());
|
||||
assertTrue(hash.startsWith("820aa7"));
|
||||
|
||||
blockStore.flush();
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockByNumber(7000).getHash());
|
||||
assertTrue(hash.startsWith("459a8f"));
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockByNumber(6000).getHash());
|
||||
assertTrue(hash.startsWith("7a577a"));
|
||||
|
||||
hash = Hex.toHexString(blockStore.getBlockByNumber(5000).getHash());
|
||||
assertTrue(hash.startsWith("820aa7"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGetBlockByNumber() {
|
||||
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
BlockStore blockStore = new InMemoryBlockStore(database);
|
||||
|
||||
for( Block block : blocks ){
|
||||
blockStore.saveBlock(block, null);
|
||||
}
|
||||
|
||||
assertEquals("4312750101", blockStore.getTotalDifficulty().toString());
|
||||
|
||||
blockStore.flush();
|
||||
assertEquals("4312750101", blockStore.getTotalDifficulty().toString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDbGetBlockByHash(){
|
||||
|
||||
while(!loaded) {
|
||||
//Thread.sleep(1000);
|
||||
}
|
||||
BlockStore blockStore = new InMemoryBlockStore(database);
|
||||
|
||||
for( Block block : blocks ){
|
||||
blockStore.saveBlock(block, null);
|
||||
}
|
||||
|
||||
byte[] hash7000 = Hex.decode("459a8f0ee5d4b0c9ea047797606c94f0c1158ed0f30120490b96f7df9893e1fa");
|
||||
byte[] hash6000 = Hex.decode("7a577a6b0b7e72e51a646c4cec82cf684c977bca6307e2a49a4116af49316159");
|
||||
byte[] hash5000 = Hex.decode("820aa786619e1a2ae139877ba342078c83e5bd65c559069336c13321441e03dc");
|
||||
|
||||
Long number = blockStore.getBlockByHash(hash7000).getNumber();
|
||||
assertTrue(number == 7000);
|
||||
|
||||
number = blockStore.getBlockByHash(hash6000).getNumber();
|
||||
assertTrue(number == 6000);
|
||||
|
||||
number = blockStore.getBlockByHash(hash5000).getNumber();
|
||||
assertTrue(number == 5000);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@Ignore // TO much time to run it on general basis
|
||||
@Test
|
||||
public void save100KBlocks() throws FileNotFoundException {
|
||||
|
||||
String blocksFile = "E:\\temp\\_poc-9-blocks\\poc-9-492k.dmp";
|
||||
|
||||
FileInputStream inputStream = new FileInputStream(blocksFile);
|
||||
Scanner scanner = new Scanner(inputStream, "UTF-8");
|
||||
|
||||
BlockStore blockStore = new InMemoryBlockStore();
|
||||
//blockStore.setSessionFactory(sessionFactory());
|
||||
|
||||
|
||||
while (scanner.hasNextLine()) {
|
||||
|
||||
byte[] blockRLPBytes = Hex.decode( scanner.nextLine());
|
||||
Block block = new Block(blockRLPBytes);
|
||||
|
||||
System.out.println(block.getNumber());
|
||||
|
||||
blockStore.saveBlock(block, null);
|
||||
|
||||
if (block.getNumber() > 100_000) break;
|
||||
}
|
||||
|
||||
blockStore.flush();
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
import android.os.Environment;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
|
||||
import org.ethereum.android.datasource.LevelDbDataSource;
|
||||
import org.ethereum.config.SystemProperties;
|
||||
import org.ethereum.datasource.KeyValueDataSource;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class LevelDbDataSourceTest extends ActivityInstrumentationTestCase2<TestActivity> {
|
||||
|
||||
private TestActivity activity;
|
||||
|
||||
public LevelDbDataSourceTest() {
|
||||
|
||||
super(TestActivity.class);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
super.setUp();
|
||||
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
|
||||
activity = getActivity();
|
||||
System.setProperty("sun.arch.data.model", "32");
|
||||
System.setProperty("leveldb.mmap", "false");
|
||||
String databaseFolder = null;
|
||||
File extStore = Environment.getExternalStorageDirectory();
|
||||
if (extStore.exists()) {
|
||||
databaseFolder = extStore.getAbsolutePath();
|
||||
} else {
|
||||
databaseFolder = activity.getApplicationInfo().dataDir;
|
||||
}
|
||||
if (databaseFolder != null) {
|
||||
System.out.println("Database folder: " + databaseFolder);
|
||||
SystemProperties.CONFIG.setDataBaseDir(databaseFolder);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSet0() {
|
||||
|
||||
assertThat(activity, notNullValue());
|
||||
assertThat(getInstrumentation(), notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSet1() {
|
||||
|
||||
KeyValueDataSource dataSource = createDataSource("test-state");
|
||||
try {
|
||||
byte[] key = Hex.decode("a1a2a3");
|
||||
byte[] val = Hex.decode("b1b2b3");
|
||||
|
||||
dataSource.put(key, val);
|
||||
byte[] val2 = dataSource.get(key);
|
||||
|
||||
assertThat(Hex.toHexString(val), is(Hex.toHexString(val2)));
|
||||
} finally {
|
||||
clear(dataSource);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSet2() {
|
||||
|
||||
KeyValueDataSource states = createDataSource("test-state");
|
||||
KeyValueDataSource details = createDataSource("test-details");
|
||||
|
||||
try {
|
||||
byte[] key = Hex.decode("a1a2a3");
|
||||
byte[] val1 = Hex.decode("b1b2b3");
|
||||
byte[] val2 = Hex.decode("c1c2c3");
|
||||
|
||||
states.put(key, val1);
|
||||
details.put(key, val2);
|
||||
|
||||
byte[] res1 = states.get(key);
|
||||
byte[] res2 = details.get(key);
|
||||
|
||||
assertThat(Hex.toHexString(val1), is(Hex.toHexString(res1)));
|
||||
assertThat(Hex.toHexString(val2), is(Hex.toHexString(res2)));
|
||||
} finally {
|
||||
clear(states);
|
||||
clear(details);
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
|
||||
private KeyValueDataSource createDataSource(String name) {
|
||||
|
||||
LevelDbDataSource result = new LevelDbDataSource();
|
||||
result.setName(name);
|
||||
result.init();
|
||||
return result;
|
||||
}
|
||||
|
||||
private void clear(KeyValueDataSource dataSource) {
|
||||
|
||||
((LevelDbDataSource) dataSource).close();
|
||||
}
|
||||
|
||||
}
|
|
@ -2,15 +2,19 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.ethereum.android_app" >
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
||||
<application
|
||||
android:name="org.ethereum.android_app.EthereumApplication"
|
||||
android:name=".EthereumApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:largeHeap="true"
|
||||
android:theme="@style/AppTheme" >
|
||||
<activity
|
||||
android:name="org.ethereum.android_app.MainActivity"
|
||||
android:name=".RemoteMainActivity"
|
||||
android:label="@string/app_name" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
@ -18,8 +22,28 @@
|
|||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".TestActivity"
|
||||
android:label="@string/title_activity_test" >
|
||||
</activity>
|
||||
|
||||
<service
|
||||
android:name=".EthereumService"
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:process=":ethereum_process" >
|
||||
</service>
|
||||
<service
|
||||
android:name=".EthereumRemoteService"
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:process=":ethereum_remote_process" >
|
||||
</service>
|
||||
|
||||
<activity
|
||||
android:name=".AidlMainActivity"
|
||||
android:label="@string/app_name" >
|
||||
</activity>
|
||||
</application>
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
|
||||
</manifest>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,7 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
|
||||
public interface ActivityInterface {
|
||||
|
||||
void registerFragment(FragmentInterface fragment);
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.Environment;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.ethereum.android.interop.IEthereumService;
|
||||
import org.ethereum.android.interop.IListener;
|
||||
import org.ethereum.config.SystemProperties;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class AidlMainActivity extends ActionBarActivity implements ActivityInterface {
|
||||
|
||||
private static final String TAG = "MyActivity";
|
||||
|
||||
private Toolbar toolbar;
|
||||
private ViewPager viewPager;
|
||||
private SlidingTabLayout tabs;
|
||||
private TabsPagerAdapter adapter;
|
||||
protected ArrayList<FragmentInterface> fragments = new ArrayList<>();
|
||||
|
||||
protected static String consoleLog = "";
|
||||
|
||||
/** Ethereum Aidl Service. */
|
||||
IEthereumService ethereumService = null;
|
||||
|
||||
IListener.Stub ethereumListener = new IListener.Stub() {
|
||||
|
||||
public void trace(String message) throws RemoteException {
|
||||
|
||||
logMessage(message);
|
||||
}
|
||||
};
|
||||
|
||||
/** Flag indicating whether we have called bind on the service. */
|
||||
boolean isBound;
|
||||
|
||||
/**
|
||||
* Class for interacting with the main interface of the service.
|
||||
*/
|
||||
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 service object we can use to
|
||||
// interact with the service. We are communicating with our
|
||||
// service through an IDL interface, so get a client-side
|
||||
// representation of that from the raw service object.
|
||||
ethereumService = IEthereumService.Stub.asInterface(service);
|
||||
Toast.makeText(AidlMainActivity.this, "service attached", Toast.LENGTH_SHORT).show();
|
||||
|
||||
try {
|
||||
|
||||
|
||||
// Try to load blocks dump file from /sdcard/poc-9-492k.dmp
|
||||
String blocksDump = null;
|
||||
File extStore = Environment.getExternalStorageDirectory();
|
||||
if (extStore.exists()) {
|
||||
String sdcardPath = extStore.getAbsolutePath();
|
||||
File dumpFile = new File(extStore, "poc-9-492k.dmp");
|
||||
if (dumpFile.exists()) {
|
||||
blocksDump = dumpFile.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
// Start json rpc server
|
||||
ethereumService.startJsonRpcServer();
|
||||
// If blocks dump not found, connect to peer
|
||||
if (blocksDump != null) {
|
||||
ethereumService.loadBlocks(blocksDump);
|
||||
} else {
|
||||
ethereumService.addListener(ethereumListener);
|
||||
ethereumService.connect(SystemProperties.CONFIG.activePeerIP(),
|
||||
SystemProperties.CONFIG.activePeerPort(),
|
||||
SystemProperties.CONFIG.activePeerNodeid());
|
||||
}
|
||||
Toast.makeText(AidlMainActivity.this, "connected to service", Toast.LENGTH_SHORT).show();
|
||||
} catch (Exception e) {
|
||||
logMessage("Error adding listener: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void onServiceDisconnected(ComponentName className) {
|
||||
|
||||
// This is called when the connection with the service has been
|
||||
// unexpectedly disconnected -- that is, its process crashed.
|
||||
ethereumService = null;
|
||||
Toast.makeText(AidlMainActivity.this, "service disconnected", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
toolbar = (Toolbar) findViewById(R.id.tool_bar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
adapter = new TabsPagerAdapter(getSupportFragmentManager());
|
||||
viewPager = (ViewPager) findViewById(R.id.pager);
|
||||
viewPager.setAdapter(adapter);;
|
||||
|
||||
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
|
||||
tabs.setDistributeEvenly(true);
|
||||
tabs.setViewPager(viewPager);
|
||||
|
||||
ComponentName myService = startService(new Intent(AidlMainActivity.this, EthereumService.class));
|
||||
doBindService();
|
||||
|
||||
//StrictMode.enableDefaults();
|
||||
}
|
||||
|
||||
protected void logMessage(String message) {
|
||||
|
||||
AidlMainActivity.consoleLog += message + "\n";
|
||||
int consoleLength = AidlMainActivity.consoleLog.length();
|
||||
if (consoleLength > 5000) {
|
||||
AidlMainActivity.consoleLog = AidlMainActivity.consoleLog.substring(4000);
|
||||
}
|
||||
|
||||
broadcastFragments(AidlMainActivity.consoleLog);
|
||||
}
|
||||
|
||||
|
||||
protected void broadcastFragments(String message) {
|
||||
|
||||
for (FragmentInterface fragment : fragments) {
|
||||
fragment.onMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
void doBindService() {
|
||||
|
||||
// Establish a connection with the service. We use an explicit
|
||||
// class name because there is no reason to be able to let other
|
||||
// applications replace our component.
|
||||
bindService(new Intent(AidlMainActivity.this, EthereumService.class), serviceConnection, Context.BIND_AUTO_CREATE);
|
||||
isBound = true;
|
||||
Toast.makeText(AidlMainActivity.this, "binding to service", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
void doUnbindService() {
|
||||
|
||||
if (isBound) {
|
||||
// If we have received the service, and hence registered with
|
||||
// it, then now is the time to unregister.
|
||||
if (ethereumService != null) {
|
||||
try {
|
||||
ethereumService.removeListener(ethereumListener);
|
||||
} catch (RemoteException e) {
|
||||
// There is nothing special we need to do if the service
|
||||
// has crashed.
|
||||
}
|
||||
}
|
||||
|
||||
// Detach our existing connection.
|
||||
unbindService(serviceConnection);
|
||||
isBound = false;
|
||||
Toast.makeText(AidlMainActivity.this, "unbinding from service", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
public void registerFragment(FragmentInterface fragment) {
|
||||
|
||||
if (!fragments.contains(fragment)) {
|
||||
fragments.add(fragment);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
|
||||
getMenuInflater().inflate(R.menu.menu_main, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
// Handle action bar item clicks here. The action bar will
|
||||
// automatically handle clicks on the Home/Up button, so long
|
||||
// as you specify a parent activity in AndroidManifest.xml.
|
||||
int id = item.getItemId();
|
||||
Log.v(TAG, Integer.valueOf(id).toString());
|
||||
//noinspection SimplifiableIfStatement
|
||||
if (id == R.id.action_settings) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
|
||||
super.onDestroy();
|
||||
doUnbindService();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
|
@ -12,45 +13,54 @@ import android.widget.TextView;
|
|||
import org.ethereum.android.EthereumManager;
|
||||
import org.ethereum.listener.EthereumListenerAdapter;
|
||||
|
||||
public class ConsoleFragment extends Fragment {
|
||||
public class ConsoleFragment extends Fragment implements FragmentInterface {
|
||||
|
||||
EthereumManager ethereumManager;
|
||||
private TextView console;
|
||||
|
||||
TextViewUpdater consoleUpdater = new TextViewUpdater();
|
||||
|
||||
private class TextViewUpdater implements Runnable {
|
||||
|
||||
private String txt;
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
console.setText(txt);
|
||||
}
|
||||
public void setText(String txt) {
|
||||
|
||||
this.txt = txt;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
|
||||
super.onAttach(activity);
|
||||
ActivityInterface activityInterface = (ActivityInterface) activity;
|
||||
activityInterface.registerFragment(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
|
||||
View view = inflater.inflate(R.layout.fragment_console, container, false);
|
||||
console = (TextView) view.findViewById(R.id.console);
|
||||
console.setMovementMethod(new ScrollingMovementMethod());
|
||||
console.append("aaaa");
|
||||
return view;
|
||||
|
||||
}
|
||||
|
||||
public void setEthereumManager(EthereumManager ethereumManager) {
|
||||
public void onMessage(String message) {
|
||||
|
||||
this.ethereumManager = ethereumManager;
|
||||
/*
|
||||
ethereumManager.addListener(new EthereumListenerAdapter() {
|
||||
|
||||
@Override
|
||||
public void trace(final String output) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//console.append(output);
|
||||
consoleUpdater.setText(message);
|
||||
ConsoleFragment.this.console.post(consoleUpdater);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
public void updateDuration(long duration) {
|
||||
console.append(String.valueOf(duration/1000) + "seconds");
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -3,11 +3,24 @@ package org.ethereum.android_app;
|
|||
|
||||
import android.support.multidex.MultiDexApplication;
|
||||
|
||||
import org.ethereum.android.service.EthereumConnector;
|
||||
|
||||
public class EthereumApplication extends MultiDexApplication {
|
||||
|
||||
public EthereumConnector ethereum = null;
|
||||
public String log="";
|
||||
|
||||
@Override public void onCreate() {
|
||||
|
||||
super.onCreate();
|
||||
|
||||
ethereum = new EthereumConnector(this, EthereumRemoteService.class);
|
||||
ethereum.bindService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTerminate() {
|
||||
|
||||
super.onTerminate();
|
||||
ethereum.unbindService();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
|
||||
public class EthereumRemoteService extends org.ethereum.android.service.EthereumRemoteService {
|
||||
|
||||
public EthereumRemoteService() {
|
||||
|
||||
super();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
import org.ethereum.android.service.EthereumAidlService;
|
||||
import org.ethereum.android.interop.IListener;
|
||||
|
||||
public class EthereumService extends EthereumAidlService {
|
||||
|
||||
public EthereumService() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void broadcastMessage(String message) {
|
||||
|
||||
updateLog(message);
|
||||
for (IListener listener: clientListeners) {
|
||||
try {
|
||||
listener.trace(message);
|
||||
} catch (Exception e) {
|
||||
// Remove listener
|
||||
clientListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLog(String message) {
|
||||
|
||||
EthereumService.log += message;
|
||||
int logLength = EthereumService.log.length();
|
||||
if (logLength > 5000) {
|
||||
EthereumService.log = EthereumService.log.substring(2500);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
public interface FragmentInterface {
|
||||
|
||||
void onMessage(String message);
|
||||
}
|
|
@ -1,179 +0,0 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Environment;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.os.Build;
|
||||
|
||||
import org.ethereum.android.EthereumManager;
|
||||
import org.ethereum.config.SystemProperties;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
||||
public class MainActivity extends ActionBarActivity {
|
||||
|
||||
private static final String TAG = "MyActivity";
|
||||
private static Integer quit = 0;
|
||||
|
||||
private Toolbar toolbar;
|
||||
private ViewPager viewPager;
|
||||
private SlidingTabLayout tabs;
|
||||
private TabsPagerAdapter adapter;
|
||||
|
||||
public EthereumManager ethereumManager = null;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
toolbar = (Toolbar) findViewById(R.id.tool_bar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
String databaseFolder = null;
|
||||
File extStore = Environment.getExternalStorageDirectory();
|
||||
if (extStore.exists()) {
|
||||
databaseFolder = extStore.getAbsolutePath();
|
||||
} else {
|
||||
databaseFolder = getApplicationInfo().dataDir;
|
||||
}
|
||||
|
||||
ethereumManager = new EthereumManager(this, databaseFolder);
|
||||
|
||||
adapter = new TabsPagerAdapter(getSupportFragmentManager(), ethereumManager);
|
||||
viewPager = (ViewPager) findViewById(R.id.pager);
|
||||
viewPager.setAdapter(adapter);;
|
||||
|
||||
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
|
||||
tabs.setDistributeEvenly(true);
|
||||
tabs.setViewPager(viewPager);
|
||||
|
||||
//StrictMode.enableDefaults();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
|
||||
new PostTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else
|
||||
new PostTask().execute();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
|
||||
new JsonRpcTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else
|
||||
new JsonRpcTask().execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
//return super.onCreateOptionsMenu(menu);
|
||||
getMenuInflater().inflate(R.menu.menu_main, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
// Handle action bar item clicks here. The action bar will
|
||||
// automatically handle clicks on the Home/Up button, so long
|
||||
// as you specify a parent activity in AndroidManifest.xml.
|
||||
int id = item.getItemId();
|
||||
Log.v(TAG, Integer.valueOf(id).toString());
|
||||
//noinspection SimplifiableIfStatement
|
||||
if (id == R.id.action_settings) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
ethereumManager.onDestroy();
|
||||
}
|
||||
|
||||
// The definition of our task class
|
||||
private class PostTask extends AsyncTask<Context, Integer, String> {
|
||||
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(Context... params) {
|
||||
Log.v(TAG, "111");
|
||||
|
||||
Log.v(TAG, "222");
|
||||
long duration = ethereumManager.connect(SystemProperties.CONFIG.databaseDir() + File.separator + "poc-9-492k.dmp");
|
||||
//ConsoleFragment consoleeFrag = (ConsoleFragment)getSupportFragmentManager().findFragmentById(R.id.console);
|
||||
//consoleeFrag.updateDuration(duration);
|
||||
Log.v(TAG, "333");
|
||||
while(true) {
|
||||
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (quit == 1) {
|
||||
Log.v(TAG, "Ending background process.");
|
||||
return "All Done!";
|
||||
}
|
||||
|
||||
//publishProgress(1111);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(Integer... values) {
|
||||
super.onProgressUpdate(values);
|
||||
Log.v(TAG, values[0].toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String result) {
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The definition of our task class
|
||||
private class JsonRpcTask extends AsyncTask<Context, Integer, String> {
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(Context... params) {
|
||||
Log.v(TAG, "444");
|
||||
try {
|
||||
ethereumManager.startJsonRpc();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
Log.v(TAG, "555");
|
||||
return "done";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(Integer... values) {
|
||||
super.onProgressUpdate(values);
|
||||
Log.v(TAG, values[0].toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String result) {
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,186 @@
|
|||
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;
|
||||
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, 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) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
toolbar = (Toolbar) findViewById(R.id.tool_bar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
adapter = new TabsPagerAdapter(getSupportFragmentManager());
|
||||
viewPager = (ViewPager) findViewById(R.id.pager);
|
||||
viewPager.setAdapter(adapter);;
|
||||
|
||||
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
|
||||
tabs.setDistributeEvenly(true);
|
||||
tabs.setViewPager(viewPager);
|
||||
EthereumApplication app = (EthereumApplication)getApplication();
|
||||
app.ethereum.registerHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
getMenuInflater().inflate(R.menu.menu_main, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
// Handle action bar item clicks here. The action bar will
|
||||
// automatically handle clicks on the Home/Up button, so long
|
||||
// as you specify a parent activity in AndroidManifest.xml.
|
||||
int id = item.getItemId();
|
||||
|
||||
//noinspection SimplifiableIfStatement
|
||||
if (id == R.id.action_settings) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
public void registerFragment(FragmentInterface fragment) {
|
||||
|
||||
if (!fragments.contains(fragment)) {
|
||||
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);
|
||||
|
||||
EthereumApplication app = (EthereumApplication)getApplication();
|
||||
app.log += formatter.format(date) + " -> " + message + "\n\n";
|
||||
if (app.log.length() > 10000) {
|
||||
app.log = app.log.substring(5000);
|
||||
}
|
||||
for(FragmentInterface fragment: fragments) {
|
||||
fragment.onMessage(app.log);
|
||||
}
|
||||
}
|
||||
|
||||
@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());
|
||||
app.ethereum.startJsonRpc();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectorDisconnected() {
|
||||
|
||||
}
|
||||
}
|
|
@ -10,13 +10,11 @@ public class TabsPagerAdapter extends FragmentPagerAdapter {
|
|||
|
||||
int tabsCount;
|
||||
private String[] tabTitles = { "Console", "Tests" };
|
||||
private EthereumManager ethereumManager;
|
||||
|
||||
public TabsPagerAdapter(FragmentManager fragmentManager, EthereumManager ethereumManager) {
|
||||
public TabsPagerAdapter(FragmentManager fragmentManager) {
|
||||
|
||||
super(fragmentManager);
|
||||
this.tabsCount = tabTitles.length;
|
||||
this.ethereumManager = ethereumManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -25,7 +23,6 @@ public class TabsPagerAdapter extends FragmentPagerAdapter {
|
|||
switch (index) {
|
||||
case 0:
|
||||
ConsoleFragment consoleFragment = new ConsoleFragment();
|
||||
consoleFragment.setEthereumManager(ethereumManager);
|
||||
return consoleFragment;
|
||||
case 1:
|
||||
TestsFragment testsFragment = new TestsFragment();
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
|
||||
public class TestActivity extends ActionBarActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_test);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
getMenuInflater().inflate(R.menu.menu_test, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
// Handle action bar item clicks here. The action bar will
|
||||
// automatically handle clicks on the Home/Up button, so long
|
||||
// as you specify a parent activity in AndroidManifest.xml.
|
||||
int id = item.getItemId();
|
||||
|
||||
//noinspection SimplifiableIfStatement
|
||||
if (id == R.id.action_settings) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
|
@ -1,22 +1,147 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Message;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
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;
|
||||
|
||||
public class TestsFragment extends Fragment {
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.EnumSet;
|
||||
import java.util.UUID;
|
||||
|
||||
EthereumManager ethereumManager;
|
||||
import static org.ethereum.config.SystemProperties.CONFIG;
|
||||
|
||||
public class TestsFragment extends Fragment implements ConnectorHandler {
|
||||
|
||||
TextView connectionStatus;
|
||||
TextView blockchainStatus;
|
||||
TextView startupTime;
|
||||
TextView isConsensus;
|
||||
TextView blockExecTime;
|
||||
|
||||
Button connectButton;
|
||||
Button getEthereumStatus;
|
||||
Button getBlockchainStatus;
|
||||
|
||||
String identifier = UUID.randomUUID().toString();
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
|
||||
View view = inflater.inflate(R.layout.fragment_tests, container, false);
|
||||
|
||||
connectionStatus = (TextView)view.findViewById(R.id.connectionStatus);
|
||||
blockchainStatus = (TextView)view.findViewById(R.id.blockchainStatus);
|
||||
startupTime = (TextView)view.findViewById(R.id.startupTime);
|
||||
isConsensus = (TextView)view.findViewById(R.id.isConsensus);
|
||||
blockExecTime = (TextView)view.findViewById(R.id.blockExecTime);
|
||||
connectButton = (Button)view.findViewById(R.id.connectButton);
|
||||
getEthereumStatus = (Button)view.findViewById(R.id.getEthereumStatus);
|
||||
getBlockchainStatus = (Button)view.findViewById(R.id.getBlockchainStatus);
|
||||
|
||||
connectButton.setOnClickListener(onClickListener);
|
||||
getEthereumStatus.setOnClickListener(onClickListener);
|
||||
getBlockchainStatus.setOnClickListener(onClickListener);
|
||||
|
||||
EthereumApplication app = (EthereumApplication)getActivity().getApplication();
|
||||
app.ethereum.registerHandler(this);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private View.OnClickListener onClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
|
||||
EthereumApplication app = (EthereumApplication)getActivity().getApplication();
|
||||
switch(v.getId()){
|
||||
case R.id.connectButton:
|
||||
app.ethereum.connect(CONFIG.activePeerIP(), CONFIG.activePeerPort(), CONFIG.activePeerNodeid());
|
||||
break;
|
||||
case R.id.getEthereumStatus:
|
||||
app.ethereum.getConnectionStatus(identifier);
|
||||
app.ethereum.getAdminInfo(identifier);
|
||||
break;
|
||||
case R.id.getBlockchainStatus:
|
||||
app.ethereum.getBlockchainStatus(identifier);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
protected void updateTextView(final TextView view, final String text) {
|
||||
|
||||
view.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
view.setText(text);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleMessage(final Message message) {
|
||||
|
||||
boolean isClaimed = true;
|
||||
switch(message.what) {
|
||||
case EthereumClientMessage.MSG_CONNECTION_STATUS:
|
||||
updateTextView(connectionStatus, message.getData().getString("status"));
|
||||
break;
|
||||
case EthereumClientMessage.MSG_BLOCKCHAIN_STATUS:
|
||||
updateTextView(blockchainStatus, message.getData().getString("status"));
|
||||
break;
|
||||
case EthereumClientMessage.MSG_ADMIN_INFO:
|
||||
Bundle data = message.getData();
|
||||
data.setClassLoader(AdminInfo.class.getClassLoader());
|
||||
AdminInfo adminInfo = data.getParcelable("adminInfo");
|
||||
updateTextView(startupTime, new SimpleDateFormat("yyyy MM dd HH:mm:ss").format(new Date(adminInfo.getStartupTimeStamp())));
|
||||
updateTextView(isConsensus, adminInfo.isConsensus() ? "true" : "false");
|
||||
updateTextView(blockExecTime, adminInfo.getExecAvg().toString());
|
||||
break;
|
||||
case EthereumClientMessage.MSG_ONLINE_PEER:
|
||||
break;
|
||||
case EthereumClientMessage.MSG_PEERS:
|
||||
break;
|
||||
case EthereumClientMessage.MSG_PENDING_TRANSACTIONS:
|
||||
break;
|
||||
case EthereumClientMessage.MSG_SUBMIT_TRANSACTION_RESULT:
|
||||
break;
|
||||
default:
|
||||
isClaimed = false;
|
||||
}
|
||||
return isClaimed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
|
||||
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() {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
tools:context="org.ethereum.android_app.RemoteMainActivity">
|
||||
|
||||
<TextView android:text="@string/hello_world" android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</RelativeLayout>
|
|
@ -0,0 +1,12 @@
|
|||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
tools:context="org.ethereum.android_app.TestActivity">
|
||||
|
||||
<TextView android:text="@string/hello_world" android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</RelativeLayout>
|
|
@ -4,11 +4,14 @@
|
|||
android:orientation="vertical">
|
||||
<TextView android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="top"
|
||||
android:text="@string/console_output"
|
||||
android:textSize="14sp"
|
||||
android:layout_centerInParent="true"
|
||||
android:id="@+id/console"/>
|
||||
android:id="@+id/console"
|
||||
android:gravity="bottom"
|
||||
android:scrollbars="vertical"
|
||||
android:scrollbarStyle="insideOverlay"
|
||||
android:scrollbarSize="25dip"
|
||||
android:scrollbarFadeDuration="0"/>
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
|
|
|
@ -7,5 +7,162 @@
|
|||
android:gravity="center"
|
||||
android:text="@string/ethereumj_tests"
|
||||
android:textSize="20sp"
|
||||
android:layout_centerInParent="true"/>
|
||||
android:id="@+id/textView2"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/textView2"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:weightSum="1">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Connect"
|
||||
android:id="@+id/connectButton"
|
||||
android:layout_below="@+id/textView2"
|
||||
android:layout_alignLeft="@+id/getBlockchainStatus"
|
||||
android:layout_alignStart="@+id/getBlockchainStatus"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:textSize="10sp" />
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Ethereum Status"
|
||||
android:id="@+id/getEthereumStatus"
|
||||
android:layout_alignTop="@+id/connectButton"
|
||||
android:layout_toRightOf="@+id/textView"
|
||||
android:layout_toEndOf="@+id/textView"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:singleLine="true"
|
||||
android:textSize="10sp" />
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Blockchain Status"
|
||||
android:id="@+id/getBlockchainStatus"
|
||||
android:layout_marginBottom="42dp"
|
||||
android:layout_above="@+id/textView"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:textSize="10sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:text="Ethereum Status: "
|
||||
android:id="@+id/textView" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:text="Not Connected"
|
||||
android:id="@+id/connectionStatus" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:text="Blockchain Status: "
|
||||
android:id="@+id/textView4" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:text="None"
|
||||
android:id="@+id/blockchainStatus" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:text="Startup Time:"
|
||||
android:id="@+id/textView6" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:text="None"
|
||||
android:id="@+id/startupTime" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:text="Is Consensus:"
|
||||
android:id="@+id/textView3" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:text="None"
|
||||
android:id="@+id/isConsensus" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:text="Average block exec time:"
|
||||
android:id="@+id/textView7" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:text="None"
|
||||
android:id="@+id/blockExecTime" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context="org.ethereum.android_app.RemoteMainActivity">
|
||||
<item android:id="@+id/action_settings" android:title="@string/action_settings"
|
||||
android:orderInCategory="100" app:showAsAction="never" />
|
||||
</menu>
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context="org.ethereum.android_app.TestActivity">
|
||||
<item android:id="@+id/action_settings" android:title="@string/action_settings"
|
||||
android:orderInCategory="100" app:showAsAction="never" />
|
||||
</menu>
|
|
@ -1,3 +1,6 @@
|
|||
<resources>
|
||||
<dimen name="toolbar_elevation">4dp</dimen>
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
</resources>
|
||||
|
|
|
@ -6,5 +6,9 @@
|
|||
<string name="console_output">Console Output:</string>
|
||||
|
||||
<string name="ethereumj_tests">EthereumJ Tests</string>
|
||||
<string name="title_activity_test">TestActivity</string>
|
||||
|
||||
<string name="hello_world">Hello world!</string>
|
||||
<string name="title_activity_remote_main">RemoteMainActivity</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -51,10 +51,11 @@ dependencies {
|
|||
exclude group: "org.apache.commons", module: "commons-pool2"
|
||||
exclude group: "org.slf4j", module: "slf4j-log4j12"
|
||||
exclude group: "log4j", module: "apache-log4j-extras"
|
||||
exclude group: "org.hibernate", module: "hibernate-core"
|
||||
exclude group: "org.hibernate", module: "hibernate-entitymanager"
|
||||
exclude group: "redis.clients", module: "jedis"
|
||||
exclude group: "org.antlr", module: "antlr4-runtime"
|
||||
exclude group: "org.fusesource.leveldbjni", module: "leveldbjni"
|
||||
exclude group: "org.fusesource.leveldbjni", module: "leveldbjni-all"
|
||||
}
|
||||
|
||||
//compile "com.google.dagger:dagger:2.1-SNAPSHOT"
|
||||
|
@ -67,4 +68,5 @@ dependencies {
|
|||
compile "javax.persistence:persistence-api:1.0.2"
|
||||
|
||||
compile group: "com.thetransactioncompany", name: "jsonrpc2-server", version: "1.11"
|
||||
compile group: "com.thetransactioncompany", name: "jsonrpc2-client", version: "1.15"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,30 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.ethereum.android">
|
||||
|
||||
<application android:allowBackup="true" android:label="@string/app_name">
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.ethereum.android" >
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:label="@string/app_name" >
|
||||
<service
|
||||
android:name=".service.EthereumAidlService"
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:process=":ethereum_process" >
|
||||
<intent-filter>
|
||||
<action android:name="org.ethereum.android.IEthereumAidl" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
<service
|
||||
android:name=".service.EthereumRemoteService"
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:process=":ethereum_process" >
|
||||
</service>
|
||||
<service
|
||||
android:name=".service.EthereumService"
|
||||
android:enabled="true"
|
||||
android:exported="true" >
|
||||
</service>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package org.ethereum.android.interop;
|
||||
|
||||
interface IAsyncCallback {
|
||||
|
||||
void handleResponse(String name);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package org.ethereum.android.interop;
|
||||
|
||||
import org.ethereum.android.interop.IListener;
|
||||
import org.ethereum.android.interop.IAsyncCallback;
|
||||
|
||||
oneway interface IEthereumService {
|
||||
|
||||
void loadBlocks(String dumpFile);
|
||||
void connect(String ip, int port, String remoteId);
|
||||
void startJsonRpcServer();
|
||||
void addListener(IListener listener);
|
||||
void removeListener(IListener listener);
|
||||
void getLog(IAsyncCallback callback);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package org.ethereum.android.interop;
|
||||
|
||||
oneway interface IListener {
|
||||
|
||||
void trace(String output);
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
<!-- Create a logcat appender -->
|
||||
<appender name="logcat" class="ch.qos.logback.classic.android.LogcatAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>ERROR</level>
|
||||
<level>INFO</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
|
@ -47,11 +47,11 @@
|
|||
<appender-ref ref="logcat" />
|
||||
</logger>
|
||||
|
||||
<logger name="net" level="ERROR">
|
||||
<logger name="net" level="DEBUG">
|
||||
<appender-ref ref="logcat" />
|
||||
</logger>
|
||||
|
||||
<logger name="db" level="ERROR">
|
||||
<logger name="db" level="DEBUG">
|
||||
<appender-ref ref="logcat" />
|
||||
</logger>
|
||||
|
||||
|
@ -87,7 +87,7 @@
|
|||
<appender-ref ref="logcat" />
|
||||
</logger>
|
||||
|
||||
<logger name="general" level="ERROR">
|
||||
<logger name="general" level="DEBUG">
|
||||
<appender-ref ref="logcat" />
|
||||
</logger>
|
||||
|
||||
|
@ -99,19 +99,19 @@
|
|||
<appender-ref ref="logcat" />
|
||||
</logger>
|
||||
|
||||
<logger name="main" level="ERROR">
|
||||
<logger name="main" level="DEBUG">
|
||||
<appender-ref ref="logcat" />
|
||||
</logger>
|
||||
|
||||
<logger name="state" level="ERROR">
|
||||
<logger name="state" level="DEBUG">
|
||||
<appender-ref ref="logcat" />
|
||||
</logger>
|
||||
|
||||
<logger name="repository" level="ERROR">
|
||||
<logger name="repository" level="DEBUG">
|
||||
<appender-ref ref="logcat" />
|
||||
</logger>
|
||||
|
||||
<logger name="blockchain" level="ERROR">
|
||||
<logger name="blockchain" level="DEBUG">
|
||||
<appender-ref ref="logcat" />
|
||||
</logger>
|
||||
|
||||
|
@ -127,7 +127,7 @@
|
|||
<appender-ref ref="logcat" />
|
||||
</logger>
|
||||
|
||||
<logger name="hsqldb.db" level="ERROR">
|
||||
<logger name="hsqldb.db" level="DEBUG">
|
||||
<appender-ref ref="logcat" />
|
||||
</logger>
|
||||
|
||||
|
@ -135,7 +135,7 @@
|
|||
<appender-ref ref="logcat" />
|
||||
</logger>
|
||||
|
||||
<root level="INFO">
|
||||
<root level="DEBUG">
|
||||
<appender-ref ref="logcat" />
|
||||
</root>
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@ package org.ethereum.android;
|
|||
|
||||
import android.content.Context;
|
||||
|
||||
import com.j256.ormlite.android.apptools.OpenHelperManager;
|
||||
|
||||
import org.ethereum.android.di.modules.EthereumModule;
|
||||
import org.ethereum.android.di.components.DaggerEthereumComponent;
|
||||
import org.ethereum.config.SystemProperties;
|
||||
|
@ -37,7 +35,8 @@ public class EthereumManager {
|
|||
.ethereumModule(new EthereumModule(context))
|
||||
.build().ethereum();
|
||||
|
||||
jsonRpcServer = new JsonRpcServer(ethereum);
|
||||
//TODO: add here switch between full and light version
|
||||
jsonRpcServer = new org.ethereum.android.jsonrpc.light.JsonRpcServer(ethereum);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
|
@ -80,7 +79,6 @@ public class EthereumManager {
|
|||
public void close() {
|
||||
|
||||
ethereum.close();
|
||||
OpenHelperManager.releaseHelper();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,15 +3,12 @@ package org.ethereum.android.datasource;
|
|||
import org.ethereum.config.SystemProperties;
|
||||
|
||||
import org.ethereum.datasource.KeyValueDataSource;
|
||||
import org.fusesource.leveldbjni.JniDBFactory;
|
||||
import org.fusesource.leveldbjni.internal.JniDB;
|
||||
import org.iq80.leveldb.CompressionType;
|
||||
import org.iq80.leveldb.DB;
|
||||
import org.iq80.leveldb.DBIterator;
|
||||
import org.iq80.leveldb.Options;
|
||||
import org.iq80.leveldb.WriteBatch;
|
||||
|
||||
import org.iq80.leveldb.impl.Iq80DBFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -22,7 +19,7 @@ import java.util.HashSet;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import android.content.Context;
|
||||
import static org.iq80.leveldb.impl.Iq80DBFactory.factory;
|
||||
|
||||
/**
|
||||
* @author Roman Mandeleil
|
||||
|
@ -34,7 +31,6 @@ public class LevelDbDataSource implements KeyValueDataSource {
|
|||
|
||||
String name;
|
||||
private DB db;
|
||||
private Context context;
|
||||
|
||||
public LevelDbDataSource() {
|
||||
}
|
||||
|
@ -43,10 +39,6 @@ public class LevelDbDataSource implements KeyValueDataSource {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
public void setContext(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
|
||||
|
@ -63,6 +55,7 @@ public class LevelDbDataSource implements KeyValueDataSource {
|
|||
logger.debug("Opening database");
|
||||
File dbLocation = new File(SystemProperties.CONFIG.databaseDir());
|
||||
File fileLocation = new File(dbLocation, name);
|
||||
if (!dbLocation.exists()) dbLocation.mkdirs();
|
||||
|
||||
if (SystemProperties.CONFIG.databaseReset()) {
|
||||
destroyDB(fileLocation);
|
||||
|
@ -70,21 +63,7 @@ public class LevelDbDataSource implements KeyValueDataSource {
|
|||
|
||||
logger.debug("Initializing new or existing database: '{}'", name);
|
||||
|
||||
try {
|
||||
db = JniDBFactory.factory.open(fileLocation, options);
|
||||
} catch (Throwable e) {
|
||||
System.out.println("No native version of LevelDB found");
|
||||
}
|
||||
|
||||
String cpu = System.getProperty("sun.arch.data.model");
|
||||
String os = System.getProperty("os.name");
|
||||
|
||||
if (db instanceof JniDB)
|
||||
System.out.println("Native version of LevelDB loaded for: " + os + "." + cpu + "bit");
|
||||
else{
|
||||
System.out.println("Pure Java version of LevelDB loaded");
|
||||
db = Iq80DBFactory.factory.open(fileLocation, options);
|
||||
}
|
||||
db = factory.open(fileLocation, options);
|
||||
|
||||
|
||||
} catch (IOException ioe) {
|
||||
|
@ -98,7 +77,7 @@ public class LevelDbDataSource implements KeyValueDataSource {
|
|||
logger.debug("Destroying existing database");
|
||||
Options options = new Options();
|
||||
try {
|
||||
Iq80DBFactory.factory.destroy(fileLocation, options);
|
||||
factory.destroy(fileLocation, options);
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
|
@ -110,6 +89,11 @@ public class LevelDbDataSource implements KeyValueDataSource {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] get(byte[] key) {
|
||||
return db.get(key);
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
package org.ethereum.android.datasource;
|
||||
|
||||
import org.ethereum.config.SystemProperties;
|
||||
import org.ethereum.datasource.KeyValueDataSource;
|
||||
import org.ethereum.db.ByteArrayWrapper;
|
||||
import org.mapdb.DB;
|
||||
import org.mapdb.DBMaker;
|
||||
import org.mapdb.HTreeMap;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.ethereum.util.ByteUtil.wrap;
|
||||
|
||||
public class MapDBDataSource implements KeyValueDataSource {
|
||||
|
||||
private static final int BATCH_SIZE = 1024 * 1000 * 10;
|
||||
|
||||
private DB db;
|
||||
private HTreeMap<ByteArrayWrapper, byte[]> map;
|
||||
private String name;
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
File dbLocation = new File(SystemProperties.CONFIG.databaseDir() + "/");
|
||||
if (!dbLocation.exists()) {
|
||||
dbLocation.mkdirs();
|
||||
}
|
||||
|
||||
db = DBMaker.newFileDB(new File(dbLocation, name))
|
||||
.asyncWriteEnable()
|
||||
.mmapFileEnableIfSupported()
|
||||
// .compressionEnable()
|
||||
.cacheDisable()
|
||||
// .asyncWriteFlushDelay(1000)
|
||||
.closeOnJvmShutdown()
|
||||
.make();
|
||||
|
||||
this.map = db.createHashMap(name).makeOrGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] get(byte[] key) {
|
||||
return map.get(wrap(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] put(byte[] key, byte[] value) {
|
||||
try {
|
||||
return map.put(wrap(key), value);
|
||||
} finally {
|
||||
db.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(byte[] key) {
|
||||
try {
|
||||
map.remove(key);
|
||||
} finally {
|
||||
db.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<byte[]> keys() {
|
||||
HashSet<byte[]> result = new HashSet<>();
|
||||
for (ByteArrayWrapper key : map.keySet()) {
|
||||
result.add(key.getData());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBatch(Map<byte[], byte[]> rows) {
|
||||
int savedSize = 0;
|
||||
try {
|
||||
for (byte[] key : rows.keySet()) {
|
||||
byte[] value = rows.get(key);
|
||||
savedSize += value.length;
|
||||
|
||||
map.put(wrap(key), value);
|
||||
if (savedSize > BATCH_SIZE) {
|
||||
db.commit();
|
||||
savedSize = 0;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
db.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
db.close();
|
||||
}
|
||||
}
|
|
@ -33,4 +33,10 @@ public interface BlockStoreDatabase {
|
|||
public TransactionReceipt getTransactionReceiptByHash(byte[] hash);
|
||||
|
||||
public boolean flush(List<Block> blocks);
|
||||
|
||||
public void save(BlockTransactionVO blockTransactionVO);
|
||||
|
||||
public BlockTransactionVO getTransactionLocation(byte[] transactionHash);
|
||||
|
||||
public void setFullStorage(boolean storeAllBlocks);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.ethereum.core.Block;
|
|||
import org.ethereum.core.TransactionReceipt;
|
||||
import org.ethereum.db.BlockStore;
|
||||
import org.ethereum.util.ByteUtil;
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
|
@ -65,16 +66,22 @@ public class BlockStoreImpl implements BlockStore {
|
|||
|
||||
public void saveBlock(Block block, List<TransactionReceipt> receipts) {
|
||||
|
||||
BlockVO blockVO = new BlockVO(block.getNumber(), block.getHash(),
|
||||
byte[] blockHash = block.getHash();
|
||||
BlockVO blockVO = new BlockVO(block.getNumber(), blockHash,
|
||||
block.getEncoded(), block.getCumulativeDifficulty());
|
||||
|
||||
int index = 0;
|
||||
for (TransactionReceipt receipt : receipts) {
|
||||
|
||||
byte[] hash = receipt.getTransaction().getHash();
|
||||
byte[] transactionHash = receipt.getTransaction().getHash();
|
||||
byte[] rlp = receipt.getEncoded();
|
||||
|
||||
TransactionReceiptVO transactionReceiptVO = new TransactionReceiptVO(hash, rlp);
|
||||
TransactionReceiptVO transactionReceiptVO = new TransactionReceiptVO(transactionHash, rlp);
|
||||
database.save(transactionReceiptVO);
|
||||
|
||||
BlockTransactionVO blockTransactionVO = new BlockTransactionVO(blockHash, transactionHash, index);
|
||||
database.save(blockTransactionVO);
|
||||
index++;
|
||||
}
|
||||
|
||||
database.save(blockVO);
|
||||
|
@ -119,4 +126,9 @@ public class BlockStoreImpl implements BlockStore {
|
|||
public void flush() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSessionFactory(SessionFactory sessionFactory) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package org.ethereum.android.db;
|
||||
|
||||
|
||||
import com.j256.ormlite.field.DataType;
|
||||
import com.j256.ormlite.field.DatabaseField;
|
||||
import com.j256.ormlite.table.DatabaseTable;
|
||||
|
||||
@DatabaseTable(tableName = "block_transaction")
|
||||
public class BlockTransactionVO {
|
||||
|
||||
@DatabaseField(index = true, persisterClass = HashPersister.class)
|
||||
byte[] blockHash;
|
||||
|
||||
@DatabaseField(index = true, persisterClass = HashPersister.class)
|
||||
byte[] transactionHash;
|
||||
|
||||
@DatabaseField(dataType = DataType.INTEGER)
|
||||
int transactionIndex;
|
||||
|
||||
public BlockTransactionVO() {
|
||||
|
||||
}
|
||||
|
||||
public BlockTransactionVO(byte[] blockHash, byte[] transactionHash, int transactionIndex) {
|
||||
|
||||
this.blockHash = blockHash;
|
||||
this.transactionHash = transactionHash;
|
||||
this.transactionIndex = transactionIndex;
|
||||
}
|
||||
|
||||
public byte[] getBlockHash() {
|
||||
return blockHash;
|
||||
}
|
||||
|
||||
public void setBlockHash(byte[] blockHash) {
|
||||
this.blockHash = blockHash;
|
||||
}
|
||||
|
||||
public byte[] getTransactionHash() {
|
||||
return transactionHash;
|
||||
}
|
||||
|
||||
public void setTransactionHash(byte[] transactionHash) {
|
||||
this.transactionHash = transactionHash;
|
||||
}
|
||||
|
||||
public int getTransactionIndex() {
|
||||
return transactionIndex;
|
||||
}
|
||||
|
||||
public void setTransactionIndex(int transactionIndex) {
|
||||
this.transactionIndex = transactionIndex;
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import org.ethereum.core.Block;
|
|||
import org.ethereum.core.TransactionReceipt;
|
||||
import org.ethereum.db.BlockStore;
|
||||
import org.ethereum.db.ByteArrayWrapper;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -27,6 +28,7 @@ public class InMemoryBlockStore implements BlockStore {
|
|||
List<Block> blocks = new ArrayList<>();
|
||||
|
||||
private BlockStoreDatabase database;
|
||||
protected boolean storeAllBlocks = false;
|
||||
|
||||
BigInteger totalDifficulty = ZERO;
|
||||
|
||||
|
@ -35,6 +37,13 @@ public class InMemoryBlockStore implements BlockStore {
|
|||
this.database = database;
|
||||
}
|
||||
|
||||
public InMemoryBlockStore(BlockStoreDatabase database, boolean storeAllBlocks) {
|
||||
|
||||
this.database = database;
|
||||
this.database.setFullStorage(storeAllBlocks);
|
||||
this.storeAllBlocks = storeAllBlocks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBlockHashByNumber(long blockNumber) {
|
||||
|
||||
|
@ -202,4 +211,8 @@ public class InMemoryBlockStore implements BlockStore {
|
|||
logger.info("Loaded db in: {} ms", ((float)(t_ - t) / 1_000_000));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSessionFactory(SessionFactory sessionFactory) {
|
||||
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ import com.j256.ormlite.table.TableUtils;
|
|||
|
||||
import org.ethereum.config.SystemProperties;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.core.TransactionReceipt;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -26,11 +27,24 @@ import java.util.concurrent.Callable;
|
|||
|
||||
public class OrmLiteBlockStoreDatabase extends OrmLiteSqliteOpenHelper implements BlockStoreDatabase {
|
||||
|
||||
private static OrmLiteBlockStoreDatabase instance;
|
||||
|
||||
private static final String DATABASE_NAME = "blockchain.db";
|
||||
private static final int DATABASE_VERSION = 1;
|
||||
|
||||
private Dao<BlockVO, Integer> blockDao = null;
|
||||
private Dao<TransactionReceiptVO, Integer> transactionDao = null;
|
||||
private Dao<BlockTransactionVO, Integer> blockTransactionDao = null;
|
||||
|
||||
protected boolean storeAllBLocks = false;
|
||||
|
||||
public static synchronized OrmLiteBlockStoreDatabase getHelper(Context context)
|
||||
{
|
||||
if (instance == null)
|
||||
instance = new OrmLiteBlockStoreDatabase(context);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public OrmLiteBlockStoreDatabase(Context context) {
|
||||
super(context, SystemProperties.CONFIG.databaseDir()
|
||||
|
@ -48,6 +62,7 @@ public class OrmLiteBlockStoreDatabase extends OrmLiteSqliteOpenHelper implement
|
|||
Log.i(OrmLiteBlockStoreDatabase.class.getName(), "onCreate");
|
||||
TableUtils.createTable(connectionSource, BlockVO.class);
|
||||
TableUtils.createTable(connectionSource, TransactionReceiptVO.class);
|
||||
TableUtils.createTable(connectionSource, BlockTransactionVO.class);
|
||||
} catch (SQLException e) {
|
||||
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Can't create database", e);
|
||||
throw new RuntimeException(e);
|
||||
|
@ -65,6 +80,7 @@ public class OrmLiteBlockStoreDatabase extends OrmLiteSqliteOpenHelper implement
|
|||
Log.i(OrmLiteBlockStoreDatabase.class.getName(), "onUpgrade");
|
||||
TableUtils.dropTable(connectionSource, BlockVO.class, true);
|
||||
TableUtils.dropTable(connectionSource, TransactionReceiptVO.class, true);
|
||||
TableUtils.dropTable(connectionSource, BlockTransactionVO.class, true);
|
||||
// after we drop the old databases, we create the new ones
|
||||
onCreate(db, connectionSource);
|
||||
} catch (SQLException e) {
|
||||
|
@ -96,6 +112,17 @@ public class OrmLiteBlockStoreDatabase extends OrmLiteSqliteOpenHelper implement
|
|||
return transactionDao;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Database Access Object (DAO) for our SimpleData class. It will create it or just give the cached
|
||||
* value.
|
||||
*/
|
||||
public Dao<BlockTransactionVO, Integer> getBlockTransactionDao() throws SQLException {
|
||||
if (blockTransactionDao == null) {
|
||||
blockTransactionDao = getDao(BlockTransactionVO.class);
|
||||
}
|
||||
return blockTransactionDao;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the database connections and clear any cached DAOs.
|
||||
*/
|
||||
|
@ -243,6 +270,15 @@ public class OrmLiteBlockStoreDatabase extends OrmLiteSqliteOpenHelper implement
|
|||
}
|
||||
}
|
||||
|
||||
public void save(BlockTransactionVO blockTransactionV0) {
|
||||
|
||||
try {
|
||||
getBlockTransactionDao().create(blockTransactionV0);
|
||||
} catch(java.sql.SQLException e) {
|
||||
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error saving blockTransaction", e);
|
||||
}
|
||||
}
|
||||
|
||||
public TransactionReceipt getTransactionReceiptByHash(byte[] hash) {
|
||||
|
||||
List<TransactionReceiptVO> list = new ArrayList<TransactionReceiptVO>();
|
||||
|
@ -259,19 +295,57 @@ public class OrmLiteBlockStoreDatabase extends OrmLiteSqliteOpenHelper implement
|
|||
|
||||
}
|
||||
|
||||
public BlockTransactionVO getTransactionLocation(byte[] transactionHash) {
|
||||
|
||||
List<BlockTransactionVO> list = new ArrayList<>();
|
||||
try {
|
||||
list = getBlockTransactionDao().queryForEq("transactionHash", transactionHash);
|
||||
} catch(java.sql.SQLException e) {
|
||||
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error querying for transaction hash", e);
|
||||
}
|
||||
|
||||
if (list.size() == 0) return null;
|
||||
BlockTransactionVO blockTransactionVO = list.get(0);
|
||||
|
||||
return blockTransactionVO;
|
||||
}
|
||||
|
||||
public boolean flush(final List<Block> blocks) {
|
||||
|
||||
if (!storeAllBLocks) {
|
||||
reset();
|
||||
}
|
||||
try {
|
||||
TransactionManager.callInTransaction(getBlockDao().getConnectionSource(),
|
||||
new Callable<Void>() {
|
||||
public Void call() throws Exception {
|
||||
int lastIndex = blocks.size() - 1;
|
||||
for (int i = 0; i < 1000; ++i){
|
||||
|
||||
if (storeAllBLocks) {
|
||||
for (Block block: blocks) {
|
||||
byte[] blockHash = block.getHash();
|
||||
BlockVO blockVO = new BlockVO(block.getNumber(), blockHash, block.getEncoded(), block.getCumulativeDifficulty());
|
||||
save(blockVO);
|
||||
|
||||
List<Transaction> transactions = block.getTransactionsList();
|
||||
|
||||
int index = 0;
|
||||
for (Transaction transaction: transactions) {
|
||||
BlockTransactionVO transactionVO = new BlockTransactionVO(blockHash, transaction.getHash(), index);
|
||||
save(transactionVO);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int size = blocks.size();
|
||||
int lastIndex = size - 1;
|
||||
for (int i = 0;
|
||||
i < (size > 1000 ? 1000 : size);
|
||||
++i){
|
||||
Block block = blocks.get(lastIndex - i);
|
||||
BlockVO blockVO = new BlockVO(block.getNumber(), block.getHash(), block.getEncoded(), block.getCumulativeDifficulty());
|
||||
save(blockVO);
|
||||
}
|
||||
}
|
||||
// you could pass back an object here
|
||||
return null;
|
||||
}
|
||||
|
@ -280,8 +354,13 @@ public class OrmLiteBlockStoreDatabase extends OrmLiteSqliteOpenHelper implement
|
|||
|
||||
return true;
|
||||
} catch(java.sql.SQLException e) {
|
||||
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error querying for hash", e);
|
||||
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error flushing blocks", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setFullStorage(boolean storeAllBlocks) {
|
||||
|
||||
this.storeAllBLocks = storeAllBlocks;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@ package org.ethereum.android.di.modules;
|
|||
|
||||
import android.content.Context;
|
||||
|
||||
import com.j256.ormlite.android.apptools.OpenHelperManager;
|
||||
|
||||
import org.ethereum.android.datasource.LevelDbDataSource;
|
||||
import org.ethereum.android.db.InMemoryBlockStore;
|
||||
import org.ethereum.android.db.OrmLiteBlockStoreDatabase;
|
||||
|
@ -46,8 +44,18 @@ public class EthereumModule {
|
|||
|
||||
private Context context;
|
||||
|
||||
boolean storeAllBlocks;
|
||||
|
||||
public EthereumModule(Context context) {
|
||||
|
||||
this.context = context;
|
||||
this.storeAllBlocks = false;
|
||||
}
|
||||
|
||||
public EthereumModule(Context context,boolean storeAllBlocks) {
|
||||
|
||||
this.context = context;
|
||||
this.storeAllBlocks = storeAllBlocks;
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
@ -75,17 +83,15 @@ public class EthereumModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
BlockStore provideBlockStore() {
|
||||
OrmLiteBlockStoreDatabase database = OpenHelperManager.getHelper(context, OrmLiteBlockStoreDatabase.class);
|
||||
return new InMemoryBlockStore(database);
|
||||
OrmLiteBlockStoreDatabase database = OrmLiteBlockStoreDatabase.getHelper(context);
|
||||
return new InMemoryBlockStore(database, storeAllBlocks);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Repository provideRepository() {
|
||||
LevelDbDataSource detailsDS = new LevelDbDataSource();
|
||||
detailsDS.setContext(context);
|
||||
LevelDbDataSource stateDS = new LevelDbDataSource();
|
||||
stateDS.setContext(context);
|
||||
return new RepositoryImpl(detailsDS, stateDS);
|
||||
}
|
||||
|
||||
|
@ -131,8 +137,8 @@ public class EthereumModule {
|
|||
}
|
||||
|
||||
@Provides
|
||||
ShhHandler provideShhHandler(EthereumListener listener) {
|
||||
return new ShhHandler(listener);
|
||||
ShhHandler provideShhHandler(WorldManager worldManager) {
|
||||
return new ShhHandler(worldManager);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
package org.ethereum.android.interop;
|
||||
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AdminInfo extends org.ethereum.manager.AdminInfo implements Parcelable {
|
||||
|
||||
public AdminInfo(org.ethereum.manager.AdminInfo adminInfo) {
|
||||
|
||||
startupTimeStamp = adminInfo.getStartupTimeStamp();
|
||||
consensus = adminInfo.isConsensus();
|
||||
blockExecTime = adminInfo.getBlockExecTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int i) {
|
||||
|
||||
parcel.writeLong(getStartupTimeStamp());
|
||||
parcel.writeByte((byte) (isConsensus() ? 1 : 0));
|
||||
parcel.writeLongArray(listToArray(getBlockExecTime()));
|
||||
}
|
||||
|
||||
private long[] listToArray(List<Long> list) {
|
||||
|
||||
int length = list.size();
|
||||
int arrayLength = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (list.get(i) != null) {
|
||||
arrayLength++;
|
||||
}
|
||||
}
|
||||
long[] array = new long[arrayLength];
|
||||
int arrayIndex = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
Long item = list.get(i);
|
||||
if (item != null) {
|
||||
array[arrayIndex] = item;
|
||||
arrayIndex++;
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private List<Long> arrayToList(long[] array) {
|
||||
|
||||
ArrayList<Long> list = new ArrayList<>(array.length);
|
||||
for (long item : array) {
|
||||
list.add(item);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<AdminInfo> CREATOR = new Parcelable.Creator<AdminInfo>() {
|
||||
|
||||
public AdminInfo createFromParcel(Parcel in) {
|
||||
|
||||
return new AdminInfo(in);
|
||||
}
|
||||
|
||||
public AdminInfo[] newArray(int size) {
|
||||
|
||||
return new AdminInfo[size];
|
||||
}
|
||||
};
|
||||
|
||||
private AdminInfo(Parcel in) {
|
||||
|
||||
startupTimeStamp = in.readLong();
|
||||
consensus = in.readByte() == 1 ? true : false;
|
||||
blockExecTime = arrayToList(in.createLongArray());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package org.ethereum.android.interop;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
public class Block extends org.ethereum.core.Block implements Parcelable {
|
||||
|
||||
public Block(byte[] rawData) {
|
||||
|
||||
super(rawData);
|
||||
}
|
||||
|
||||
public Block(org.ethereum.core.Block block) {
|
||||
|
||||
super(block.getEncoded());
|
||||
}
|
||||
|
||||
public Block(Parcel in) {
|
||||
|
||||
super(null);
|
||||
rlpEncoded = new byte[in.readInt()];
|
||||
in.readByteArray(rlpEncoded);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int i) {
|
||||
|
||||
byte[] data = getEncoded();
|
||||
parcel.writeInt(data.length);
|
||||
parcel.writeByteArray(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
|
||||
|
||||
public Block createFromParcel(Parcel in) {
|
||||
|
||||
return new Block(in);
|
||||
}
|
||||
|
||||
public Block[] newArray(int size) {
|
||||
|
||||
return new Block[size];
|
||||
}
|
||||
|
||||
};
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package org.ethereum.android.interop;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
public class PeerInfo extends org.ethereum.net.peerdiscovery.PeerInfo implements Parcelable {
|
||||
|
||||
public PeerInfo(InetAddress ip, int port, String peerId) {
|
||||
|
||||
super(ip, port, peerId);
|
||||
}
|
||||
|
||||
public PeerInfo(org.ethereum.net.peerdiscovery.PeerInfo peerInfo) {
|
||||
|
||||
super(peerInfo.getAddress(), peerInfo.getPort(), peerInfo.getPeerId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int i) {
|
||||
|
||||
parcel.writeByteArray(address.getAddress());
|
||||
parcel.writeInt(port);
|
||||
parcel.writeString(peerId);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<PeerInfo> CREATOR = new Parcelable.Creator<PeerInfo>() {
|
||||
|
||||
public PeerInfo createFromParcel(Parcel in) {
|
||||
|
||||
return new PeerInfo(in);
|
||||
}
|
||||
|
||||
public PeerInfo[] newArray(int size) {
|
||||
|
||||
return new PeerInfo[size];
|
||||
}
|
||||
};
|
||||
|
||||
private PeerInfo(Parcel in) {
|
||||
|
||||
super(null, 0, "");
|
||||
InetAddress ip = null;
|
||||
try {
|
||||
address = InetAddress.getByAddress(in.createByteArray());
|
||||
} catch (UnknownHostException e) {
|
||||
|
||||
}
|
||||
port = in.readInt();
|
||||
peerId = in.readString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package org.ethereum.android.interop;
|
||||
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
public class Transaction extends org.ethereum.core.Transaction implements Parcelable{
|
||||
|
||||
|
||||
public Transaction(org.ethereum.core.Transaction transaction) {
|
||||
|
||||
super(transaction.getEncoded());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int i) {
|
||||
|
||||
parcel.writeByteArray(getEncoded());
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<Transaction> CREATOR = new Parcelable.Creator<Transaction>() {
|
||||
|
||||
public Transaction createFromParcel(Parcel in) {
|
||||
|
||||
return new Transaction(in);
|
||||
}
|
||||
|
||||
public Transaction[] newArray(int size) {
|
||||
|
||||
return new Transaction[size];
|
||||
}
|
||||
};
|
||||
|
||||
private Transaction(Parcel in) {
|
||||
|
||||
super(in.createByteArray());
|
||||
}
|
||||
}
|
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,224 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc;
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.handler.codec.http.HttpServerCodec;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.handler.codec.http.multipart.HttpPostStandardRequestDecoder;
|
||||
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
|
||||
import io.netty.handler.codec.http.HttpObject;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.HttpContent;
|
||||
import io.netty.handler.codec.http.LastHttpContent;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.util.CharsetUtil;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import io.netty.handler.codec.http.HttpHeaders;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.*;
|
||||
|
||||
import org.ethereum.android.jsonrpc.method.*;
|
||||
|
||||
|
||||
public final class JsonRpcServer {
|
||||
|
||||
static final int PORT = 8545;
|
||||
|
||||
private Ethereum ethereum;
|
||||
private Dispatcher dispatcher;
|
||||
|
||||
public JsonRpcServer(Ethereum ethereum) {
|
||||
this.ethereum = ethereum;
|
||||
|
||||
this.dispatcher = new Dispatcher();
|
||||
|
||||
this.dispatcher.register(new web3_clientVersion(this.ethereum));
|
||||
this.dispatcher.register(new web3_sha3(this.ethereum));
|
||||
|
||||
this.dispatcher.register(new net_version(this.ethereum));
|
||||
this.dispatcher.register(new net_listening(this.ethereum));
|
||||
this.dispatcher.register(new net_peerCount(this.ethereum));
|
||||
|
||||
this.dispatcher.register(new eth_protocolVersion(this.ethereum));
|
||||
this.dispatcher.register(new eth_coinbase(this.ethereum));
|
||||
this.dispatcher.register(new eth_mining(this.ethereum));
|
||||
this.dispatcher.register(new eth_hashrate(this.ethereum));
|
||||
this.dispatcher.register(new eth_gasPrice(this.ethereum));
|
||||
this.dispatcher.register(new eth_accounts(this.ethereum));
|
||||
this.dispatcher.register(new eth_blockNumber(this.ethereum));
|
||||
this.dispatcher.register(new eth_getBalance(this.ethereum));
|
||||
this.dispatcher.register(new eth_getStorageAt(this.ethereum));
|
||||
this.dispatcher.register(new eth_getTransactionCount(this.ethereum));
|
||||
this.dispatcher.register(new eth_getBlockTransactionCountByHash(this.ethereum));
|
||||
this.dispatcher.register(new eth_getBlockTransactionCountByNumber(this.ethereum));
|
||||
this.dispatcher.register(new eth_getUncleCountByBlockHash(this.ethereum));
|
||||
this.dispatcher.register(new eth_getUncleCountByBlockNumber(this.ethereum));
|
||||
this.dispatcher.register(new eth_getCode(this.ethereum));
|
||||
this.dispatcher.register(new eth_sign(this.ethereum));
|
||||
this.dispatcher.register(new eth_sendTransaction(this.ethereum));
|
||||
this.dispatcher.register(new eth_call(this.ethereum));
|
||||
this.dispatcher.register(new eth_estimateGas(this.ethereum));
|
||||
this.dispatcher.register(new eth_getBlockByHash(this.ethereum));
|
||||
this.dispatcher.register(new eth_getBlockByNumber(this.ethereum));
|
||||
this.dispatcher.register(new eth_getTransactionByHash(this.ethereum));
|
||||
this.dispatcher.register(new eth_getTransactionByBlockHashAndIndex(this.ethereum));
|
||||
this.dispatcher.register(new eth_getTransactionByBlockNumberAndIndex(this.ethereum));
|
||||
this.dispatcher.register(new eth_getUncleByBlockHashAndIndex(this.ethereum));
|
||||
this.dispatcher.register(new eth_getUncleByBlockNumberAndIndex(this.ethereum));
|
||||
this.dispatcher.register(new eth_getCompilers(this.ethereum));
|
||||
this.dispatcher.register(new eth_compileSolidity(this.ethereum));
|
||||
this.dispatcher.register(new eth_compileLLL(this.ethereum));
|
||||
this.dispatcher.register(new eth_compileSerpent(this.ethereum));
|
||||
this.dispatcher.register(new eth_newFilter(this.ethereum));
|
||||
this.dispatcher.register(new eth_newBlockFilter(this.ethereum));
|
||||
this.dispatcher.register(new eth_newPendingTransactionFilter(this.ethereum));
|
||||
this.dispatcher.register(new eth_uninstallFilter(this.ethereum));
|
||||
this.dispatcher.register(new eth_getFilterChanges(this.ethereum));
|
||||
this.dispatcher.register(new eth_getFilterLogs(this.ethereum));
|
||||
this.dispatcher.register(new eth_getLogs(this.ethereum));
|
||||
this.dispatcher.register(new eth_getWork(this.ethereum));
|
||||
this.dispatcher.register(new eth_submitWork(this.ethereum));
|
||||
|
||||
this.dispatcher.register(new db_putString(this.ethereum));
|
||||
this.dispatcher.register(new db_getString(this.ethereum));
|
||||
this.dispatcher.register(new db_putHex(this.ethereum));
|
||||
this.dispatcher.register(new db_getHex(this.ethereum));
|
||||
|
||||
this.dispatcher.register(new shh_version(this.ethereum));
|
||||
this.dispatcher.register(new shh_post(this.ethereum));
|
||||
this.dispatcher.register(new shh_newIdentity(this.ethereum));
|
||||
this.dispatcher.register(new shh_hasIdentity(this.ethereum));
|
||||
this.dispatcher.register(new shh_newGroup(this.ethereum));
|
||||
this.dispatcher.register(new shh_addToGroup(this.ethereum));
|
||||
this.dispatcher.register(new shh_newFilter(this.ethereum));
|
||||
this.dispatcher.register(new shh_uninstallFilter(this.ethereum));
|
||||
this.dispatcher.register(new shh_getFilterChanges(this.ethereum));
|
||||
this.dispatcher.register(new shh_getMessages(this.ethereum));
|
||||
|
||||
FilterManager.getInstance();
|
||||
org.ethereum.android.jsonrpc.whisper.FilterManager.getInstance();
|
||||
}
|
||||
|
||||
public void start() throws Exception {
|
||||
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
|
||||
EventLoopGroup workerGroup = new NioEventLoopGroup();
|
||||
try {
|
||||
ServerBootstrap b = new ServerBootstrap();
|
||||
b.option(ChannelOption.SO_BACKLOG, 1024);
|
||||
// b.localAddress(InetAddress.getLocalHost(), PORT);
|
||||
b.localAddress(PORT);
|
||||
b.group(bossGroup, workerGroup)
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.childHandler(new JsonRpcServerInitializer());
|
||||
|
||||
Channel ch = b.bind().sync().channel();
|
||||
|
||||
ch.closeFuture().sync();
|
||||
} finally {
|
||||
bossGroup.shutdownGracefully();
|
||||
workerGroup.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
|
||||
class JsonRpcServerInitializer extends ChannelInitializer<SocketChannel> {
|
||||
@Override
|
||||
public void initChannel(SocketChannel ch) {
|
||||
ChannelPipeline p = ch.pipeline();
|
||||
p.addLast(new HttpServerCodec());
|
||||
p.addLast(new JsonRpcServerHandler());
|
||||
}
|
||||
}
|
||||
|
||||
class JsonRpcServerHandler extends SimpleChannelInboundHandler<HttpObject> {
|
||||
|
||||
private HttpRequest request;
|
||||
private final StringBuilder responseContent = new StringBuilder();
|
||||
private HttpPostStandardRequestDecoder decoder;
|
||||
private String postData;
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
if (decoder != null) {
|
||||
decoder.destroy();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
|
||||
if (msg instanceof HttpRequest) {
|
||||
HttpRequest req = this.request = (HttpRequest) msg;
|
||||
if (!req.getUri().equals("/") || !request.getMethod().equals(HttpMethod.POST)) {
|
||||
responseContent.append("Hi, how are you?!!");
|
||||
return;
|
||||
} else {
|
||||
decoder = new HttpPostStandardRequestDecoder(new DefaultHttpDataFactory(false), req);
|
||||
postData = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (decoder != null) {
|
||||
if (msg instanceof HttpContent) {
|
||||
HttpContent chunk = (HttpContent) msg;
|
||||
decoder.offer(chunk);
|
||||
postData += chunk.content().toString(0, chunk.content().capacity(), CharsetUtil.UTF_8);
|
||||
|
||||
if (chunk instanceof LastHttpContent) {
|
||||
JSONRPC2Request req = JSONRPC2Request.parse(postData);
|
||||
JSONRPC2Response resp = dispatcher.process(req, null);
|
||||
responseContent.append(resp);
|
||||
writeResponse(ctx);
|
||||
request = null;
|
||||
decoder.destroy();
|
||||
decoder = null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
writeResponse(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeResponse(ChannelHandlerContext ctx) {
|
||||
ByteBuf buf = Unpooled.copiedBuffer(responseContent.toString(), CharsetUtil.UTF_8);
|
||||
responseContent.setLength(0);
|
||||
|
||||
boolean close = HttpHeaders.Values.CLOSE.equalsIgnoreCase(request.headers().get(CONNECTION))
|
||||
|| request.getProtocolVersion().equals(HttpVersion.HTTP_1_0)
|
||||
&& !HttpHeaders.Values.KEEP_ALIVE.equalsIgnoreCase(request.headers().get(CONNECTION));
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(
|
||||
HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf);
|
||||
response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");
|
||||
|
||||
if (!close) {
|
||||
response.headers().set(CONTENT_LENGTH, buf.readableBytes());
|
||||
}
|
||||
|
||||
ChannelFuture future = ctx.writeAndFlush(response);
|
||||
if (close) {
|
||||
future.addListener(ChannelFutureListener.CLOSE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
cause.printStackTrace();
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
public abstract class JsonRpcServer {
|
||||
public JsonRpcServer(Ethereum ethereum) {};
|
||||
public abstract void start() throws Exception;
|
||||
}
|
|
@ -0,0 +1,226 @@
|
|||
package org.ethereum.android.jsonrpc.full;
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.handler.codec.http.HttpServerCodec;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.handler.codec.http.multipart.HttpPostStandardRequestDecoder;
|
||||
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
|
||||
import io.netty.handler.codec.http.HttpObject;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.HttpContent;
|
||||
import io.netty.handler.codec.http.LastHttpContent;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.util.CharsetUtil;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import io.netty.handler.codec.http.HttpHeaders;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.*;
|
||||
import org.ethereum.android.jsonrpc.full.method.*;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
|
||||
public final class JsonRpcServer extends org.ethereum.android.jsonrpc.JsonRpcServer{
|
||||
|
||||
static final int PORT = 8545;
|
||||
|
||||
private Ethereum ethereum;
|
||||
private Dispatcher dispatcher;
|
||||
|
||||
public JsonRpcServer(Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
this.ethereum = ethereum;
|
||||
|
||||
this.dispatcher = new Dispatcher();
|
||||
|
||||
this.dispatcher.register(new web3_clientVersion(this.ethereum));
|
||||
this.dispatcher.register(new web3_sha3(this.ethereum));
|
||||
|
||||
this.dispatcher.register(new net_version(this.ethereum));
|
||||
this.dispatcher.register(new net_listening(this.ethereum));
|
||||
this.dispatcher.register(new net_peerCount(this.ethereum));
|
||||
|
||||
this.dispatcher.register(new eth_protocolVersion(this.ethereum));
|
||||
this.dispatcher.register(new eth_coinbase(this.ethereum));
|
||||
this.dispatcher.register(new eth_mining(this.ethereum));
|
||||
this.dispatcher.register(new eth_hashrate(this.ethereum));
|
||||
this.dispatcher.register(new eth_gasPrice(this.ethereum));
|
||||
this.dispatcher.register(new eth_accounts(this.ethereum));
|
||||
this.dispatcher.register(new eth_blockNumber(this.ethereum));
|
||||
this.dispatcher.register(new eth_getBalance(this.ethereum));
|
||||
this.dispatcher.register(new eth_getStorageAt(this.ethereum));
|
||||
this.dispatcher.register(new eth_getTransactionCount(this.ethereum));
|
||||
this.dispatcher.register(new eth_getBlockTransactionCountByHash(this.ethereum));
|
||||
this.dispatcher.register(new eth_getBlockTransactionCountByNumber(this.ethereum));
|
||||
this.dispatcher.register(new eth_getUncleCountByBlockHash(this.ethereum));
|
||||
this.dispatcher.register(new eth_getUncleCountByBlockNumber(this.ethereum));
|
||||
this.dispatcher.register(new eth_getCode(this.ethereum));
|
||||
this.dispatcher.register(new eth_sign(this.ethereum));
|
||||
this.dispatcher.register(new eth_sendTransaction(this.ethereum));
|
||||
this.dispatcher.register(new eth_call(this.ethereum));
|
||||
this.dispatcher.register(new eth_estimateGas(this.ethereum));
|
||||
this.dispatcher.register(new eth_getBlockByHash(this.ethereum));
|
||||
this.dispatcher.register(new eth_getBlockByNumber(this.ethereum));
|
||||
this.dispatcher.register(new eth_getTransactionByHash(this.ethereum));
|
||||
this.dispatcher.register(new eth_getTransactionByBlockHashAndIndex(this.ethereum));
|
||||
this.dispatcher.register(new eth_getTransactionByBlockNumberAndIndex(this.ethereum));
|
||||
this.dispatcher.register(new eth_getUncleByBlockHashAndIndex(this.ethereum));
|
||||
this.dispatcher.register(new eth_getUncleByBlockNumberAndIndex(this.ethereum));
|
||||
this.dispatcher.register(new eth_getCompilers(this.ethereum));
|
||||
this.dispatcher.register(new eth_compileSolidity(this.ethereum));
|
||||
this.dispatcher.register(new eth_compileLLL(this.ethereum));
|
||||
this.dispatcher.register(new eth_compileSerpent(this.ethereum));
|
||||
this.dispatcher.register(new eth_newFilter(this.ethereum));
|
||||
this.dispatcher.register(new eth_newBlockFilter(this.ethereum));
|
||||
this.dispatcher.register(new eth_newPendingTransactionFilter(this.ethereum));
|
||||
this.dispatcher.register(new eth_uninstallFilter(this.ethereum));
|
||||
this.dispatcher.register(new eth_getFilterChanges(this.ethereum));
|
||||
this.dispatcher.register(new eth_getFilterLogs(this.ethereum));
|
||||
this.dispatcher.register(new eth_getLogs(this.ethereum));
|
||||
this.dispatcher.register(new eth_getWork(this.ethereum));
|
||||
this.dispatcher.register(new eth_submitWork(this.ethereum));
|
||||
|
||||
this.dispatcher.register(new db_putString(this.ethereum));
|
||||
this.dispatcher.register(new db_getString(this.ethereum));
|
||||
this.dispatcher.register(new db_putHex(this.ethereum));
|
||||
this.dispatcher.register(new db_getHex(this.ethereum));
|
||||
|
||||
this.dispatcher.register(new shh_version(this.ethereum));
|
||||
this.dispatcher.register(new shh_post(this.ethereum));
|
||||
this.dispatcher.register(new shh_newIdentity(this.ethereum));
|
||||
this.dispatcher.register(new shh_hasIdentity(this.ethereum));
|
||||
this.dispatcher.register(new shh_newGroup(this.ethereum));
|
||||
this.dispatcher.register(new shh_addToGroup(this.ethereum));
|
||||
this.dispatcher.register(new shh_newFilter(this.ethereum));
|
||||
this.dispatcher.register(new shh_uninstallFilter(this.ethereum));
|
||||
this.dispatcher.register(new shh_getFilterChanges(this.ethereum));
|
||||
this.dispatcher.register(new shh_getMessages(this.ethereum));
|
||||
|
||||
ethereum.addListener(FilterManager.getInstance());
|
||||
org.ethereum.android.jsonrpc.full.whisper.FilterManager.getInstance();
|
||||
}
|
||||
|
||||
public void start() throws Exception {
|
||||
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
|
||||
EventLoopGroup workerGroup = new NioEventLoopGroup();
|
||||
try {
|
||||
ServerBootstrap b = new ServerBootstrap();
|
||||
b.option(ChannelOption.SO_BACKLOG, 1024);
|
||||
b.localAddress(InetAddress.getLocalHost(), PORT);
|
||||
// b.localAddress(PORT);
|
||||
b.group(bossGroup, workerGroup)
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.childHandler(new JsonRpcServerInitializer());
|
||||
|
||||
Channel ch = b.bind().sync().channel();
|
||||
|
||||
ch.closeFuture().sync();
|
||||
} finally {
|
||||
bossGroup.shutdownGracefully();
|
||||
workerGroup.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
|
||||
class JsonRpcServerInitializer extends ChannelInitializer<SocketChannel> {
|
||||
@Override
|
||||
public void initChannel(SocketChannel ch) {
|
||||
ChannelPipeline p = ch.pipeline();
|
||||
p.addLast(new HttpServerCodec());
|
||||
p.addLast(new JsonRpcServerHandler());
|
||||
}
|
||||
}
|
||||
|
||||
class JsonRpcServerHandler extends SimpleChannelInboundHandler<HttpObject> {
|
||||
|
||||
private HttpRequest request;
|
||||
private final StringBuilder responseContent = new StringBuilder();
|
||||
private HttpPostStandardRequestDecoder decoder;
|
||||
private String postData;
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
if (decoder != null) {
|
||||
decoder.destroy();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
|
||||
if (msg instanceof HttpRequest) {
|
||||
HttpRequest req = this.request = (HttpRequest) msg;
|
||||
if (!req.getUri().equals("/") || !request.getMethod().equals(HttpMethod.POST)) {
|
||||
responseContent.append("Hi, how are you?!!");
|
||||
return;
|
||||
} else {
|
||||
decoder = new HttpPostStandardRequestDecoder(new DefaultHttpDataFactory(false), req);
|
||||
postData = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (decoder != null) {
|
||||
if (msg instanceof HttpContent) {
|
||||
HttpContent chunk = (HttpContent) msg;
|
||||
decoder.offer(chunk);
|
||||
postData += chunk.content().toString(0, chunk.content().capacity(), CharsetUtil.UTF_8);
|
||||
|
||||
if (chunk instanceof LastHttpContent) {
|
||||
JSONRPC2Request req = JSONRPC2Request.parse(postData);
|
||||
JSONRPC2Response resp = dispatcher.process(req, null);
|
||||
responseContent.append(resp);
|
||||
writeResponse(ctx);
|
||||
request = null;
|
||||
decoder.destroy();
|
||||
decoder = null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
writeResponse(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeResponse(ChannelHandlerContext ctx) {
|
||||
ByteBuf buf = Unpooled.copiedBuffer(responseContent.toString(), CharsetUtil.UTF_8);
|
||||
responseContent.setLength(0);
|
||||
|
||||
boolean close = HttpHeaders.Values.CLOSE.equalsIgnoreCase(request.headers().get(CONNECTION))
|
||||
|| request.getProtocolVersion().equals(HttpVersion.HTTP_1_0)
|
||||
&& !HttpHeaders.Values.KEEP_ALIVE.equalsIgnoreCase(request.headers().get(CONNECTION));
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(
|
||||
HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf);
|
||||
response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");
|
||||
|
||||
if (!close) {
|
||||
response.headers().set(CONTENT_LENGTH, buf.readableBytes());
|
||||
}
|
||||
|
||||
ChannelFuture future = ctx.writeAndFlush(response);
|
||||
if (close) {
|
||||
future.addListener(ChannelFutureListener.CLOSE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
cause.printStackTrace();
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.ethereum.android.jsonrpc;
|
||||
package org.ethereum.android.jsonrpc.full;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
|
@ -6,7 +6,9 @@ import com.thetransactioncompany.jsonrpc2.server.*;
|
|||
import net.minidev.json.JSONArray;
|
||||
import net.minidev.json.JSONObject;
|
||||
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServer;
|
||||
import org.ethereum.android.db.BlockTransactionVO;
|
||||
import org.ethereum.android.db.OrmLiteBlockStoreDatabase;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServer;
|
||||
import org.ethereum.core.Account;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.Block;
|
||||
|
@ -89,7 +91,7 @@ public abstract class JsonRpcServerMethod implements RequestHandler {
|
|||
throw new Exception("");
|
||||
}
|
||||
|
||||
byte[] from = ((Account) ethereum.getWallet().getAccountCollection().toArray()[1]).getEcKey().getAddress();
|
||||
byte[] from = getCoinBase();
|
||||
if (obj.containsKey("from") && !((String)obj.get("from")).equals("")) {
|
||||
from = jsToAddress((String) obj.get("from"));
|
||||
}
|
||||
|
@ -204,7 +206,7 @@ public abstract class JsonRpcServerMethod implements RequestHandler {
|
|||
i = 0;
|
||||
for (Transaction transaction : block.getTransactionsList()) {
|
||||
if (detailed) {
|
||||
JSONObject tx = transactionToJS(transaction);
|
||||
JSONObject tx = transactionToJS(block, transaction);
|
||||
tx.put("transactionIndex", "0x" + Integer.toHexString(i));
|
||||
tx.put("blockHash", "0x" + Hex.toHexString(block.getHash()));
|
||||
tx.put("blockNumber", "0x" + Long.toHexString(block.getNumber()));
|
||||
|
@ -216,7 +218,6 @@ public abstract class JsonRpcServerMethod implements RequestHandler {
|
|||
}
|
||||
res.put("transactions", transactionsJA);
|
||||
|
||||
//TODO: ask if I correctly get uncle's hash (takes form -core right now)
|
||||
JSONArray unclesJA = new JSONArray();
|
||||
for (BlockHeader uncle : block.getUncleList()) {
|
||||
unclesJA.add("0x" + Hex.toHexString(HashUtil.sha3(uncle.getEncoded())));
|
||||
|
@ -226,7 +227,7 @@ public abstract class JsonRpcServerMethod implements RequestHandler {
|
|||
return res;
|
||||
}
|
||||
|
||||
protected JSONObject transactionToJS (Transaction transaction) {
|
||||
protected JSONObject transactionToJS (Block block, Transaction transaction) {
|
||||
JSONObject res = new JSONObject();
|
||||
|
||||
res.put("hash", "0x" + Hex.toHexString(transaction.getHash()));
|
||||
|
@ -245,13 +246,33 @@ public abstract class JsonRpcServerMethod implements RequestHandler {
|
|||
|
||||
res.put("input", "0x" + Hex.toHexString(transaction.getData()));
|
||||
|
||||
/*
|
||||
No way to get this data from inside of transaction.
|
||||
TODO: Ask roman to include it into transaction class.
|
||||
res.put("transactionIndex", "0x" + "");
|
||||
res.put("blockHash", "0x" + "");
|
||||
res.put("blockNumber", "0x" + "");
|
||||
*/
|
||||
if (block == null) {
|
||||
OrmLiteBlockStoreDatabase db = OrmLiteBlockStoreDatabase.getHelper(null);
|
||||
BlockTransactionVO relation = db.getTransactionLocation(transaction.getHash());
|
||||
if (relation == null) {
|
||||
res.put("transactionIndex", null);
|
||||
res.put("blockHash", null);
|
||||
res.put("blockNumber", null);
|
||||
} else {
|
||||
block = ethereum.getBlockchain().getBlockByHash(relation.getBlockHash());
|
||||
}
|
||||
}
|
||||
if (block != null) {
|
||||
long txi = 0;
|
||||
for (Transaction tx : block.getTransactionsList()) {
|
||||
if (Arrays.equals(tx.getHash(), transaction.getHash()))
|
||||
break;
|
||||
txi++;
|
||||
}
|
||||
res.put("transactionIndex", "0x" + Long.toHexString(txi));
|
||||
res.put("blockHash", "0x" + Hex.toHexString(block.getHash()));
|
||||
res.put("blockNumber", "0x" + Long.toHexString(block.getNumber()));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
protected byte[] getCoinBase() {
|
||||
return ((Account) ethereum.getWallet().getAccountCollection().toArray()[0]).getEcKey().getAddress();
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.ethereum.android.jsonrpc.filter;
|
||||
package org.ethereum.android.jsonrpc.full.filter;
|
||||
|
||||
import net.minidev.json.JSONArray;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.ethereum.android.jsonrpc.filter;
|
||||
package org.ethereum.android.jsonrpc.full.filter;
|
||||
|
||||
import net.minidev.json.JSONArray;
|
||||
import org.ethereum.core.Block;
|
|
@ -1,4 +1,4 @@
|
|||
package org.ethereum.android.jsonrpc.filter;
|
||||
package org.ethereum.android.jsonrpc.full.filter;
|
||||
|
||||
import net.minidev.json.JSONArray;
|
||||
import net.minidev.json.JSONObject;
|
||||
|
@ -13,20 +13,19 @@ import org.spongycastle.util.encoders.Hex;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
/*
|
||||
Right now LogInfo not contains information about Transaction and Transaction not have information about block.
|
||||
TODO: talk to Roman about create links between LogInfo and Transaction and between Transaction and Block.
|
||||
*/
|
||||
public class FilterLog extends FilterBase {
|
||||
|
||||
private ArrayList<LogInfo> logs = new ArrayList<LogInfo>();
|
||||
private ArrayList<FilterLogData> logs = new ArrayList<FilterLogData>();
|
||||
|
||||
long blockFrom;
|
||||
long blockTo;
|
||||
ArrayList<byte[]> addresses = new ArrayList<>();
|
||||
ArrayList<byte[]> topics = new ArrayList<>();
|
||||
|
||||
private Ethereum ethereum;
|
||||
|
||||
public FilterLog (Ethereum ethereum, JSONObject data) {
|
||||
this.ethereum = ethereum;
|
||||
blockFrom = ethereum.getBlockchain().getBestBlock().getNumber();
|
||||
if (data.containsKey("fromBlock") && !((String)data.get("fromBlock")).equals("")) {
|
||||
String fromS = (String)data.get("fromBlock");
|
||||
|
@ -74,16 +73,17 @@ public class FilterLog extends FilterBase {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: Right now Bloom from -core can be used only to check total mach of 2 same class objects. Will be nice to have possibility to check contains.
|
||||
*/
|
||||
public void processEvent(Object data) {
|
||||
if (data instanceof LogInfo) {
|
||||
if (data instanceof FilterLogData) {
|
||||
synchronized (logs) {
|
||||
LogInfo li = (LogInfo)data;
|
||||
//TODO: check if li inside blockFrom - blockTo
|
||||
FilterLogData li = (FilterLogData)data;
|
||||
if ((blockFrom >= 0 && li.block.getNumber() < blockFrom) || (blockTo >= 0 && li.block.getNumber() > blockTo))
|
||||
return;
|
||||
|
||||
if (checkLogInfo(li))
|
||||
/*
|
||||
TODO: Roman must implement Bloom contain. When it will be done - we can use just Bloom.
|
||||
*/
|
||||
if (checkLogInfo(li.li))
|
||||
logs.add(li);
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ TODO: Right now Bloom from -core can be used only to check total mach of 2 same
|
|||
updateLastRequest();
|
||||
JSONArray res = new JSONArray();
|
||||
synchronized (logs) {
|
||||
for(LogInfo item : logs) {
|
||||
for(FilterLogData item : logs) {
|
||||
res.add(logInfoToJS(item));
|
||||
}
|
||||
logs.clear();
|
||||
|
@ -104,7 +104,6 @@ TODO: Right now Bloom from -core can be used only to check total mach of 2 same
|
|||
public JSONArray toJS(Ethereum ethereum) {
|
||||
JSONArray res = new JSONArray();
|
||||
|
||||
// Process mined blocks
|
||||
if (blockFrom >= 0) {
|
||||
long i = blockFrom;
|
||||
while (true) {
|
||||
|
@ -116,7 +115,7 @@ TODO: Right now Bloom from -core can be used only to check total mach of 2 same
|
|||
if (txr != null) {
|
||||
for (LogInfo li : txr.getLogInfoList()) {
|
||||
if (checkLogInfo(li))
|
||||
res.add(logInfoToJS(li));
|
||||
res.add(logInfoToJS(new FilterLogData(block, txr, li)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,16 +123,13 @@ TODO: Right now Bloom from -core can be used only to check total mach of 2 same
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Process pending transactions. But not sure if BlockChain can return TransactionReceipt for pending transaction.
|
||||
*/
|
||||
if (blockFrom < 0 || blockTo < 0) {
|
||||
for (Transaction tx : ethereum.getPendingTransactions()) {
|
||||
TransactionReceipt txr = ethereum.getBlockchain().getTransactionReceiptByHash(tx.getHash());
|
||||
if (txr != null) {
|
||||
for (LogInfo li : txr.getLogInfoList()) {
|
||||
if (checkLogInfo(li))
|
||||
res.add(logInfoToJS(li));
|
||||
res.add(logInfoToJS(new FilterLogData(null, txr, li)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -171,29 +167,63 @@ Process pending transactions. But not sure if BlockChain can return TransactionR
|
|||
return true;
|
||||
}
|
||||
|
||||
private JSONObject logInfoToJS(LogInfo li) {
|
||||
private JSONObject logInfoToJS(FilterLogData data) {
|
||||
JSONObject res = new JSONObject();
|
||||
|
||||
/*
|
||||
TODO: check here if log's transaction / block mined or pending.
|
||||
*/
|
||||
if (data.block == null) {
|
||||
res.put("type", "pending");
|
||||
res.put("logIndex", null);
|
||||
res.put("transactionIndex", null);
|
||||
res.put("transactionHash", null);
|
||||
res.put("blockHash", null);
|
||||
res.put("blockNumber", null);
|
||||
} else {
|
||||
res.put("type", "mined");
|
||||
long txi = 0;
|
||||
long lii = 0;
|
||||
/*
|
||||
TODO: for me it's a little strange way.
|
||||
*/
|
||||
for (Transaction tx : data.block.getTransactionsList()) {
|
||||
for (LogInfo li : ethereum.getBlockchain().getTransactionReceiptByHash(tx.getHash()).getLogInfoList()) {
|
||||
if (li.getBloom().equals(data.li.getBloom()))
|
||||
break;
|
||||
lii++;
|
||||
}
|
||||
if (Arrays.equals(tx.getHash(), data.txr.getTransaction().getHash())) {
|
||||
break;
|
||||
}
|
||||
txi++;
|
||||
}
|
||||
res.put("logIndex", "0x" + Long.toHexString(lii));
|
||||
res.put("transactionIndex", "0x" + Long.toHexString(txi));
|
||||
res.put("transactionHash", "0x" + Hex.toHexString(data.txr.getTransaction().getHash()));
|
||||
res.put("blockHash", "0x" + Hex.toHexString(data.block.getHash()));
|
||||
res.put("blockNumber", "0x" + Long.toHexString(data.block.getNumber()));
|
||||
}
|
||||
|
||||
res.put("address", Hex.toHexString(li.getAddress()));
|
||||
res.put("address", "0x" + Hex.toHexString(data.li.getAddress()));
|
||||
|
||||
res.put("data", Hex.toHexString(li.getData()));
|
||||
res.put("data", "0x" + Hex.toHexString(data.li.getData()));
|
||||
|
||||
JSONArray topics = new JSONArray();
|
||||
for (DataWord topic : li.getTopics()) {
|
||||
topics.add(Hex.toHexString(topic.getData()));
|
||||
for (DataWord topic : data.li.getTopics()) {
|
||||
topics.add("0x" + Hex.toHexString(topic.getData()));
|
||||
}
|
||||
res.put("topics", topics);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public static class FilterLogData {
|
||||
public Block block;
|
||||
public TransactionReceipt txr;
|
||||
public LogInfo li;
|
||||
|
||||
public FilterLogData( Block block, TransactionReceipt txr, LogInfo li) {
|
||||
this.block = block;
|
||||
this.txr = txr;
|
||||
this.li = li;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +1,23 @@
|
|||
package org.ethereum.android.jsonrpc.filter;
|
||||
package org.ethereum.android.jsonrpc.full.filter;
|
||||
|
||||
import net.minidev.json.JSONArray;
|
||||
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.core.TransactionReceipt;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.ethereum.listener.EthereumListenerAdapter;
|
||||
import org.ethereum.vm.LogInfo;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/*
|
||||
This class must receive notification from -core about new log, Block, Transaction. Right now I not see the way todo that.
|
||||
TODO: ask advice from Roman about how to send notification to this class.
|
||||
*/
|
||||
public class FilterManager {
|
||||
public class FilterManager extends EthereumListenerAdapter {
|
||||
|
||||
protected static FilterManager instance = null;
|
||||
|
||||
|
@ -49,7 +52,25 @@ public class FilterManager {
|
|||
}, TimeUnit.MINUTES.toMillis(1));
|
||||
}
|
||||
|
||||
public void processEvent(Object data) {
|
||||
@Override
|
||||
public void onBlock(Block block, List<TransactionReceipt> receipts) {
|
||||
processEvent(block);
|
||||
for(TransactionReceipt tx : receipts) {
|
||||
for (LogInfo li : tx.getLogInfoList()) {
|
||||
processEvent(new FilterLog.FilterLogData(block, tx, li));
|
||||
}
|
||||
processEvent(tx.getTransaction());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPendingTransactionsReceived(Set<Transaction> transactions) {
|
||||
for(Transaction tx : transactions) {
|
||||
processEvent(tx);
|
||||
}
|
||||
}
|
||||
|
||||
private void processEvent(Object data) {
|
||||
synchronized (filters) {
|
||||
for (Map.Entry<Integer, FilterBase> item : filters.entrySet()) {
|
||||
item.getValue().processEvent(data);
|
|
@ -1,4 +1,4 @@
|
|||
package org.ethereum.android.jsonrpc.filter;
|
||||
package org.ethereum.android.jsonrpc.full.filter;
|
||||
|
||||
import net.minidev.json.JSONArray;
|
||||
import org.ethereum.core.Transaction;
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
/*
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
/*
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
/*
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
/*
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.ethereum.core.*;
|
||||
import org.spongycastle.util.encoders.Hex;
|
|
@ -1,14 +1,10 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
/*
|
||||
No matter how long I wait on synchronization - all time got best block number = 0
|
||||
TODO: check this after Adrian finish db implementation.
|
||||
*/
|
||||
public class eth_blockNumber extends JsonRpcServerMethod {
|
||||
|
||||
public eth_blockNumber (Ethereum ethereum) {
|
|
@ -1,9 +1,9 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.ethereum.vm.Program;
|
||||
|
@ -11,10 +11,6 @@ import org.ethereum.vm.VM;
|
|||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
It's magic here, not sure if -core have this possibility at all. I found this in test and studio. But not sure that getHReturn it's what specification mean.
|
||||
TODO: get advice from Roman
|
||||
*/
|
||||
public class eth_call extends JsonRpcServerMethod {
|
||||
|
||||
public eth_call (Ethereum ethereum) {
|
|
@ -0,0 +1,26 @@
|
|||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.ethereum.core.*;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
/*
|
||||
TODO: -core not handle mining so coinbase not present in it. Right now returned second address from Wallet. Must be changed in app where implemented mining
|
||||
*/
|
||||
public class eth_coinbase extends JsonRpcServerMethod {
|
||||
|
||||
public eth_coinbase (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
String tmp = "0x" + Hex.toHexString(getCoinBase());
|
||||
JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID());
|
||||
return res;
|
||||
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.spongycastle.util.encoders.Hex;
|
|
@ -0,0 +1,36 @@
|
|||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
//import org.ethereum.serpent.SerpentCompiler;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/*
|
||||
TODO: -core not have serpent compiler
|
||||
*/
|
||||
public class eth_compileSerpent extends JsonRpcServerMethod {
|
||||
|
||||
public eth_compileSerpent (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
String code = (String)params.get(0);
|
||||
|
||||
return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
@ -10,7 +10,7 @@ import java.math.BigInteger;
|
|||
import java.util.List;
|
||||
|
||||
/*
|
||||
TODO: -core not have solidity compiler
|
||||
TODO: -core not have Solidity compiler
|
||||
*/
|
||||
public class eth_compileSolidity extends JsonRpcServerMethod {
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.ethereum.vm.Program;
|
||||
|
@ -11,10 +11,6 @@ import org.ethereum.vm.VM;
|
|||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
It's magic here, not sure if -core have this possibility at all. I found this in test and studio. But not sure that getHReturn it's what specification mean.
|
||||
TODO: get advice from Roman
|
||||
*/
|
||||
public class eth_estimateGas extends JsonRpcServerMethod {
|
||||
|
||||
public eth_estimateGas (Ethereum ethereum) {
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import static org.ethereum.core.Denomination.SZABO;
|
||||
|
|
@ -1,17 +1,14 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
TODO: ask roman advice for this method.
|
||||
*/
|
||||
public class eth_getBalance extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getBalance (Ethereum ethereum) {
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
@ -10,10 +10,6 @@ import org.spongycastle.util.encoders.Hex;
|
|||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
By specification this method can receive hash of pending block but from -core it's not possible.
|
||||
TODO: get advice from Roman about pending block
|
||||
*/
|
||||
public class eth_getBlockByHash extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getBlockByHash (Ethereum ethereum) {
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
@ -10,10 +10,6 @@ import org.spongycastle.util.encoders.Hex;
|
|||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
By specification this method can receive number of pending block but from -core it's not possible.
|
||||
TODO: get advice from Roman about pending block
|
||||
*/
|
||||
public class eth_getBlockByNumber extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getBlockByNumber (Ethereum ethereum) {
|
||||
|
@ -33,8 +29,9 @@ public class eth_getBlockByNumber extends JsonRpcServerMethod {
|
|||
if (blockNumber == -1) {
|
||||
blockNumber = ethereum.getBlockchain().getBestBlock().getNumber();
|
||||
}
|
||||
// TODO: here we must load pending block but -core not "group" it.
|
||||
|
||||
if (blockNumber == -2) {
|
||||
return new JSONRPC2Response(null, req.getID());
|
||||
}
|
||||
|
||||
Block block = ethereum.getBlockchain().getBlockByNumber(blockNumber);
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.util.List;
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.List;
|
||||
|
|
@ -1,16 +1,12 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
Not sure if pending can have code. Also code by itself related to repository not very clear for me.
|
||||
TODO: ask Roman advice for this method.
|
||||
*/
|
||||
public class eth_getCode extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getCode (Ethereum ethereum) {
|
|
@ -1,14 +1,11 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/*
|
||||
As I see right now -core have only serpent compiler
|
||||
*/
|
||||
public class eth_getCompilers extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getCompilers (Ethereum ethereum) {
|
||||
|
@ -18,8 +15,9 @@ public class eth_getCompilers extends JsonRpcServerMethod {
|
|||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
ArrayList<String> tmp = new ArrayList<String>();
|
||||
tmp.add("serpent");
|
||||
//TODO: add lll and solidity when they will be implemented in -core
|
||||
/*
|
||||
TODO: add lll and solidity and serpent when we find good libs for them. They not planned to be implemented in -core.
|
||||
*/
|
||||
JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID());
|
||||
return res;
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterBase;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterLog;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterBase;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterLog;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.List;
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterBase;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterLog;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterBase;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterLog;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.List;
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterLog;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterLog;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.List;
|
||||
|
|
@ -1,18 +1,14 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServer;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServer;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.ethereum.vm.DataWord;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
As I see getStorageValue not check Pending Transactions.
|
||||
TODO: ask roman advice for this method.
|
||||
*/
|
||||
public class eth_getStorageAt extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getStorageAt(Ethereum ethereum) { super(ethereum); }
|
|
@ -1,11 +1,11 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
|
||||
import net.minidev.json.JSONObject;
|
||||
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
@ -36,7 +36,7 @@ public class eth_getTransactionByBlockHashAndIndex extends JsonRpcServerMethod {
|
|||
if (block.getTransactionsList().size() <= index)
|
||||
return new JSONRPC2Response(null, req.getID());
|
||||
|
||||
JSONObject tx = transactionToJS(block.getTransactionsList().get(index));
|
||||
JSONObject tx = transactionToJS(block, block.getTransactionsList().get(index));
|
||||
tx.put("transactionIndex", "0x" + Integer.toHexString(index));
|
||||
tx.put("blockHash", "0x" + Hex.toHexString(block.getHash()));
|
||||
tx.put("blockNumber", "0x" + Long.toHexString(block.getNumber()));
|
|
@ -1,13 +1,14 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
|
||||
import net.minidev.json.JSONObject;
|
||||
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.math.BigInteger;
|
||||
|
@ -32,22 +33,21 @@ public class eth_getTransactionByBlockNumberAndIndex extends JsonRpcServerMethod
|
|||
if (blockNumber == -1) {
|
||||
blockNumber = ethereum.getBlockchain().getBestBlock().getNumber();
|
||||
}
|
||||
// TODO: here we must load pending block but -core not "group" it.
|
||||
|
||||
Block block = null;
|
||||
JSONObject tx = null;
|
||||
if (blockNumber == -2) {
|
||||
}
|
||||
|
||||
Block block = ethereum.getBlockchain().getBlockByNumber(blockNumber);
|
||||
|
||||
if (ethereum.getPendingTransactions().size() <= index)
|
||||
return new JSONRPC2Response(null, req.getID());
|
||||
tx = transactionToJS(null, (Transaction)ethereum.getPendingTransactions().toArray()[index]);
|
||||
} else {
|
||||
block = ethereum.getBlockchain().getBlockByNumber(blockNumber);
|
||||
if (block == null)
|
||||
return new JSONRPC2Response(null, req.getID());
|
||||
|
||||
if (block.getTransactionsList().size() <= index)
|
||||
return new JSONRPC2Response(null, req.getID());
|
||||
|
||||
JSONObject tx = transactionToJS(block.getTransactionsList().get(index));
|
||||
tx.put("transactionIndex", "0x" + Integer.toHexString(index));
|
||||
tx.put("blockHash", "0x" + Hex.toHexString(block.getHash()));
|
||||
tx.put("blockNumber", "0x" + Long.toHexString(block.getNumber()));
|
||||
tx = transactionToJS(block, block.getTransactionsList().get(index));
|
||||
}
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(tx, req.getID());
|
||||
return res;
|
|
@ -1,15 +1,12 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.core.TransactionReceipt;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
TODO: get advice from Roman about get block from transaction.
|
||||
*/
|
||||
public class eth_getTransactionByHash extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getTransactionByHash (Ethereum ethereum) {
|
||||
|
@ -29,7 +26,7 @@ public class eth_getTransactionByHash extends JsonRpcServerMethod {
|
|||
if (transaction == null)
|
||||
return new JSONRPC2Response(null, req.getID());
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(transactionToJS(transaction.getTransaction()), req.getID());
|
||||
JSONRPC2Response res = new JSONRPC2Response(transactionToJS(null, transaction.getTransaction()), req.getID());
|
||||
return res;
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServer;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServer;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
@ -12,10 +12,6 @@ import java.math.BigInteger;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
Can't find correct way to get contracts' state for specified block number. Right now method return correct value only for "latest" parameter
|
||||
TODO: ask roman advice for this method.
|
||||
*/
|
||||
public class eth_getTransactionCount extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getTransactionCount(Ethereum ethereum) { super(ethereum); }
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
@ -31,7 +31,7 @@ public class eth_getUncleByBlockHashAndIndex extends JsonRpcServerMethod {
|
|||
if (block.getUncleList().size() <= index)
|
||||
return new JSONRPC2Response(null, req.getID());
|
||||
|
||||
Block uncle = ethereum.getBlockchain().getBlockByHash(HashUtil.sha3(block.getUncleList().get(index).getEncoded()));
|
||||
Block uncle = new Block(block.getUncleList().get(index), null, null);
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(blockToJS(uncle, false), req.getID());
|
||||
return res;
|
|
@ -1,13 +1,14 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class eth_getUncleByBlockNumberAndIndex extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getUncleByBlockNumberAndIndex (Ethereum ethereum) {
|
||||
|
@ -27,7 +28,7 @@ public class eth_getUncleByBlockNumberAndIndex extends JsonRpcServerMethod {
|
|||
if (blockNumber == -1) {
|
||||
blockNumber = ethereum.getBlockchain().getBestBlock().getNumber();
|
||||
}
|
||||
// TODO: here we must load pending block but -core not "group" it.
|
||||
|
||||
if (blockNumber == -2) {
|
||||
}
|
||||
|
||||
|
@ -39,7 +40,7 @@ public class eth_getUncleByBlockNumberAndIndex extends JsonRpcServerMethod {
|
|||
if (block.getUncleList().size() <= index)
|
||||
return new JSONRPC2Response(null, req.getID());
|
||||
|
||||
Block uncle = ethereum.getBlockchain().getBlockByHash(HashUtil.sha3(block.getUncleList().get(index).getEncoded()));
|
||||
Block uncle = new Block(block.getUncleList().get(index), null, null);
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(blockToJS(uncle, false), req.getID());
|
||||
return res;
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.util.List;
|
|
@ -1,15 +1,11 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
Not sure if pending transactions can have uncle.
|
||||
TODO: ask Roman about this
|
||||
*/
|
||||
public class eth_getUncleCountByBlockNumber extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getUncleCountByBlockNumber (Ethereum ethereum) {
|
|
@ -1,12 +1,12 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
/*
|
||||
TODO: right now -core not auto start mining so no way to get information about state
|
||||
TODO: must be changed in app that implement mining
|
||||
*/
|
||||
public class eth_getWork extends JsonRpcServerMethod {
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
/*
|
||||
TODO: right now -core not have "finished" mining architecture so not have hashrate
|
||||
TODO: must be changed in app that implement mining
|
||||
*/
|
||||
public class eth_hashrate extends JsonRpcServerMethod {
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
/*
|
||||
TODO: right now -core not auto start mining and also not have marker to identify if it's happening
|
||||
TODO: must be changed in app that implement mining
|
||||
*/
|
||||
public class eth_mining extends JsonRpcServerMethod {
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterBlock;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterBlock;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
public class eth_newBlockFilter extends JsonRpcServerMethod {
|
|
@ -1,11 +1,11 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterLog;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterLog;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.List;
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterBlock;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterTransaction;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterBlock;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterManager;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterTransaction;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
public class eth_newPendingTransactionFilter extends JsonRpcServerMethod {
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.ethereum.net.eth.EthHandler;
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.core.Account;
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
@ -15,9 +15,9 @@ import java.util.concurrent.TimeUnit;
|
|||
import static org.ethereum.core.Denomination.SZABO;
|
||||
import static org.ethereum.config.SystemProperties.CONFIG;
|
||||
|
||||
|
||||
/*
|
||||
Not sure if we must call submitTransaction from here but logically to do it. Also not clear how created transaction added to pending and to "from" account pending (in test - it didn't)
|
||||
TODO: get advice from Roman. By spec if created transaction (empty data param) - result must be 20 bytes hash, but I got 32 bytes for both contract and transaction create.
|
||||
TODO: get more information from Roman, he think about this right now about 20 - 32 result.
|
||||
*/
|
||||
public class eth_sendTransaction extends JsonRpcServerMethod {
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.core.Account;
|
||||
import org.ethereum.crypto.ECKey;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
@ -26,25 +26,24 @@ public class eth_sign extends JsonRpcServerMethod {
|
|||
} else {
|
||||
byte[] address = jsToAddress((String) params.get(0));
|
||||
byte[] data = jsToAddress((String) params.get(1));
|
||||
String out = null;
|
||||
byte[] sigData = null;
|
||||
|
||||
for (Account ac : ethereum.getWallet().getAccountCollection()) {
|
||||
if (Arrays.equals(ac.getAddress(), address)) {
|
||||
ECKey.ECDSASignature sig = ac.getEcKey().doSign(data);
|
||||
byte[] sigData = new byte[65];
|
||||
sigData = new byte[65];
|
||||
sigData[0] = sig.v;
|
||||
System.arraycopy(bigIntegerToBytes(sig.r, 32), 0, sigData, 1, 32);
|
||||
System.arraycopy(bigIntegerToBytes(sig.s, 32), 0, sigData, 33, 32);
|
||||
out = Hex.toHexString(sigData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (out == null) {
|
||||
if (sigData == null) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INTERNAL_ERROR, req.getID());
|
||||
}
|
||||
|
||||
String tmp = "0x" + out;
|
||||
String tmp = "0x" + Hex.toHexString(sigData);
|
||||
JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID());
|
||||
return res;
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
TODO: right now -core not auto start mining so no way to get information about state
|
||||
TODO: must be changed in app that implement mining
|
||||
*/
|
||||
public class eth_submitWork extends JsonRpcServerMethod {
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterBase;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterLog;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterBase;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterLog;
|
||||
import org.ethereum.android.jsonrpc.full.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.List;
|
||||
|
|
@ -1,13 +1,10 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
/*
|
||||
TODO: right now -core not mark fact of start listening, it do it automatically and only send Listening trace "string" message.
|
||||
*/
|
||||
public class net_listening extends JsonRpcServerMethod {
|
||||
|
||||
public net_listening (Ethereum ethereum) {
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.ethereum.net.peerdiscovery.PeerInfo;
|
||||
import java.util.Set;
|
|
@ -1,12 +1,12 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
/*
|
||||
TODO: request go version how this must be identified. Cpp version just return "".
|
||||
TODO: maybe in future AdminState will have information about this.
|
||||
*/
|
||||
public class net_version extends JsonRpcServerMethod {
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
package org.ethereum.android.jsonrpc.full.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.full.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
import java.util.List;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue