Skip to content

Commit

Permalink
Add support for historical account details on accounts endpoint (#6034)
Browse files Browse the repository at this point in the history
* Ensure provided timestamp params provide effective range
* Union entity query with entity_history for specified timestamp
* Return balance by querying the account_balance table for matching timestamp query
* Filter token balances from token_account by matching created_timestamp against timestamp query
* add config prop to disable strict timestamp range checking

Signed-off-by: Jesse Nelson <jesse@swirldslabs.com>
  • Loading branch information
jnels124 committed Jun 16, 2023
1 parent dad1439 commit e807071
Show file tree
Hide file tree
Showing 18 changed files with 1,265 additions and 245 deletions.
1 change: 1 addition & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ value, it is recommended to only populate overridden properties in the custom `a
| `hedera.mirror.rest.query.maxRepeatedQueryParameters` | 100 | The maximum number of times any query parameter can be repeated in the uri |
| `hedera.mirror.rest.query.maxTimestampRange` | 7d | The maximum amount of time a timestamp range query param can span for some APIs. |
| `hedera.mirror.rest.query.maxTransactionConsensusTimestampRange` | 35m | The maximum amount of time of a transaction's consensus timestamp from its valid start timestamp. |
| `hedera.mirror.rest.query.strictTimestampParam` | true | Enables strict checking of timestamp query param (currently only effects /api/v1/accounts/{id}?timestamp={timestamp} |
| `hedera.mirror.rest.response.compression` | true | Whether content negotiation should occur to compress response bodies if requested |
| `hedera.mirror.rest.response.headers.default` | See application.yml | The default headers to add to every response. |
| `hedera.mirror.rest.response.headers.path` | See application.yml | The per path headers to add to every response. The key is the route name and the value is a header map. |
Expand Down
6 changes: 4 additions & 2 deletions hedera-mirror-rest/__tests__/__snapshots__/utils.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ exports[`Utils test - utils.checkTimestampRange invalid bad range lower bound >

exports[`Utils test - utils.checkTimestampRange invalid bad range lower bound > higher bound gte lte 1`] = `"Timestamp lower and upper bounds must be positive and within 7d"`;

exports[`Utils test - utils.checkTimestampRange invalid ne combined with eq - ne allowed 1`] = `"Cannot combine eq with ne, gt, gte, lt, or lte for timestamp param"`;

exports[`Utils test - utils.checkTimestampRange invalid no filters 1`] = `"No timestamp range or eq operator provided"`;

exports[`Utils test - utils.checkTimestampRange invalid one filter gt 1`] = `"Timestamp range must have gt (or gte) and lt (or lte)"`;
Expand All @@ -22,9 +24,9 @@ exports[`Utils test - utils.checkTimestampRange invalid range exceeds configured

exports[`Utils test - utils.checkTimestampRange invalid range exceeds configured max gte and lte 1`] = `"Timestamp lower and upper bounds must be positive and within 7d"`;

exports[`Utils test - utils.checkTimestampRange invalid three filters gt lte eq 1`] = `"Cannot combine eq with gt, gte, lt, or lte for timestamp param"`;
exports[`Utils test - utils.checkTimestampRange invalid three filters gt lte eq 1`] = `"Cannot combine eq with ne, gt, gte, lt, or lte for timestamp param"`;

exports[`Utils test - utils.checkTimestampRange invalid two filters gt and eq 1`] = `"Cannot combine eq with gt, gte, lt, or lte for timestamp param"`;
exports[`Utils test - utils.checkTimestampRange invalid two filters gt and eq 1`] = `"Cannot combine eq with ne, gt, gte, lt, or lte for timestamp param"`;

exports[`Utils test - utils.checkTimestampRange invalid two filters gt and get 1`] = `"Multiple gt or gte operators not permitted for timestamp param"`;

Expand Down
1 change: 1 addition & 0 deletions hedera-mirror-rest/__tests__/config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ describe('Override query config', () => {
maxTimestampRangeNs: 86400000000000n,
maxTransactionConsensusTimestampRange: '10m',
maxTransactionConsensusTimestampRangeNs: 600000000000n,
strictTimestampParam: true,
};
const config = await loadCustomConfig(customConfig(queryConfig));
expect(config.query).toEqual(expected);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,94 +123,6 @@ describe('extractSqlFromContractFilters', () => {
});
});

describe('extractTimestampConditionsFromContractFilters', () => {
const timestampKey = constants.filterKeys.TIMESTAMP;
const timestampColumn = Entity.getFullName(Entity.TIMESTAMP_RANGE);
const specs = [
{
name: emptyFilterString,
input: [],
expected: {
conditions: [],
params: [],
},
},
{
name: 'no timestamp filters',
input: [
{
key: constants.filterKeys.ORDER,
operator: utils.opsMap.eq,
value: constants.orderFilterValues.ASC,
},
],
expected: {
conditions: [],
params: [],
},
},
{
name: 'timestamp filters',
input: [
{
key: timestampKey,
operator: utils.opsMap.eq, // will be converted to lte
value: '200',
},
{
key: timestampKey,
operator: utils.opsMap.gt,
value: '201',
},
{
key: timestampKey,
operator: utils.opsMap.gte,
value: '202',
},
{
key: timestampKey,
operator: utils.opsMap.lt,
value: '203',
},
{
key: timestampKey,
operator: utils.opsMap.lte,
value: '204',
},
{
key: timestampKey,
operator: utils.opsMap.ne,
value: '205',
},
],
expected: {
conditions: [
`${timestampColumn} && $1`,
`${timestampColumn} && $2`,
`${timestampColumn} && $3`,
`${timestampColumn} && $4`,
`${timestampColumn} && $5`,
`not ${timestampColumn} @> $6`,
],
params: [
Range(null, '200', '(]'),
Range('201', null, '()'),
Range('202', null, '[)'),
Range(null, '203', '()'),
Range(null, '204', '(]'),
Range('205', '205', '[]'),
],
},
},
];

specs.forEach((spec) => {
test(`${spec.name}`, () => {
expect(contracts.extractTimestampConditionsFromContractFilters(spec.input)).toEqual(spec.expected);
});
});
});

describe('formatContractRow', () => {
const input = {
auto_renew_account_id: 1005,
Expand Down

0 comments on commit e807071

Please sign in to comment.