-
Notifications
You must be signed in to change notification settings - Fork 285
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core-database-postgres): enforce chained blocks at database level (
#2753) Make sure we don't end up with blocks having previous_block point to a nonexistent block, even if bugs exist at the application level that would attempt to do that.
- Loading branch information
1 parent
5e17b5a
commit 7de758b
Showing
2 changed files
with
44 additions
and
0 deletions.
There are no files selected for viewing
43 changes: 43 additions & 0 deletions
43
packages/core-database-postgres/src/migrations/20190626000000-enforce-chained-blocks.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
ALTER TABLE blocks DROP CONSTRAINT IF EXISTS "chained_blocks"; | ||
|
||
DROP FUNCTION IF EXISTS check_previous_block; | ||
|
||
CREATE FUNCTION check_previous_block( | ||
id_arg VARCHAR(64), | ||
previous_block_arg VARCHAR(64), | ||
height_arg INTEGER | ||
) RETURNS BOOLEAN | ||
AS | ||
$$ | ||
DECLARE | ||
block_id_at_height_minus1 VARCHAR(64); | ||
previous_block_height INTEGER; | ||
fail_reason TEXT; | ||
BEGIN | ||
IF height_arg = 1 THEN | ||
RETURN TRUE; | ||
END IF; | ||
|
||
SELECT id INTO block_id_at_height_minus1 FROM blocks WHERE height = height_arg - 1; | ||
|
||
IF previous_block_arg = block_id_at_height_minus1 THEN | ||
RETURN TRUE; | ||
END IF; | ||
|
||
SELECT height INTO previous_block_height FROM blocks WHERE id = previous_block_arg; | ||
|
||
IF previous_block_height IS NULL THEN | ||
fail_reason := 'a block with id "' || previous_block_arg || '" does not exist'; | ||
ELSE | ||
fail_reason := 'a block with id "' || previous_block_arg || '" exists but at an unexpected height ' || | ||
previous_block_height || ' instead of ' || height_arg - 1; | ||
END IF; | ||
|
||
RAISE 'Cannot insert new block (id="%", height=%, previous_block="%") because %', | ||
id_arg, height_arg, previous_block_arg, fail_reason; | ||
END; | ||
$$ | ||
LANGUAGE PLPGSQL | ||
VOLATILE; | ||
|
||
ALTER TABLE blocks ADD CONSTRAINT "chained_blocks" CHECK (check_previous_block(id, previous_block, height)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters