Skip to content

Commit

Permalink
Remove entities.admin_key (store value in entities.key). Add column e…
Browse files Browse the repository at this point in the history
…ntities.ed25519_public_key_hex.

Signed-off-by: Mike Burrage <mike.burrage@hedera.com>
  • Loading branch information
mike-burrage-hedera committed Sep 7, 2019
1 parent dd287c7 commit edc0af7
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 65 deletions.
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
110 changes: 74 additions & 36 deletions src/main/java/com/hedera/recordFileLogger/Entities.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,19 @@
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 com.hederahashgraph.api.proto.java.Key;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.codec.binary.Hex;

import javax.annotation.Nullable;

import static com.hederahashgraph.api.proto.java.Key.KeyCase.ED25519;
import static java.sql.Types.VARCHAR;

@Log4j2
public class Entities {
Expand All @@ -52,7 +60,7 @@ enum F_ENTITIES {
,EXP_TIME_NANOS
,EXP_TIME_NS
,AUTO_RENEW
,ADMIN_KEY
,ED25519_PUBLIC_KEY_HEX
,KEY
,FK_PROXY_ACCOUNT_ID
}
Expand All @@ -77,10 +85,25 @@ 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 {

/**
* If the protobuf encoding of a Key is a single ED25519 key, return the key as a String with hex encoding.
* @param protobufKey
* @return ED25519 public key as a String in hex encoding, or null
* @throws InvalidProtocolBufferException if the protobufKey is not a valid protobuf encoding of a Key (BasicTypes.proto)
*/
private @Nullable String protobufKeyToHexIfEd25519OrNull(@Nullable byte[] protobufKey)
throws InvalidProtocolBufferException {
if ((null == protobufKey) || (0 == protobufKey.length)) return null;

var parsedKey = Key.parseFrom(protobufKey);
if (ED25519 != parsedKey.getKeyCase()) return null;

return Hex.encodeHexString(parsedKey.getEd25519().toByteArray());
}

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 +112,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 +135,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 +173,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 = 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 +224,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 +339,7 @@ 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 +360,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.setNull(10, VARCHAR);
entityCreate.setBytes(11, new byte[0]);
} else {
String ed25519PublicKeyHex = null;
try {
ed25519PublicKeyHex = 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 +390,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,7 +416,7 @@ 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.setNull(10, VARCHAR);
entityCreate.setBytes(11, new byte[0]);
entityCreate.setLong(12, 0);

Expand Down
Loading

0 comments on commit edc0af7

Please sign in to comment.