Skip to content

Commit

Permalink
WIP #1
Browse files Browse the repository at this point in the history
  • Loading branch information
Ed Gamble committed Sep 29, 2018
1 parent 5f47257 commit 6bba34d
Show file tree
Hide file tree
Showing 13 changed files with 436 additions and 126 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -38,3 +38,4 @@ xcuserdata/
.idea/

test
.git-re*
22 changes: 22 additions & 0 deletions Swift/BRCore/BREthereum.swift
Expand Up @@ -608,6 +608,13 @@ public protocol EthereumClient : class {
event: String,
rid: Int32) -> Void

func getBlocks (ewm: EthereumWalletManager,
address: String,
flags: Int32,
blockStart: UInt64,
blockStop: UInt64,
rid: Int32) -> Void

func getTokens (ewm: EthereumWalletManager,
rid: Int32) -> Void

Expand Down Expand Up @@ -940,6 +947,17 @@ public class EthereumWalletManager {
rid: rid)
}},

funcGetBlocks: { (coreClient, coreEWM, address, flags, blockStart, blockStop, rid) in
if let client = coreClient.map ({ Unmanaged<AnyEthereumClient>.fromOpaque($0).takeUnretainedValue() }),
let ewm = EthereumWalletManager.lookup(core: coreEWM) {
client.getBlocks (ewm: ewm,
address: asUTF8String (address!),
flags: flags,
blockStart: blockStart,
blockStop: blockStop,
rid: rid)
}},

