Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support "pending" option for Web3 requests #713

Merged
merged 3 commits into from
Nov 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 55 additions & 63 deletions modApiServer/src/org/aion/api/server/rpc/ApiWeb3Aion.java
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ public class ApiWeb3Aion extends ApiAion {

private boolean isSeedMode;

private final long BEST_PENDING_BLOCK = -1L;

private final LoadingCache<Integer, ChainHeadView> CachedRecentEntities;
private final LoadingCache<String, MinerStatsView> MinerStats;

Expand Down Expand Up @@ -237,8 +239,9 @@ public ApiWeb3Aion(final IAionChain _ac) {
public ChainHeadView load(Integer key) { // no checked exception
return new ChainHeadView(OPS_RECENT_ENTITY_COUNT).update();
}

// reload() executed asynchronously using ForkJoinPool.commonPool()

// reload() executed asynchronously using
// ForkJoinPool.commonPool()
public ChainHeadView reload(
final Integer key, ChainHeadView prev) {
return new ChainHeadView(prev).update();
Expand Down Expand Up @@ -272,8 +275,9 @@ public MinerStatsView load(String key) { // no checked exception
STRATUM_RECENT_BLK_COUNT, miner.toBytes())
.update();
}

// reload() executed asynchronously using ForkJoinPool.commonPool()

// reload() executed asynchronously using
// ForkJoinPool.commonPool()
public MinerStatsView reload(
final String key, MinerStatsView prev) {
return new MinerStatsView(prev).update();
Expand Down Expand Up @@ -426,13 +430,6 @@ public RpcMsg eth_getBalance(Object _params) {
if (!JSONObject.NULL.equals(_bnOrId)) {
bnOrId = _bnOrId + "";
}
/*
if (!bnOrId.equalsIgnoreCase("latest")) {
return new RpcMsg(
null,
RpcError.INVALID_PARAMS,
"Default block parameter temporarily unsupported");
}*/

IRepository repo = getRepoByJsonBlockId(bnOrId);
if (repo == null) // invalid bnOrId
Expand All @@ -446,8 +443,6 @@ public RpcMsg eth_getBalance(Object _params) {
+ "State may have been pruned; please check your db pruning settings in the configuration file.");
}

// IRepository repo = this.ac.getRepository();

BigInteger balance = repo.getBalance(address);
return new RpcMsg(TypeConverter.toJsonHex(balance));
}
Expand Down Expand Up @@ -485,13 +480,6 @@ public RpcMsg eth_getStorageAt(Object _params) {
return new RpcMsg(
null, RpcError.INVALID_PARAMS, "Invalid storageIndex. Must be <= 16 bytes.");
}
/*
if (!bnOrId.equalsIgnoreCase("latest")) {
return new RpcMsg(
null,
RpcError.INVALID_PARAMS,
"Default block parameter temporarily unsupported");
}*/

IRepository repo = getRepoByJsonBlockId(bnOrId);
if (repo == null) // invalid bnOrId
Expand All @@ -505,8 +493,6 @@ public RpcMsg eth_getStorageAt(Object _params) {
+ "State may have been pruned; please check your db pruning settings in the configuration file.");
}

// IRepository repo = this.ac.getRepository();

@SuppressWarnings("unchecked")
IDataWord storageValue = repo.getStorageValue(address, key);
if (storageValue != null) {
Expand Down Expand Up @@ -535,17 +521,6 @@ public RpcMsg eth_getTransactionCount(Object _params) {
if (!JSONObject.NULL.equals(_bnOrId)) {
bnOrId = _bnOrId + "";
}
/*
if (!bnOrId.equalsIgnoreCase("latest")) {
return new RpcMsg(
null,
RpcError.INVALID_PARAMS,
"Default block parameter temporarily unsupported");
}*/

if (bnOrId.equalsIgnoreCase("pending")) {
return new RpcMsg(TypeConverter.toJsonHex(pendingState.bestPendingStateNonce(address)));
}
AlexandraRoatis marked this conversation as resolved.
Show resolved Hide resolved

IRepository repo = getRepoByJsonBlockId(bnOrId);
if (repo == null) // invalid bnOrId
Expand All @@ -559,8 +534,6 @@ public RpcMsg eth_getTransactionCount(Object _params) {
+ "State may have been pruned; please check your db pruning settings in the configuration file.");
}

// IRepository repo = this.ac.getRepository();

return new RpcMsg(TypeConverter.toJsonHex(repo.getNonce(address)));
}

Expand Down Expand Up @@ -600,7 +573,7 @@ public RpcMsg eth_getBlockTransactionCountByNumber(Object _params) {
}

// pending transactions
if (bn < 0) {
if (bn == BEST_PENDING_BLOCK) {
long pendingTxCount = this.ac.getAionHub().getPendingState().getPendingTxSize();
return new RpcMsg(TypeConverter.toJsonHex(pendingTxCount));
}
Expand Down Expand Up @@ -635,13 +608,6 @@ public RpcMsg eth_getCode(Object _params) {
if (!JSONObject.NULL.equals(_bnOrId)) {
bnOrId = _bnOrId + "";
}
/*
if (!bnOrId.equalsIgnoreCase("latest")) {
return new RpcMsg(
null,
RpcError.INVALID_PARAMS,
"Default block parameter temporarily unsupported");
}*/

IRepository repo = getRepoByJsonBlockId(bnOrId);
if (repo == null) // invalid bnOrId
Expand All @@ -655,8 +621,6 @@ public RpcMsg eth_getCode(Object _params) {
+ "State may have been pruned; please check your db pruning settings in the configuration file.");
}

// IRepository repo = this.ac.getRepository();

byte[] code = repo.getCode(address);
return new RpcMsg(TypeConverter.toJsonHex(code));
}
Expand Down Expand Up @@ -826,10 +790,12 @@ public RpcMsg eth_call(Object _params) {
}

Long bn = parseBnOrId(bnOrId);
if (bn == null || bn < 0) {
return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid block id provided.");
if (bn == null) {
AlexandraRoatis marked this conversation as resolved.
Show resolved Hide resolved
return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid block number.");
}

AionBlock b = getBlockByBN(bn);

AionTransaction tx =
new AionTransaction(
txParams.getNonce().toByteArray(),
Expand All @@ -839,7 +805,6 @@ public RpcMsg eth_call(Object _params) {
txParams.getNrg(),
txParams.getNrgPrice());

AionBlock b = this.ac.getBlockchain().getBlockByNumber(bn);
AionTxReceipt receipt = this.ac.callConstant(tx, b);

return new RpcMsg(TypeConverter.toJsonHex(receipt.getExecutionResult()));
Expand Down Expand Up @@ -923,11 +888,11 @@ public RpcMsg eth_getBlockByNumber(Object _params) {

Long bn = this.parseBnOrId(_bnOrId);

if (bn == null || bn < 0) {
return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid block id provided.");
if (bn == null) {
return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid block number.");
}

AionBlock nb = this.ac.getBlockchain().getBlockByNumber(bn);
AionBlock nb = getBlockByBN(bn);

if (nb == null) {
LOG.debug("<get-block bn={} err=not-found>", bn);
Expand Down Expand Up @@ -1025,11 +990,12 @@ public RpcMsg eth_getTransactionByBlockNumberAndIndex(Object _params) {
}

Long bn = parseBnOrId(_bnOrId);
if (bn == null || bn < 0) {
return null;
if (bn == null) {
return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid block number.");
}

AionBlock b = this.ac.getBlockchain().getBlockByNumber(bn);
AionBlock b = this.getBlockByBN(bn);

if (b == null) {
return new RpcMsg(
JSONObject.NULL); // json rpc spec: 'or null when no transaction was found'
Expand Down Expand Up @@ -1131,13 +1097,18 @@ private FltrLg createFilter(ArgFltr rf) {
Long bnFrom = parseBnOrId(rf.fromBlock);
Long bnTo = parseBnOrId(rf.toBlock);

if (bnFrom == null || bnTo == null || bnFrom == -1 || bnTo == -1) {
if (bnFrom == null || bnTo == null) {
AlexandraRoatis marked this conversation as resolved.
Show resolved Hide resolved
LOG.debug("jsonrpc - eth_newFilter(): from, to block parse failed");
return null;
}

final AionBlock fromBlock = this.ac.getBlockchain().getBlockByNumber(bnFrom);
AionBlock toBlock = this.ac.getBlockchain().getBlockByNumber(bnTo);
if (bnTo != BEST_PENDING_BLOCK && bnFrom > bnTo) {
LOG.debug("jsonrpc - eth_newFilter(): from block is after to block");
return null;
}

AionBlock fromBlock = this.getBlockByBN(bnFrom);
AionBlock toBlock = this.getBlockByBN(bnTo);

if (fromBlock != null) {
// need to add historical data
Expand Down Expand Up @@ -1374,7 +1345,7 @@ public RpcMsg debug_getBlocksByNumber(Object _params) {
Long bn = parseBnOrId(_bnOrId);

if (bn == null || bn < 0) {
return null;
return new RpcMsg(null, RpcError.INVALID_PARAMS, "Invalid block number.");
}

List<Map.Entry<AionBlock, Map.Entry<BigInteger, Boolean>>> blocks =
Expand Down Expand Up @@ -2859,11 +2830,13 @@ public RpcMsg stratum_getMinerStats(Object _params) {
// comment out until resolved
private IRepository getRepoByJsonBlockId(String _bnOrId) {
Long bn = parseBnOrId(_bnOrId);
// if you passed in an invalid bnOrId, pending or it's an error
if (bn == null || bn < 0) {

if (bn == null) {
return null;
}

if (bn == BEST_PENDING_BLOCK) return pendingState.getRepository();

AionBlock b = this.ac.getBlockchain().getBlockByNumber(bn);
if (b == null) {
return null;
Expand All @@ -2872,6 +2845,16 @@ private IRepository getRepoByJsonBlockId(String _bnOrId) {
return ac.getRepository().getSnapshotTo(b.getStateRoot());
}

private AionBlock getBlockByBN(long bn) {
if (bn == BEST_PENDING_BLOCK) {
return pendingState.getBestBlock();
} else {
return this.ac.getBlockchain().getBlockByNumber(bn);
}
}

// Note: If return is null, caller sometimes assumes no blockNumber was passed in

private Long parseBnOrId(String _bnOrId) {
if (_bnOrId == null) {
return null;
Expand All @@ -2883,12 +2866,21 @@ private Long parseBnOrId(String _bnOrId) {
} else if ("latest".equalsIgnoreCase(_bnOrId)) {
return getBestBlock().getNumber();
} else if ("pending".equalsIgnoreCase(_bnOrId)) {
return -1L;
return BEST_PENDING_BLOCK;
} else {

Long ret;

if (_bnOrId.startsWith("0x")) {
return TypeConverter.StringHexToBigInteger(_bnOrId).longValue();
ret = TypeConverter.StringHexToBigInteger(_bnOrId).longValue();
} else {
ret = Long.parseLong(_bnOrId);
}
if (ret < 0) {
LOG.debug("block number cannot be negative" + _bnOrId);
return null;
} else {
return Long.parseLong(_bnOrId);
return ret;
}
}
} catch (Exception e) {
Expand Down
Loading