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

Expose ed25519 key explicitly and remove admin_key in t_entities #217

Merged
merged 2 commits into from
Sep 9, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 1 addition & 3 deletions rest-api/accounts.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ const processRow = function (row) {
accRecord.balance.balance = (row.account_balance === null) ? null : Number(row.account_balance);
accRecord.expiry_timestamp = (row.exp_time_ns === null) ? null : utils.nsToSecNs(row.exp_time_ns);
accRecord.auto_renew_period = (row.auto_renew_period=== null) ? null : Number(row.auto_renew_period);
accRecord.admin_key = (row.admin_key === null) ? null : utils.encodeKey(row.admin_key);
accRecord.key = (row.key === null) ? null : utils.encodeKey(row.key);
accRecord.deleted = row.deleted;
accRecord.entity_type = row.entity_type;
Expand All @@ -53,7 +52,6 @@ const getAccountQueryPrefix = function() {
" , coalesce(ab.account_num, e.entity_num) as entity_num\n" +
" , e.exp_time_ns\n" +
" , e.auto_renew_period\n" +
" , e.admin_key\n" +
" , e.key\n" +
" , e.deleted\n" +
" , et.name as entity_type\n" +
Expand Down Expand Up @@ -100,7 +98,7 @@ const getAccounts = function (req) {
['ab.balance']);

let [pubKeyQuery, pubKeyParams] = utils.parseParams(req, 'account.publickey',
['e.key'], 'hexstring');
['e.ed25519_public_key_hex'], null, (s) => {return s.toLowerCase();});

const { limitQuery, limitParams, order, limit } =
utils.parseLimitAndOrderParams(req, 'asc');
Expand Down
2 changes: 1 addition & 1 deletion rest-api/balances.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const getBalances = function (req) {
['ab.balance']);

let [pubKeyQuery, pubKeyParams] = utils.parseParams(req, 'account.publickey',
['e.key'], 'hexstring');
['e.ed25519_public_key_hex'], null, (s) => {return s.toLowerCase();});
let joinEntities = ('' !== pubKeyQuery); // Only need to join t_entites if we're selecting on publickey.

