github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/state/stateutil/trie_helpers.go (about)

     1  package stateutil
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  
     7  	"github.com/pkg/errors"
     8  	"github.com/prysmaticlabs/prysm/shared/hashutil"
     9  	"github.com/prysmaticlabs/prysm/shared/htrutils"
    10  	"github.com/prysmaticlabs/prysm/shared/trieutil"
    11  )
    12  
    13  // ReturnTrieLayer returns the representation of a merkle trie when
    14  // provided with the elements of a fixed sized trie and the corresponding depth of
    15  // it.
    16  func ReturnTrieLayer(elements [][32]byte, length uint64) [][]*[32]byte {
    17  	hasher := hashutil.CustomSHA256Hasher()
    18  	leaves := elements
    19  
    20  	if len(leaves) == 1 {
    21  		return [][]*[32]byte{{&leaves[0]}}
    22  	}
    23  	hashLayer := leaves
    24  	layers := make([][][32]byte, htrutils.Depth(length)+1)
    25  	layers[0] = hashLayer
    26  	layers, _ = merkleizeTrieLeaves(layers, hashLayer, hasher)
    27  	refLayers := make([][]*[32]byte, len(layers))
    28  	for i, val := range layers {
    29  		refLayers[i] = make([]*[32]byte, len(val))
    30  		for j, innerVal := range val {
    31  			newVal := innerVal
    32  			refLayers[i][j] = &newVal
    33  		}
    34  	}
    35  	return refLayers
    36  }
    37  
    38  func merkleizeTrieLeaves(layers [][][32]byte, hashLayer [][32]byte,
    39  	hasher func([]byte) [32]byte) ([][][32]byte, [][32]byte) {
    40  	// We keep track of the hash layers of a Merkle trie until we reach
    41  	// the top layer of length 1, which contains the single root element.
    42  	//        [Root]      -> Top layer has length 1.
    43  	//    [E]       [F]   -> This layer has length 2.
    44  	// [A]  [B]  [C]  [D] -> The bottom layer has length 4 (needs to be a power of two).
    45  	i := 1
    46  	chunkBuffer := bytes.NewBuffer([]byte{})
    47  	chunkBuffer.Grow(64)
    48  	for len(hashLayer) > 1 && i < len(layers) {
    49  		layer := make([][32]byte, len(hashLayer)/2)
    50  		for j := 0; j < len(hashLayer); j += 2 {
    51  			chunkBuffer.Write(hashLayer[j][:])
    52  			chunkBuffer.Write(hashLayer[j+1][:])
    53  			hashedChunk := hasher(chunkBuffer.Bytes())
    54  			layer[j/2] = hashedChunk
    55  			chunkBuffer.Reset()
    56  		}
    57  		hashLayer = layer
    58  		layers[i] = hashLayer
    59  		i++
    60  	}
    61  	return layers, hashLayer
    62  }
    63  
    64  // ReturnTrieLayerVariable returns the representation of a merkle trie when
    65  // provided with the elements of a variable sized trie and the corresponding depth of
    66  // it.
    67  func ReturnTrieLayerVariable(elements [][32]byte, length uint64) [][]*[32]byte {
    68  	hasher := hashutil.CustomSHA256Hasher()
    69  	depth := htrutils.Depth(length)
    70  	layers := make([][]*[32]byte, depth+1)
    71  	// Return zerohash at depth
    72  	if len(elements) == 0 {
    73  		zerohash := trieutil.ZeroHashes[depth]
    74  		layers[len(layers)-1] = []*[32]byte{&zerohash}
    75  		return layers
    76  	}
    77  	transformedLeaves := make([]*[32]byte, len(elements))
    78  	for i := range elements {
    79  		arr := elements[i]
    80  		transformedLeaves[i] = &arr
    81  	}
    82  	layers[0] = transformedLeaves
    83  	buffer := bytes.NewBuffer([]byte{})
    84  	buffer.Grow(64)
    85  	for i := 0; i < int(depth); i++ {
    86  		oddNodeLength := len(layers[i])%2 == 1
    87  		if oddNodeLength {
    88  			zerohash := trieutil.ZeroHashes[i]
    89  			layers[i] = append(layers[i], &zerohash)
    90  		}
    91  		updatedValues := make([]*[32]byte, 0, len(layers[i])/2)
    92  		for j := 0; j < len(layers[i]); j += 2 {
    93  			buffer.Write(layers[i][j][:])
    94  			buffer.Write(layers[i][j+1][:])
    95  			concat := hasher(buffer.Bytes())
    96  			updatedValues = append(updatedValues, &concat)
    97  			buffer.Reset()
    98  		}
    99  		// remove zerohash node from tree
   100  		if oddNodeLength {
   101  			layers[i] = layers[i][:len(layers[i])-1]
   102  		}
   103  		layers[i+1] = updatedValues
   104  	}
   105  	return layers
   106  }
   107  
   108  // RecomputeFromLayer recomputes specific branches of a fixed sized trie depending on the provided changed indexes.
   109  func RecomputeFromLayer(changedLeaves [][32]byte, changedIdx []uint64, layer [][]*[32]byte) ([32]byte, [][]*[32]byte, error) {
   110  	hasher := hashutil.CustomSHA256Hasher()
   111  	for i, idx := range changedIdx {
   112  		layer[0][idx] = &changedLeaves[i]
   113  	}
   114  
   115  	if len(changedIdx) == 0 {
   116  		return *layer[0][0], layer, nil
   117  	}
   118  
   119  	leaves := layer[0]
   120  
   121  	// We need to ensure we recompute indices of the Merkle tree which
   122  	// changed in-between calls to this function. This check adds an offset
   123  	// to the recomputed indices to ensure we do so evenly.
   124  	maxChangedIndex := changedIdx[len(changedIdx)-1]
   125  	if int(maxChangedIndex+2) == len(leaves) && maxChangedIndex%2 != 0 {
   126  		changedIdx = append(changedIdx, maxChangedIndex+1)
   127  	}
   128  
   129  	root := *layer[0][0]
   130  	var err error
   131  
   132  	for _, idx := range changedIdx {
   133  		root, layer, err = recomputeRootFromLayer(int(idx), layer, leaves, hasher)
   134  		if err != nil {
   135  			return [32]byte{}, nil, err
   136  		}
   137  	}
   138  	return root, layer, nil
   139  }
   140  
   141  // RecomputeFromLayerVariable recomputes specific branches of a variable sized trie depending on the provided changed indexes.
   142  func RecomputeFromLayerVariable(changedLeaves [][32]byte, changedIdx []uint64, layer [][]*[32]byte) ([32]byte, [][]*[32]byte, error) {
   143  	hasher := hashutil.CustomSHA256Hasher()
   144  	if len(changedIdx) == 0 {
   145  		return *layer[0][0], layer, nil
   146  	}
   147  	root := *layer[len(layer)-1][0]
   148  	var err error
   149  
   150  	for i, idx := range changedIdx {
   151  		root, layer, err = recomputeRootFromLayerVariable(int(idx), changedLeaves[i], layer, hasher)
   152  		if err != nil {
   153  			return [32]byte{}, nil, err
   154  		}
   155  	}
   156  	return root, layer, nil
   157  }
   158  
   159  // this method assumes that the provided trie already has all its elements included
   160  // in the base depth.
   161  func recomputeRootFromLayer(idx int, layers [][]*[32]byte, chunks []*[32]byte,
   162  	hasher func([]byte) [32]byte) ([32]byte, [][]*[32]byte, error) {
   163  	root := *chunks[idx]
   164  	layers[0] = chunks
   165  	// The merkle tree structure looks as follows:
   166  	// [[r1, r2, r3, r4], [parent1, parent2], [root]]
   167  	// Using information about the index which changed, idx, we recompute
   168  	// only its branch up the tree.
   169  	currentIndex := idx
   170  	for i := 0; i < len(layers)-1; i++ {
   171  		isLeft := currentIndex%2 == 0
   172  		neighborIdx := currentIndex ^ 1
   173  
   174  		neighbor := [32]byte{}
   175  		if layers[i] != nil && len(layers[i]) != 0 && neighborIdx < len(layers[i]) {
   176  			neighbor = *layers[i][neighborIdx]
   177  		}
   178  		if isLeft {
   179  			parentHash := hasher(append(root[:], neighbor[:]...))
   180  			root = parentHash
   181  		} else {
   182  			parentHash := hasher(append(neighbor[:], root[:]...))
   183  			root = parentHash
   184  		}
   185  		parentIdx := currentIndex / 2
   186  		// Update the cached layers at the parent index.
   187  		rootVal := root
   188  		if len(layers[i+1]) == 0 {
   189  			layers[i+1] = append(layers[i+1], &rootVal)
   190  		} else {
   191  			layers[i+1][parentIdx] = &rootVal
   192  		}
   193  		currentIndex = parentIdx
   194  	}
   195  	// If there is only a single leaf, we return it (the identity element).
   196  	if len(layers[0]) == 1 {
   197  		return *layers[0][0], layers, nil
   198  	}
   199  	return root, layers, nil
   200  }
   201  
   202  // this method assumes that the base branch does not consist of all leaves of the
   203  // trie. Instead missing leaves are assumed to be zerohashes, following the structure
   204  // of a sparse merkle trie.
   205  func recomputeRootFromLayerVariable(idx int, item [32]byte, layers [][]*[32]byte,
   206  	hasher func([]byte) [32]byte) ([32]byte, [][]*[32]byte, error) {
   207  	for idx >= len(layers[0]) {
   208  		zerohash := trieutil.ZeroHashes[0]
   209  		layers[0] = append(layers[0], &zerohash)
   210  	}
   211  	layers[0][idx] = &item
   212  
   213  	currentIndex := idx
   214  	root := item
   215  	for i := 0; i < len(layers)-1; i++ {
   216  		isLeft := currentIndex%2 == 0
   217  		neighborIdx := currentIndex ^ 1
   218  
   219  		neighbor := [32]byte{}
   220  		if neighborIdx >= len(layers[i]) {
   221  			neighbor = trieutil.ZeroHashes[i]
   222  		} else {
   223  			neighbor = *layers[i][neighborIdx]
   224  		}
   225  		if isLeft {
   226  			parentHash := hasher(append(root[:], neighbor[:]...))
   227  			root = parentHash
   228  		} else {
   229  			parentHash := hasher(append(neighbor[:], root[:]...))
   230  			root = parentHash
   231  		}
   232  		parentIdx := currentIndex / 2
   233  		if len(layers[i+1]) == 0 || parentIdx >= len(layers[i+1]) {
   234  			newItem := root
   235  			layers[i+1] = append(layers[i+1], &newItem)
   236  		} else {
   237  			newItem := root
   238  			layers[i+1][parentIdx] = &newItem
   239  		}
   240  		currentIndex = parentIdx
   241  	}
   242  	return root, layers, nil
   243  }
   244  
   245  // AddInMixin describes a method from which a lenth mixin is added to the
   246  // provided root.
   247  func AddInMixin(root [32]byte, length uint64) ([32]byte, error) {
   248  	rootBuf := new(bytes.Buffer)
   249  	if err := binary.Write(rootBuf, binary.LittleEndian, length); err != nil {
   250  		return [32]byte{}, errors.Wrap(err, "could not marshal eth1data votes length")
   251  	}
   252  	// We need to mix in the length of the slice.
   253  	rootBufRoot := make([]byte, 32)
   254  	copy(rootBufRoot, rootBuf.Bytes())
   255  	return htrutils.MixInLength(root, rootBufRoot), nil
   256  }
   257  
   258  // Merkleize 32-byte leaves into a Merkle trie for its adequate depth, returning
   259  // the resulting layers of the trie based on the appropriate depth. This function
   260  // pads the leaves to a length of 32.
   261  func Merkleize(leaves [][]byte) [][][]byte {
   262  	hashFunc := hashutil.CustomSHA256Hasher()
   263  	layers := make([][][]byte, htrutils.Depth(uint64(len(leaves)))+1)
   264  	for len(leaves) != 32 {
   265  		leaves = append(leaves, make([]byte, 32))
   266  	}
   267  	currentLayer := leaves
   268  	layers[0] = currentLayer
   269  
   270  	// We keep track of the hash layers of a Merkle trie until we reach
   271  	// the top layer of length 1, which contains the single root element.
   272  	//        [Root]      -> Top layer has length 1.
   273  	//    [E]       [F]   -> This layer has length 2.
   274  	// [A]  [B]  [C]  [D] -> The bottom layer has length 4 (needs to be a power of two).
   275  	i := 1
   276  	for len(currentLayer) > 1 && i < len(layers) {
   277  		layer := make([][]byte, 0)
   278  		for i := 0; i < len(currentLayer); i += 2 {
   279  			hashedChunk := hashFunc(append(currentLayer[i], currentLayer[i+1]...))
   280  			layer = append(layer, hashedChunk[:])
   281  		}
   282  		currentLayer = layer
   283  		layers[i] = currentLayer
   284  		i++
   285  	}
   286  	return layers
   287  }
   288  
   289  // MerkleizeTrieLeaves merkleize the trie leaves.
   290  func MerkleizeTrieLeaves(layers [][][32]byte, hashLayer [][32]byte,
   291  	hasher func([]byte) [32]byte) ([][][32]byte, [][32]byte) {
   292  	// We keep track of the hash layers of a Merkle trie until we reach
   293  	// the top layer of length 1, which contains the single root element.
   294  	//        [Root]      -> Top layer has length 1.
   295  	//    [E]       [F]   -> This layer has length 2.
   296  	// [A]  [B]  [C]  [D] -> The bottom layer has length 4 (needs to be a power of two).
   297  	i := 1
   298  	chunkBuffer := bytes.NewBuffer([]byte{})
   299  	chunkBuffer.Grow(64)
   300  	for len(hashLayer) > 1 && i < len(layers) {
   301  		layer := make([][32]byte, len(hashLayer)/2)
   302  		for j := 0; j < len(hashLayer); j += 2 {
   303  			chunkBuffer.Write(hashLayer[j][:])
   304  			chunkBuffer.Write(hashLayer[j+1][:])
   305  			hashedChunk := hasher(chunkBuffer.Bytes())
   306  			layer[j/2] = hashedChunk
   307  			chunkBuffer.Reset()
   308  		}
   309  		hashLayer = layer
   310  		layers[i] = hashLayer
   311  		i++
   312  	}
   313  	return layers, hashLayer
   314  }