funcGetTokens: { (coreClient, coreEWM, rid) in
if let client = coreClient.map ({ Unmanaged<AnyEthereumClient>.fromOpaque($0).takeUnretainedValue() }),
let ewm = EthereumWalletManager.lookup(core: coreEWM) {
Expand Down Expand Up @@ -1223,6 +1241,10 @@ class AnyEthereumClient : EthereumClient {
base.getLogs(ewm: ewm, address: address, event: event, rid: rid)
}

func getBlocks (ewm: EthereumWalletManager, address: String, flags: Int32, blockStart: UInt64, blockStop: UInt64, rid: Int32) {
base.getBlocks (ewm: ewm, address: address, flags: flags, blockStart: blockStart, blockStop: blockStop, rid: rid)
}

func getTokens (ewm: EthereumWalletManager, rid: Int32) {
base.getTokens(ewm: ewm, rid: rid)
}
Expand Down
18 changes: 18 additions & 0 deletions ethereum/BREthereum.c
Expand Up @@ -835,6 +835,24 @@ ethereumClientAnnounceLog (BREthereumEWM ewm,
// ...
// }

//
// Blocks
//
extern BREthereumStatus
ethereumClientAnnounceBlocks (BREthereumEWM ewm,
int id,
// const char *strBlockHash,
BRArrayOf(uint64_t) blockNumbers) { // BRArrayOf(const char *) strBlockNumbers ??
assert (EWM_USE_LES == ewm->type);
assert (NULL != ewm->bcs);

// into bcs...
bcsReportInterestingBlocks (ewm->bcs, blockNumbers);

return SUCCESS;
}


//
// Tokens
//
Expand Down
33 changes: 20 additions & 13 deletions ethereum/BREthereum.h
Expand Up @@ -174,7 +174,16 @@ typedef void
const char *address,
int rid);

//
typedef void
(*BREthereumClientHandlerGetBlocks) (BREthereumClientContext context,
BREthereumEWM ewm,
const char *address,
int interestFlags,
uint64_t blockNumberStart,
uint64_t blockNumberStop,
int rid);

//
// Save Sync (and other) State
//
typedef enum {
Expand Down Expand Up @@ -339,6 +348,7 @@ typedef struct {
BREthereumClientHandlerSubmitTransaction funcSubmitTransaction;
BREthereumClientHandlerGetTransactions funcGetTransactions; // announce one-by-one
BREthereumClientHandlerGetLogs funcGetLogs; // announce one-by-one
BREthereumClientHandlerGetBlocks funcGetBlocks;
BREthereumClientHandlerGetTokens funcGetTokens; // announce one-by-one
BREthereumClientHandlerGetBlockNumber funcGetBlockNumber;
BREthereumClientHandlerGetNonce funcGetNonce;
Expand Down Expand Up @@ -385,18 +395,6 @@ typedef enum {
EWM_USE_LES
} BREthereumType;

/*!
* @typedef BREthereumSyncMode
*
* @abstract When starting the EWM we can prime the synchronization with transactions and logs
* queried from the Bread endpoint or we can use a full blockchain synchronization. (After the
* first full sync, partial syncs are used).
*/
typedef enum {
SYNC_MODE_FULL_BLOCKCHAIN,
SYNC_MODE_PRIME_WITH_ENDPOINT
} BREthereumSyncMode;

/**
* Create a EWM managing the account associated with the paperKey. (The `paperKey` must
* use words from the defaul wordList (Use installSharedWordList). The `paperKey` is used for
Expand Down Expand Up @@ -945,6 +943,15 @@ ethereumClientAnnounceLog (BREthereumEWM ewm,
const char *strBlockTransactionIndex,
const char *strBlockTimestamp);

//
// Blocks
//
extern BREthereumStatus
ethereumClientAnnounceBlocks (BREthereumEWM ewm,
int id,
// const char *strBlockHash,
BRArrayOf(uint64_t) blockNumbers);

//
// Tokens
//
Expand Down
110 changes: 98 additions & 12 deletions ethereum/bcs/BREthereumBCS.c
Expand Up @@ -24,6 +24,7 @@
// THE SOFTWARE.

#include <stdlib.h>
#include <stdarg.h>
#include "BRArray.h"
#include "BRSet.h"
#include "BREthereumBCSPrivate.h"
Expand Down Expand Up @@ -74,6 +75,21 @@ bcsSyncReportProgressCallback (BREthereumBCS bcs,
uint64_t blockNumberBeg,
uint64_t blockNumberNow,
uint64_t blockNumberEnd);

static inline BREthereumSyncInterestSet
syncInterestsCreate (int count, /* BREthereumSyncInterest*/ ...) {
BREthereumSyncInterestSet interests = 0;;

va_list args;
va_start (args, count);
for (int i = 0; i < count; i++)
interests |= va_arg (args, BREthereumSyncInterest);
va_end(args);

return interests;
}


/**
*/
static void
Expand Down Expand Up @@ -165,6 +181,7 @@ extern BREthereumBCS
bcsCreate (BREthereumNetwork network,
BREthereumAddress address,
BREthereumBCSListener listener,
BREthereumSyncMode syncMode,
BRArrayOf(BREthereumNodeConfig) peers,
BRArrayOf(BREthereumBlock) blocks,
BRArrayOf(BREthereumTransaction) transactions,
Expand All @@ -176,6 +193,7 @@ bcsCreate (BREthereumNetwork network,
bcs->network = network;
bcs->address = address;
bcs->accountState = accountStateCreateEmpty ();
bcs->syncMode = syncMode;
bcs->filterForAddressOnTransactions = bloomFilterCreateAddress(bcs->address);
bcs->filterForAddressOnLogs = logTopicGetBloomFilterAddress(bcs->address);

Expand Down Expand Up @@ -255,12 +273,14 @@ bcsCreate (BREthereumNetwork network,
blockGetHash(bcs->chain),
peers);

bcs->sync = bcsSyncCreate ((BREthereumBCSSyncContext) bcs,
(BREthereumBCSSyncReportBlocks) bcsSyncReportBlocksCallback,
(BREthereumBCSSyncReportProgress) bcsSyncReportProgressCallback,
bcs->address,
bcs->les,
bcs->handler);
bcs->sync = NULL;
if (SYNC_MODE_FULL_BLOCKCHAIN == bcs->syncMode)
bcs->sync = bcsSyncCreate ((BREthereumBCSSyncContext) bcs,
(BREthereumBCSSyncReportBlocks) bcsSyncReportBlocksCallback,
(BREthereumBCSSyncReportProgress) bcsSyncReportProgressCallback,
bcs->address,
bcs->les,
bcs->handler);

return bcs;
}
Expand Down Expand Up @@ -316,15 +336,68 @@ bcsDestroy (BREthereumBCS bcs) {
free (bcs);
}

static void
bcsSyncRange (BREthereumBCS bcs,
uint64_t blockNumberStart,
uint64_t blockNumberStop) {
switch (bcs->syncMode) {
case SYNC_MODE_FULL_BLOCKCHAIN: {
//
// For a FULL_BLOCKCHAIN sync we run our 'N-Ary Search on Account Changes' algorithm
// which has a (current) weakness on 'ERC20 transfers w/ address as target'. So, we
// exploit the BRD backend, view the `getBlocksCallback()`, to get interesting blocks.
//
assert (NULL != bcs->sync);
if (ETHEREUM_BOOLEAN_IS_FALSE (bcsSyncIsActive(bcs->sync))) {
BREthereumSyncInterestSet interests = syncInterestsCreate(1, CLIENT_GET_BLOCKS_LOGS_AS_TARGET);
bcs->listener.getBlocksCallback (bcs->listener.context,
bcs->address,
interests,
blockNumberStart,
blockNumberStop);

// Run the 'N-Ary Search' algorithm.
bcsSyncStart(bcs->sync, blockNumberStart, blockNumberStop);
}
break;
}

case SYNC_MODE_PRIME_WITH_ENDPOINT: {
//
// For a PRIME_WITH_ENDPOINT sync we rely 100% on the BRD backend to provide any and
// all blocks of interest - which is any block involving `address` in a transaction
// or a log.
//
BREthereumSyncInterestSet interests = syncInterestsCreate (4,
CLIENT_GET_BLOCKS_LOGS_AS_SOURCE,
CLIENT_GET_BLOCKS_LOGS_AS_TARGET,
CLIENT_GET_BLOCKS_TRANSACTIONS_AS_SOURCE,
CLIENT_GET_BLOCKS_TRANSACTIONS_AS_TARGET);
bcs->listener.getBlocksCallback (bcs->listener.context,
bcs->address,
interests,
blockNumberStart,
blockNumberStop);
break;
}
}
}

extern void
bcsSync (BREthereumBCS bcs,
uint64_t blockNumber) {
bcsSyncStart (bcs->sync, blockGetNumber(bcs->chain), blockNumber);
bcsSyncRange (bcs, blockGetNumber(bcs->chain), blockNumber);
}

extern BREthereumBoolean
bcsSyncInProgress (BREthereumBCS bcs) {
return bcsSyncIsActive (bcs->sync);
switch (bcs->syncMode) {
case SYNC_MODE_FULL_BLOCKCHAIN:
assert (NULL != bcs->sync);
return bcsSyncIsActive (bcs->sync);
case SYNC_MODE_PRIME_WITH_ENDPOINT:
return ETHEREUM_BOOLEAN_FALSE; // Nope
}
}

extern void
Expand Down Expand Up @@ -355,6 +428,19 @@ bcsSendLogRequest (BREthereumBCS bcs,
blockNumber, 1, 0, ETHEREUM_BOOLEAN_FALSE);
}

extern void
bcsReportInterestingBlocks (BREthereumBCS bcs,
// interest
// request id
BRArrayOf(uint64_t) blockNumbers) {
eth_log ("BCS", "Report Interesting Blocks: %zu", array_count(blockNumbers));
for (size_t index = 0; index < array_count(blockNumbers); index++)
lesProvideBlockHeaders (bcs->les,
(BREthereumLESProvisionContext) bcs,
(BREthereumLESProvisionCallback) bcsSignalProvision,
blockNumbers[index], 1, 0, ETHEREUM_BOOLEAN_FALSE);
}

extern void
bcsHandleSubmitTransaction (BREthereumBCS bcs,
BREthereumTransaction transaction) {
Expand All @@ -370,7 +456,7 @@ extern void
bcsHandleStatus (BREthereumBCS bcs,
BREthereumHash headHash,
uint64_t headNumber) {
bcsSyncStart(bcs->sync, blockGetNumber(bcs->chain), headNumber);
bcsSyncRange (bcs, blockGetNumber(bcs->chain), headNumber);
}

/*!
Expand Down Expand Up @@ -818,9 +904,9 @@ bcsExtendChainIfPossible (BREthereumBCS bcs,
// sync to recover (might not actually perform a sync - just attempt).
uint64_t orphanBlockNumberMinumum = bcsGetOrphanBlockNumberMinimum(bcs);
if (UINT64_MAX != orphanBlockNumberMinumum)
bcsSyncStart(bcs->sync,
blockGetNumber(bcs->chain),
orphanBlockNumberMinumum);
bcsSyncRange (bcs,
blockGetNumber(bcs->chain),
orphanBlockNumberMinumum);

return;
}
Expand Down
23 changes: 19 additions & 4 deletions ethereum/bcs/BREthereumBCS.h
Expand Up @@ -29,9 +29,6 @@
#include "../base/BREthereumBase.h"
#include "../les/BREthereumLES.h"

#define BRSetOf(type) BRSet*
#define BRArrayOf(type) type*

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -125,6 +122,17 @@ typedef void
uint64_t blockNumberCurrent,
uint64_t blockNumberStop);

/**
* Get (Interesting) Blocks. Depending on the sync-mode we may ask the BRD endpoint for blocks
* that contain transactions or logs of interest.
*/
typedef void
(*BREthereumBCSCallbackGetBlocks) (BREthereumBCSCallbackContext context,
BREthereumAddress address,
BREthereumSyncInterestSet interests,
uint64_t blockStart,
uint64_t blockStop);

typedef struct {
BREthereumBCSCallbackContext context;
BREthereumBCSCallbackBlockchain blockChainCallback;
Expand All @@ -134,9 +142,9 @@ typedef struct {
BREthereumBCSCallbackSaveBlocks saveBlocksCallback;
BREthereumBCSCallbackSavePeers savePeersCallback;
BREthereumBCSCallbackSync syncCallback;
BREthereumBCSCallbackGetBlocks getBlocksCallback;
} BREthereumBCSListener;


/**
* Create BCS (a 'BlockChain Slice`) providing a view of the Ethereum blockchain for `network`
* focused on the `account` primary address. Initialize the synchronization with the previously
Expand All @@ -149,6 +157,7 @@ extern BREthereumBCS
bcsCreate (BREthereumNetwork network,
BREthereumAddress address,
BREthereumBCSListener listener,
BREthereumSyncMode syncMode,
BRArrayOf(BREthereumNodeConfig) peers,
BRArrayOf(BREthereumBlock) blocks,
BRArrayOf(BREthereumTransaction) transactions,
Expand Down Expand Up @@ -211,6 +220,12 @@ bcsSendLogRequest (BREthereumBCS bcs,
uint64_t blockNumber,
uint64_t blockTransactionIndex);

extern void
bcsReportInterestingBlocks (BREthereumBCS bcs,
// interest
// request id
BRArrayOf(uint64_t) blockNumbers);

#ifdef __cplusplus
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion ethereum/bcs/BREthereumBCSSync.c
Expand Up @@ -737,7 +737,7 @@ bcsSyncStart (BREthereumBCSSync sync,
SYNC_LINEAR_LIMIT));
}

// Kick of the new sync.
// Kick off the new sync.
syncRangeDispatch (sync->root);
}

Expand Down

0 comments on commit 6bba34d

Please sign in to comment.