const { limitQuery, limitParams, order, limit } =
Expand Down
19 changes: 12 additions & 7 deletions rest-api/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,12 @@ const parseEntityId = function (acc) {
* @param {String} type Type of the field such as:
* 'entityId': Could be just a number like 1234 that gets converted to 0.0.1234, or a full
* entity id in shard.realm.entityId form; or
* 'timestamp': Could be just in seconds followed by optional decimal point and millis or nanos; or
* 'hexstring': a hexstring
* 'timestamp': Could be just in seconds followed by optional decimal point and millis or nanos
* @param {Function} valueTranslate Function(str)->str to apply to the query parameter's value (ie toLowerCase)
* this happens to the value _after_ operators removed and doesn't affect the operator
* @return {Object} {queryString, queryVals} Constructed SQL query string and values.
*/
const parseComparatorSymbol = function (fields, valArr, type = null) {
const parseComparatorSymbol = function (fields, valArr, type = null, valueTranslate = null) {
let queryStr = '';
let vals = [];

Expand All @@ -84,6 +85,9 @@ const parseComparatorSymbol = function (fields, valArr, type = null) {
op = splitItem[0]
val = splitItem[1];
}
if (null !== valueTranslate) {
val = valueTranslate(val);
}

let entity = null;

Expand Down Expand Up @@ -118,9 +122,8 @@ const parseComparatorSymbol = function (fields, valArr, type = null) {
fquery += '(' + f + ' ' + opsMap[op] + ' ?) ';
vals.push(ts);
} else {
// All other types (including hexstring) are handled here
fquery += '(' + f + ' ' + opsMap[op] + ' ?) ';
vals.push((type === 'hexstring' ? '\\x' : '') + val);
vals.push(val);
}
fieldQueryStr += (fieldQueryStr === '' ? '' : ' or ') +
fquery;
Expand Down Expand Up @@ -161,9 +164,11 @@ const getIntegerParam = function (param, limit = undefined) {
* @param {Array of Strings} SQL table field names to construct the query
* @param {String} type One of 'entityId' or 'timestamp' for special interpretation as
* an entity (shard.realm.entity format), or timestamp (ssssssssss.nnnnnnnnn)
* @param {Function} valueTranslate Function(str)->str to apply to the query parameter's value (ie toLowerCase)
* this happens to the value _after_ operators removed and doesn't affect the operator
* @return {Array} [query, params] Constructed SQL query fragment and corresponding values
*/
const parseParams = function (req, queryField, fields, type = null) {
const parseParams = function (req, queryField, fields, type = null, valueTranslate = null) {
// Parse the timestamp filter parameters
let query = '';
let params = [];
Expand All @@ -176,7 +181,7 @@ const parseParams = function (req, queryField, fields, type = null) {
reqQuery = [reqQuery];
}
// Construct the SQL query fragment
let qp = parseComparatorSymbol(fields, reqQuery, type)
let qp = parseComparatorSymbol(fields, reqQuery, type, valueTranslate)
query = qp.queryStr;
params = qp.queryVals;
}
Expand Down
97 changes: 59 additions & 38 deletions src/main/java/com/hedera/recordFileLogger/Entities.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,16 @@
import java.time.Instant;
import java.util.HashMap;

import com.google.protobuf.InvalidProtocolBufferException;
import com.hedera.utilities.Utility;
import com.hederahashgraph.api.proto.java.AccountID;
import com.hederahashgraph.api.proto.java.ContractID;
import com.hederahashgraph.api.proto.java.FileID;
import lombok.extern.log4j.Log4j2;

import static java.sql.Types.VARBINARY;
import static java.sql.Types.VARCHAR;

@Log4j2
public class Entities {
private static int FK_ACCOUNT = 0;
Expand All @@ -52,12 +56,13 @@ enum F_ENTITIES {
,EXP_TIME_NANOS
,EXP_TIME_NS
,AUTO_RENEW
,ADMIN_KEY
,ED25519_PUBLIC_KEY_HEX
,KEY
,FK_PROXY_ACCOUNT_ID
}

private static Connection connect = null;
final private Utility utility = new Utility();

public Entities(Connection connect) throws SQLException {
Entities.connect = connect;
Expand All @@ -77,10 +82,9 @@ public Entities(Connection connect) throws SQLException {
resultSet.close();
}
}
}
}

private long updateEntity(int fk_entity_type, long shard, long realm, long num, long exp_time_seconds, long exp_time_nanos, long auto_renew_period, byte[] admin_key, byte[] key, long fk_proxy_account_id) throws SQLException {

private long updateEntity(int fk_entity_type, long shard, long realm, long num, long exp_time_seconds, long exp_time_nanos, long auto_renew_period, byte[] key, long fk_proxy_account_id) throws SQLException {
long entityId = 0;

if (shard + realm + num == 0 ) {
Expand All @@ -89,7 +93,7 @@ private long updateEntity(int fk_entity_type, long shard, long realm, long num,

entityId = createOrGetEntity(shard, realm, num, fk_entity_type);

if ((exp_time_nanos == 0) && (exp_time_seconds == 0) && (auto_renew_period == 0) && (fk_proxy_account_id == 0) && (admin_key == null) && (key == null)) {
if ((exp_time_nanos == 0) && (exp_time_seconds == 0) && (auto_renew_period == 0) && (fk_proxy_account_id == 0) && (key == null)) {
// nothing to update
return entityId;
}
Expand All @@ -112,13 +116,12 @@ private long updateEntity(int fk_entity_type, long shard, long realm, long num,
bDoComma = true;
}

if (admin_key != null) {
if (bDoComma) sqlUpdate += ",";
sqlUpdate += "admin_key = ?";
bDoComma = true;
}

if (key != null) {
// The key has been specified, thus update this field either to null for non-ED25519 key or the hex value.
if (bDoComma) sqlUpdate += ",";
sqlUpdate += "ed25519_public_key_hex = ?";
bDoComma = true;

if (bDoComma) sqlUpdate += ",";
sqlUpdate += "key = ?";
bDoComma = true;
Expand Down Expand Up @@ -151,13 +154,22 @@ private long updateEntity(int fk_entity_type, long shard, long realm, long num,
fieldCount += 1;
updateEntity.setLong(fieldCount, auto_renew_period);
}

if (admin_key != null) {
fieldCount += 1;
updateEntity.setBytes(fieldCount, admin_key);
}

if (key != null) {
fieldCount += 1;
String ed25519PublicKeyHex = null;
try {
ed25519PublicKeyHex = utility.protobufKeyToHexIfEd25519OrNull(key);
} catch (InvalidProtocolBufferException e) {
log.error("Invalid ED25519 key could not be translated to hex text for entity {}.{}.{}. Column will be nulled. {}",
shard, realm, num, e);
}
if (null != ed25519PublicKeyHex) {
updateEntity.setString(fieldCount, ed25519PublicKeyHex);
} else {
updateEntity.setNull(fieldCount, VARCHAR);
}

fieldCount += 1;
updateEntity.setBytes(fieldCount, key);
}
Expand Down Expand Up @@ -193,14 +205,14 @@ private long updateEntity(int fk_entity_type, long shard, long realm, long num,

}

public long updateEntity(FileID fileId, long exp_time_seconds, long exp_time_nanos, long auto_renew_period, byte[] admin_key, byte[] key, long fk_proxy_account_id) throws SQLException {
return updateEntity(FK_FILE, fileId.getShardNum(),fileId.getRealmNum(), fileId.getFileNum(), exp_time_seconds, exp_time_nanos, auto_renew_period, admin_key, key, fk_proxy_account_id);
public long updateEntity(FileID fileId, long exp_time_seconds, long exp_time_nanos, long auto_renew_period, byte[] key, long fk_proxy_account_id) throws SQLException {
return updateEntity(FK_FILE, fileId.getShardNum(),fileId.getRealmNum(), fileId.getFileNum(), exp_time_seconds, exp_time_nanos, auto_renew_period, key, fk_proxy_account_id);
}
public long updateEntity(ContractID contractId, long exp_time_seconds, long exp_time_nanos, long auto_renew_period, byte[] admin_key, byte[] key, long fk_proxy_account_id) throws SQLException {
return updateEntity(FK_CONTRACT, contractId.getShardNum(),contractId.getRealmNum(), contractId.getContractNum(), exp_time_seconds, exp_time_nanos, auto_renew_period, admin_key, key, fk_proxy_account_id);
public long updateEntity(ContractID contractId, long exp_time_seconds, long exp_time_nanos, long auto_renew_period, byte[] key, long fk_proxy_account_id) throws SQLException {
return updateEntity(FK_CONTRACT, contractId.getShardNum(),contractId.getRealmNum(), contractId.getContractNum(), exp_time_seconds, exp_time_nanos, auto_renew_period, key, fk_proxy_account_id);
}
public long updateEntity(AccountID accountId, long exp_time_seconds, long exp_time_nanos, long auto_renew_period, byte[] admin_key, byte[] key, long fk_proxy_account_id) throws SQLException {
return updateEntity(FK_ACCOUNT, accountId.getShardNum(),accountId.getRealmNum(), accountId.getAccountNum(), exp_time_seconds, exp_time_nanos, auto_renew_period, admin_key, key, fk_proxy_account_id);
public long updateEntity(AccountID accountId, long exp_time_seconds, long exp_time_nanos, long auto_renew_period, byte[] key, long fk_proxy_account_id) throws SQLException {
return updateEntity(FK_ACCOUNT, accountId.getShardNum(),accountId.getRealmNum(), accountId.getAccountNum(), exp_time_seconds, exp_time_nanos, auto_renew_period, key, fk_proxy_account_id);
}

private long deleteEntity(int fk_entity_type, long shard, long realm, long num) throws SQLException {
Expand Down Expand Up @@ -308,7 +320,9 @@ public long unDeleteEntity(AccountID accountId) throws SQLException {
return unDeleteEntity(FK_ACCOUNT, accountId.getShardNum(),accountId.getRealmNum(), accountId.getAccountNum());
}

private long createEntity(long shard, long realm, long num, long exp_time_seconds, long exp_time_nanos, long auto_renew_period, byte[] admin_key, byte[] key, long fk_proxy_account_id, int fk_entity_type) throws SQLException {
private long createEntity(long shard, long realm, long num, long exp_time_seconds, long exp_time_nanos,
long auto_renew_period, byte[] key, long fk_proxy_account_id, int fk_entity_type)
throws SQLException {

long entityId = getCachedEntityId(shard, realm, num, fk_entity_type);
if (entityId != -1) {
Expand All @@ -329,15 +343,22 @@ private long createEntity(long shard, long realm, long num, long exp_time_second
entityCreate.setLong(8, Utility.convertInstantToNanos(expiryTime));
entityCreate.setLong(9, auto_renew_period);

if (admin_key == null) {
entityCreate.setBytes(10, new byte[0]);
} else {
entityCreate.setBytes(10, admin_key);
}

if (key == null) {
entityCreate.setBytes(11, new byte[0]);
entityCreate.setNull(10, VARCHAR);
entityCreate.setNull(11, VARBINARY);
} else {
String ed25519PublicKeyHex = null;
try {
ed25519PublicKeyHex = utility.protobufKeyToHexIfEd25519OrNull(key);
} catch (InvalidProtocolBufferException e) {
log.error("Invalid ED25519 key could not be translated to hex text for entity {}.{}.{}. Column will be nulled. {}",
shard, realm, num, e);
}
if (null != ed25519PublicKeyHex) {
entityCreate.setString(10, ed25519PublicKeyHex);
} else {
entityCreate.setNull(10, VARCHAR);
}
entityCreate.setBytes(11, key);
}

Expand All @@ -352,14 +373,14 @@ private long createEntity(long shard, long realm, long num, long exp_time_second

}

public long createEntity(FileID fileId, long exp_time_seconds, long exp_time_nanos, long auto_renew_period, byte[] admin_key, byte[] key, long fk_proxy_account_id) throws SQLException {
return createEntity(fileId.getShardNum(),fileId.getRealmNum(), fileId.getFileNum(), exp_time_seconds, exp_time_nanos, auto_renew_period, admin_key, key, fk_proxy_account_id, FK_FILE);
public long createEntity(FileID fileId, long exp_time_seconds, long exp_time_nanos, long auto_renew_period, byte[] key, long fk_proxy_account_id) throws SQLException {
return createEntity(fileId.getShardNum(),fileId.getRealmNum(), fileId.getFileNum(), exp_time_seconds, exp_time_nanos, auto_renew_period, key, fk_proxy_account_id, FK_FILE);
}
public long createEntity(ContractID contractId, long exp_time_seconds, long exp_time_nanos, long auto_renew_period, byte[] admin_key, byte[] key, long fk_proxy_account_id) throws SQLException {
return createEntity(contractId.getShardNum(),contractId.getRealmNum(), contractId.getContractNum(), exp_time_seconds, exp_time_nanos, auto_renew_period, admin_key, key, fk_proxy_account_id, FK_CONTRACT);
public long createEntity(ContractID contractId, long exp_time_seconds, long exp_time_nanos, long auto_renew_period, byte[] key, long fk_proxy_account_id) throws SQLException {
return createEntity(contractId.getShardNum(),contractId.getRealmNum(), contractId.getContractNum(), exp_time_seconds, exp_time_nanos, auto_renew_period, key, fk_proxy_account_id, FK_CONTRACT);
}
public long createEntity(AccountID accountId, long exp_time_seconds, long exp_time_nanos, long auto_renew_period, byte[] admin_key, byte[] key, long fk_proxy_account_id) throws SQLException {
return createEntity(accountId.getShardNum(),accountId.getRealmNum(), accountId.getAccountNum(), exp_time_seconds, exp_time_nanos, auto_renew_period, admin_key, key, fk_proxy_account_id, FK_ACCOUNT);
public long createEntity(AccountID accountId, long exp_time_seconds, long exp_time_nanos, long auto_renew_period, byte[] key, long fk_proxy_account_id) throws SQLException {
return createEntity(accountId.getShardNum(),accountId.getRealmNum(), accountId.getAccountNum(), exp_time_seconds, exp_time_nanos, auto_renew_period, key, fk_proxy_account_id, FK_ACCOUNT);
}
private long createOrGetEntity(long shard, long realm, long num, int fk_entity_type) throws SQLException {

Expand All @@ -378,8 +399,8 @@ private long createOrGetEntity(long shard, long realm, long num, int fk_entity_t
entityCreate.setLong(7, 0);
entityCreate.setLong(8, 0);
entityCreate.setLong(9, 0);
entityCreate.setBytes(10, new byte[0]);
entityCreate.setBytes(11, new byte[0]);
entityCreate.setNull(10, VARCHAR);
entityCreate.setNull(11, VARBINARY);
entityCreate.setLong(12, 0);

entityCreate.execute();
Expand Down
Loading