@@ -3,6 +3,7 @@ import { Cell } from '../boc/Cell';
3
3
import { Slice } from '../boc/Slice' ;
4
4
import { DictionaryKeyTypes , Dictionary , DictionaryKey } from './Dictionary' ;
5
5
import { readUnaryLength } from './utils/readUnaryLength' ;
6
+ import { convertToMerkleProof } from '../boc/cell/exoticMerkleProof' ;
6
7
7
8
function convertToPrunedBranch ( c : Cell ) : Cell {
8
9
return beginCell ( )
@@ -13,24 +14,20 @@ function convertToPrunedBranch(c: Cell): Cell {
13
14
. endCell ( { exotic : true } ) ;
14
15
}
15
16
16
- function convertToMerkleProof ( c : Cell ) : Cell {
17
- return beginCell ( )
18
- . storeUint ( 3 , 8 )
19
- . storeBuffer ( c . hash ( 0 ) )
20
- . storeUint ( c . depth ( 0 ) , 16 )
21
- . storeRef ( c )
22
- . endCell ( { exotic : true } ) ;
23
- }
24
-
25
17
function doGenerateMerkleProof (
26
18
prefix : string ,
27
19
slice : Slice ,
28
20
n : number ,
29
- key : string
21
+ keys : string [ ]
30
22
) : Cell {
31
23
// Reading label
32
24
const originalCell = slice . asCell ( ) ;
33
25
26
+ if ( keys . length == 0 ) {
27
+ // no keys to prove, prune the whole subdict
28
+ return convertToPrunedBranch ( originalCell ) ;
29
+ }
30
+
34
31
let lb0 = slice . loadBit ( ) ? 1 : 0 ;
35
32
let prefixLength = 0 ;
36
33
let pp = prefix ;
@@ -71,28 +68,26 @@ function doGenerateMerkleProof(
71
68
let right = sl . loadRef ( ) ;
72
69
// NOTE: Left and right branches are implicitly contain prefixes '0' and '1'
73
70
if ( ! left . isExotic ) {
74
- if ( pp + '0' === key . slice ( 0 , pp . length + 1 ) ) {
75
- left = doGenerateMerkleProof (
76
- pp + '0' ,
77
- left . beginParse ( ) ,
78
- n - prefixLength - 1 ,
79
- key
80
- ) ;
81
- } else {
82
- left = convertToPrunedBranch ( left ) ;
83
- }
71
+ const leftKeys = keys . filter ( ( key ) => {
72
+ return pp + '0' === key . slice ( 0 , pp . length + 1 ) ;
73
+ } ) ;
74
+ left = doGenerateMerkleProof (
75
+ pp + '0' ,
76
+ left . beginParse ( ) ,
77
+ n - prefixLength - 1 ,
78
+ leftKeys
79
+ ) ;
84
80
}
85
81
if ( ! right . isExotic ) {
86
- if ( pp + '1' === key . slice ( 0 , pp . length + 1 ) ) {
87
- right = doGenerateMerkleProof (
88
- pp + '1' ,
89
- right . beginParse ( ) ,
90
- n - prefixLength - 1 ,
91
- key
92
- ) ;
93
- } else {
94
- right = convertToPrunedBranch ( right ) ;
95
- }
82
+ const rightKeys = keys . filter ( ( key ) => {
83
+ return pp + '1' === key . slice ( 0 , pp . length + 1 ) ;
84
+ } ) ;
85
+ right = doGenerateMerkleProof (
86
+ pp + '1' ,
87
+ right . beginParse ( ) ,
88
+ n - prefixLength - 1 ,
89
+ rightKeys
90
+ ) ;
96
91
}
97
92
98
93
return beginCell ( )
@@ -103,18 +98,25 @@ function doGenerateMerkleProof(
103
98
}
104
99
}
105
100
106
- export function generateMerkleProof < K extends DictionaryKeyTypes , V > (
101
+ export function generateMerkleProofDirect < K extends DictionaryKeyTypes , V > (
107
102
dict : Dictionary < K , V > ,
108
- key : K ,
103
+ keys : K [ ] ,
109
104
keyObject : DictionaryKey < K >
110
105
) : Cell {
111
- const s = beginCell ( ) . storeDictDirect ( dict ) . endCell ( ) . beginParse ( ) ;
112
- return convertToMerkleProof (
113
- doGenerateMerkleProof (
106
+ keys = keys . filter ( ( key ) => dict . has ( key ) ) ;
107
+ const s = beginCell ( ) . storeDictDirect ( dict ) . asSlice ( ) ;
108
+ return doGenerateMerkleProof (
114
109
'' ,
115
110
s ,
116
111
keyObject . bits ,
117
- keyObject . serialize ( key ) . toString ( 2 ) . padStart ( keyObject . bits , '0' )
118
- )
112
+ keys . map ( ( key ) => keyObject . serialize ( key ) . toString ( 2 ) . padStart ( keyObject . bits , '0' ) )
119
113
) ;
120
114
}
115
+
116
+ export function generateMerkleProof < K extends DictionaryKeyTypes , V > (
117
+ dict : Dictionary < K , V > ,
118
+ keys : K [ ] ,
119
+ keyObject : DictionaryKey < K >
120
+ ) : Cell {
121
+ return convertToMerkleProof ( generateMerkleProofDirect ( dict , keys , keyObject ) ) ;
122
+ }
0 commit comments