From 994a42e6b1207fb91925e81faaf7cc282871fee8 Mon Sep 17 00:00:00 2001 From: Ben Edgington Date: Tue, 8 Jan 2019 19:47:14 +0000 Subject: [PATCH 1/6] Add getter to Vyper contract for Merkle branches Returns the Merkle branch for the leaf at index `index`. This getter provides an alternative way for beacon chain proposers to access the Merkle tree of deposits rather than being Ethereum 1.0 light clients. The method can be called on a trusted Ethereum 1.0 archive node at specific past block numbers to retrieve the Merkle branch needed to register a validator. --- specs/core/0_beacon-chain.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 23b35fc6f..c86b4b6b5 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -692,6 +692,18 @@ def deposit(deposit_input: bytes[2048]): def get_deposit_root() -> bytes32: return self.deposit_tree[1] +@public +@constant +def get_merkle_branch(index: uint256) -> bytes32[32]: # size is DEPOSIT_CONTRACT_TREE_DEPTH (symbolic const not supported) + idx: uint256 = index + TWO_TO_POWER_OF_TREE_DEPTH + ret: bytes32[32] # size is DEPOSIT_CONTRACT_TREE_DEPTH + for i in range(DEPOSIT_CONTRACT_TREE_DEPTH): + if idx % 2 == 1: + ret[i] = self.deposit_tree[idx - 1] + else: + ret[i] = self.deposit_tree[idx + 1] + idx /= 2 + return ret ``` ## Beacon chain processing From 78fcda7ce09a9075d148b7d2f5ada49cb68884e4 Mon Sep 17 00:00:00 2001 From: Ben Edgington Date: Thu, 10 Jan 2019 20:44:47 +0000 Subject: [PATCH 2/6] Use bitwise xor to simplify merkle branch getter --- specs/core/0_beacon-chain.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index c86b4b6b5..e2ed64cf1 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -698,10 +698,7 @@ def get_merkle_branch(index: uint256) -> bytes32[32]: # size is DEPOSIT_CONTRACT idx: uint256 = index + TWO_TO_POWER_OF_TREE_DEPTH ret: bytes32[32] # size is DEPOSIT_CONTRACT_TREE_DEPTH for i in range(DEPOSIT_CONTRACT_TREE_DEPTH): - if idx % 2 == 1: - ret[i] = self.deposit_tree[idx - 1] - else: - ret[i] = self.deposit_tree[idx + 1] + ret[i] = self.deposit_tree[bitwise_xor(idx,1)] idx /= 2 return ret ``` From dd532d78876871cc56a5a5102c592eccc9c6be9d Mon Sep 17 00:00:00 2001 From: Justin Date: Fri, 11 Jan 2019 11:52:04 +0000 Subject: [PATCH 3/6] Update 0_beacon-chain.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Avoid abbreviations * Use `branch` as a more suggestive variable name than `ret` * Cleanup spacing after comma * Avoid having two index variables (`index` and `idx`)—Does this break anything? --- specs/core/0_beacon-chain.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index e2ed64cf1..b7fcd284d 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -695,12 +695,12 @@ def get_deposit_root() -> bytes32: @public @constant def get_merkle_branch(index: uint256) -> bytes32[32]: # size is DEPOSIT_CONTRACT_TREE_DEPTH (symbolic const not supported) - idx: uint256 = index + TWO_TO_POWER_OF_TREE_DEPTH - ret: bytes32[32] # size is DEPOSIT_CONTRACT_TREE_DEPTH + index = index + TWO_TO_POWER_OF_TREE_DEPTH + branch: bytes32[32] # size is DEPOSIT_CONTRACT_TREE_DEPTH for i in range(DEPOSIT_CONTRACT_TREE_DEPTH): - ret[i] = self.deposit_tree[bitwise_xor(idx,1)] - idx /= 2 - return ret + branch[i] = self.deposit_tree[bitwise_xor(index, 1)] + index /= 2 + return branch ``` ## Beacon chain processing From c8bd90aba3c86222b80ca1f4ee60ed0d5d2668e5 Mon Sep 17 00:00:00 2001 From: Justin Date: Fri, 11 Jan 2019 11:53:12 +0000 Subject: [PATCH 4/6] Update 0_beacon-chain.md --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index b7fcd284d..baf5ca198 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -695,8 +695,8 @@ def get_deposit_root() -> bytes32: @public @constant def get_merkle_branch(index: uint256) -> bytes32[32]: # size is DEPOSIT_CONTRACT_TREE_DEPTH (symbolic const not supported) - index = index + TWO_TO_POWER_OF_TREE_DEPTH branch: bytes32[32] # size is DEPOSIT_CONTRACT_TREE_DEPTH + index = index + TWO_TO_POWER_OF_TREE_DEPTH for i in range(DEPOSIT_CONTRACT_TREE_DEPTH): branch[i] = self.deposit_tree[bitwise_xor(index, 1)] index /= 2 From 7a0d45279cac3a613ec31a7362b0c6114b27d794 Mon Sep 17 00:00:00 2001 From: Justin Date: Fri, 11 Jan 2019 15:24:29 +0000 Subject: [PATCH 5/6] Update 0_beacon-chain.md --- specs/core/0_beacon-chain.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index baf5ca198..dca6a0f36 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -694,9 +694,9 @@ def get_deposit_root() -> bytes32: @public @constant -def get_merkle_branch(index: uint256) -> bytes32[32]: # size is DEPOSIT_CONTRACT_TREE_DEPTH (symbolic const not supported) +def get_merkle_branch(deposit_count: uint256) -> bytes32[32]: # size is DEPOSIT_CONTRACT_TREE_DEPTH (symbolic const not supported) branch: bytes32[32] # size is DEPOSIT_CONTRACT_TREE_DEPTH - index = index + TWO_TO_POWER_OF_TREE_DEPTH + index: uint256 = deposit_count + TWO_TO_POWER_OF_TREE_DEPTH for i in range(DEPOSIT_CONTRACT_TREE_DEPTH): branch[i] = self.deposit_tree[bitwise_xor(index, 1)] index /= 2 From 271e7b5cb83386c4dc82d967df7a42eafd5c969d Mon Sep 17 00:00:00 2001 From: Justin Date: Fri, 11 Jan 2019 16:23:10 +0000 Subject: [PATCH 6/6] Update 0_beacon-chain.md --- specs/core/0_beacon-chain.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index dca6a0f36..a5c3d92f8 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -694,9 +694,9 @@ def get_deposit_root() -> bytes32: @public @constant -def get_merkle_branch(deposit_count: uint256) -> bytes32[32]: # size is DEPOSIT_CONTRACT_TREE_DEPTH (symbolic const not supported) +def get_branch(leaf: uint256) -> bytes32[32]: # size is DEPOSIT_CONTRACT_TREE_DEPTH (symbolic const not supported) branch: bytes32[32] # size is DEPOSIT_CONTRACT_TREE_DEPTH - index: uint256 = deposit_count + TWO_TO_POWER_OF_TREE_DEPTH + index: uint256 = leaf + TWO_TO_POWER_OF_TREE_DEPTH for i in range(DEPOSIT_CONTRACT_TREE_DEPTH): branch[i] = self.deposit_tree[bitwise_xor(index, 1)] index /= 2