mirror of
https://github.com/vocdoni/arbo.git
synced 2026-01-10 06:17:58 -05:00
more renames
This commit is contained in:
124
tree_big.go
124
tree_big.go
@@ -12,17 +12,17 @@ import (
|
||||
// the tree. It locks the tree to prevent concurrent writes to the valuesdb and
|
||||
// creates a transaction to store the full values in the valuesdb. It returns
|
||||
// a slice of Invalid items and an error if something fails.
|
||||
func (t *Tree) AddBatchBigInt(k []*big.Int, v [][]*big.Int) ([]Invalid, error) {
|
||||
if len(k) != len(v) {
|
||||
func (t *Tree) AddBatchBigInt(keys []*big.Int, bigintsBatch [][]*big.Int) ([]Invalid, error) {
|
||||
if len(keys) != len(bigintsBatch) {
|
||||
return nil, fmt.Errorf("the number of keys and values missmatch")
|
||||
}
|
||||
// convert each key-value tuple into bytes
|
||||
var err error
|
||||
bks := make([][]byte, len(k))
|
||||
bvs := make([][]byte, len(k))
|
||||
fbvs := make([][]byte, len(k))
|
||||
for i, ki := range k {
|
||||
bks[i], bvs[i], fbvs[i], err = bigIntsToLeaf(t.HashFunction(), t.MaxKeyLen(), ki, v[i])
|
||||
bKeys := make([][]byte, len(keys))
|
||||
bValues := make([][]byte, len(keys))
|
||||
serializedBigIntsBatch := make([][]byte, len(keys))
|
||||
for i := range keys {
|
||||
bKeys[i], bValues[i], serializedBigIntsBatch[i], err = bigIntsToLeaf(t.HashFunction(), t.MaxKeyLen(), keys[i], bigintsBatch[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -31,33 +31,33 @@ func (t *Tree) AddBatchBigInt(k []*big.Int, v [][]*big.Int) ([]Invalid, error) {
|
||||
t.valuesdbMu.Lock()
|
||||
defer t.valuesdbMu.Unlock()
|
||||
// add the keys and leaf values in batch
|
||||
if invalids, err := t.AddBatch(bks, bvs); err != nil {
|
||||
if invalids, err := t.AddBatch(bKeys, bValues); err != nil {
|
||||
return invalids, err
|
||||
}
|
||||
// create a transaction for each group of keys and full values and store
|
||||
// create a transaction for each group of keys and serialized values and store
|
||||
// the errors in a slice to return them
|
||||
var fullInvalids []Invalid
|
||||
var invalids []Invalid
|
||||
wTx := t.valuesdb.WriteTx()
|
||||
defer wTx.Discard()
|
||||
for i := range bks {
|
||||
if err := wTx.Set(bks[i], fbvs[i]); err != nil {
|
||||
fullInvalids = append(fullInvalids, Invalid{i, err})
|
||||
for i := range bKeys {
|
||||
if err := wTx.Set(bKeys[i], serializedBigIntsBatch[i]); err != nil {
|
||||
invalids = append(invalids, Invalid{i, err})
|
||||
}
|
||||
}
|
||||
return fullInvalids, wTx.Commit()
|
||||
return invalids, wTx.Commit()
|
||||
}
|
||||
|
||||
// AddBigInt adds a key-value pair to the tree, it converts the big.Int key
|
||||
// and the slice of big.Int values into bytes and adds them to the tree. It
|
||||
// locks the tree to prevent concurrent writes to the valuesdb and creates a
|
||||
// transaction to store the full value in the valuesdb. It returns an error if
|
||||
// transaction to store the serialized bigints in the valuesdb. It returns an error if
|
||||
// something fails.
|
||||
func (t *Tree) AddBigInt(k *big.Int, v ...*big.Int) error {
|
||||
if k == nil {
|
||||
func (t *Tree) AddBigInt(key *big.Int, bigints ...*big.Int) error {
|
||||
if key == nil {
|
||||
return fmt.Errorf("key cannot be nil")
|
||||
}
|
||||
// convert the big ints to bytes
|
||||
bk, bv, fbv, err := bigIntsToLeaf(t.HashFunction(), t.MaxKeyLen(), k, v)
|
||||
bKey, bValue, serializedBigInts, err := bigIntsToLeaf(t.HashFunction(), t.MaxKeyLen(), key, bigints)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -65,15 +65,15 @@ func (t *Tree) AddBigInt(k *big.Int, v ...*big.Int) error {
|
||||
t.valuesdbMu.Lock()
|
||||
defer t.valuesdbMu.Unlock()
|
||||
// add it to the tree
|
||||
if err := t.Add(bk, bv); err != nil {
|
||||
if err := t.Add(bKey, bValue); err != nil {
|
||||
return fmt.Errorf("raw key cannot be added: %w", err)
|
||||
}
|
||||
// create a transaction to store the full value
|
||||
// create a transaction to store the serialized bigints
|
||||
wTx := t.valuesdb.WriteTx()
|
||||
defer wTx.Discard()
|
||||
// store the full value in the valuesdb
|
||||
if err := wTx.Set(bk, fbv); err != nil {
|
||||
return fmt.Errorf("full value cannot be stored: %w", err)
|
||||
// store the serialized bigints in the valuesdb
|
||||
if err := wTx.Set(bKey, serializedBigInts); err != nil {
|
||||
return fmt.Errorf("serializedBigInts cannot be stored: %w", err)
|
||||
}
|
||||
return wTx.Commit()
|
||||
}
|
||||
@@ -82,12 +82,12 @@ func (t *Tree) AddBigInt(k *big.Int, v ...*big.Int) error {
|
||||
// leaf node as a slice of big.Ints. It encodes the key as bytes and updates
|
||||
// the leaf node in the tree, then it stores the full value in the valuesdb. It
|
||||
// returns an error if something fails.
|
||||
func (t *Tree) UpdateBigInt(k *big.Int, value ...*big.Int) error {
|
||||
if k == nil {
|
||||
func (t *Tree) UpdateBigInt(key *big.Int, bigints ...*big.Int) error {
|
||||
if key == nil {
|
||||
return fmt.Errorf("key cannot be nil")
|
||||
}
|
||||
// convert the big ints to bytes
|
||||
bk, bv, fbv, err := bigIntsToLeaf(t.HashFunction(), t.MaxKeyLen(), k, value)
|
||||
bKey, bValue, serializedBigInts, err := bigIntsToLeaf(t.HashFunction(), t.MaxKeyLen(), key, bigints)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -95,22 +95,22 @@ func (t *Tree) UpdateBigInt(k *big.Int, value ...*big.Int) error {
|
||||
t.valuesdbMu.Lock()
|
||||
defer t.valuesdbMu.Unlock()
|
||||
// update the leaf in the tree
|
||||
if err := t.Update(bk, bv); err != nil {
|
||||
if err := t.Update(bKey, bValue); err != nil {
|
||||
return err
|
||||
}
|
||||
// create a transaction to store the full value
|
||||
// create a transaction to store the serialized bigints
|
||||
wTx := t.valuesdb.WriteTx()
|
||||
defer wTx.Discard()
|
||||
// store the full value in the valuesdb
|
||||
if err := wTx.Set(bk, fbv); err != nil {
|
||||
// store the serialized bigints value in the valuesdb
|
||||
if err := wTx.Set(bKey, serializedBigInts); err != nil {
|
||||
return err
|
||||
}
|
||||
return wTx.Commit()
|
||||
}
|
||||
|
||||
// GetBigInt gets the value of a key as a big.Int and the values of the leaf
|
||||
// GetBigInt receives the value of a key as a big.Int and the values of the leaf
|
||||
// node as a slice of big.Ints. It encodes the key as bytes and gets the leaf
|
||||
// node from the tree, then it decodes the full value of the leaf node and
|
||||
// node from the tree, then it decodes the serialized bigints of the leaf node and
|
||||
// returns the key and the values or an error if something fails.
|
||||
func (t *Tree) GetBigInt(k *big.Int) (*big.Int, []*big.Int, error) {
|
||||
// acquire lock to wait for atomic updates to treedb and valuesdb to finish
|
||||
@@ -124,11 +124,11 @@ func (t *Tree) GetBigInt(k *big.Int) (*big.Int, []*big.Int, error) {
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
bFullValue, err := t.valuesdb.Get(bk)
|
||||
serializedBigInts, err := t.valuesdb.Get(bk)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return t.leafToBigInts(ExplicitZero(bk), bv, bFullValue)
|
||||
return t.leafToBigInts(ExplicitZero(bk), bv, serializedBigInts)
|
||||
}
|
||||
|
||||
// GenProofBigInts generates a proof for a key as a big.Int. It converts the
|
||||
@@ -169,14 +169,14 @@ func (t *Tree) GenerateGnarkVerifierProofBigInt(k *big.Int) (*GnarkVerifierProof
|
||||
}
|
||||
|
||||
// leafToBigInts converts the bytes of the key and the value of a leaf node
|
||||
// into a big.Int key and a slice of big.Int values, it gets the full value
|
||||
// into a big.Int key and a slice of big.Int values, it gets the serialized bigints
|
||||
// from the valuesdb and checks if it matches the value of the leaf node. It
|
||||
// returns the original key and values or an error if the values don't match.
|
||||
func (t *Tree) leafToBigInts(key, value, bigints []byte) (*big.Int, []*big.Int, error) {
|
||||
// reverse the process of values encoding
|
||||
values := deserializeBigInts(bigints)
|
||||
func (t *Tree) leafToBigInts(key, value, serializedBigInts []byte) (*big.Int, []*big.Int, error) {
|
||||
// reverse the process of bigints encoding
|
||||
bigints := deserializeBigInts(serializedBigInts)
|
||||
// reencode the leaf value of the tree to check if it matches the value
|
||||
bigintsHash, err := hashBigInts(t.HashFunction(), values...)
|
||||
bigintsHash, err := hashBigInts(t.HashFunction(), bigints...)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -186,12 +186,11 @@ func (t *Tree) leafToBigInts(key, value, bigints []byte) (*big.Int, []*big.Int,
|
||||
return nil, nil, fmt.Errorf("LeafToBigInt: bigintsHash != value")
|
||||
}
|
||||
// convert the bytes of the key to a big.Int
|
||||
return leafKeyToBigInt(key), values, nil
|
||||
return leafKeyToBigInt(key), bigints, nil
|
||||
}
|
||||
|
||||
// leafKeyToBigInt converts the bytes of a key into a big.Int. It returns the
|
||||
// big.Int value of the key in Big-Endian format, assuming the key is encoded
|
||||
// in Little-Endian format.
|
||||
// leafKeyToBigInt converts the bytes of a key into a big.Int.
|
||||
// It assumes the key is encoded in Little-Endian format.
|
||||
func leafKeyToBigInt(key []byte) *big.Int {
|
||||
return BytesToBigInt(key)
|
||||
}
|
||||
@@ -207,41 +206,40 @@ func bigIntToLeafKey(key *big.Int, maxLen int) []byte {
|
||||
// encoded in a reversible way. It concatenates the bytes of the
|
||||
// values with the length of each value at the beginning of each value.
|
||||
func serializeBigInts(bigints []*big.Int) ([]byte, error) {
|
||||
// calculate the bytes of the full values (should be reversible)
|
||||
bFullValue := []byte{}
|
||||
for _, v := range bigints {
|
||||
if v == nil {
|
||||
serializedBigInts := []byte{}
|
||||
for _, bi := range bigints {
|
||||
if bi == nil {
|
||||
return nil, fmt.Errorf("value cannot be nil")
|
||||
}
|
||||
vBytes := v.Bytes()
|
||||
if len(vBytes) > 255 {
|
||||
biBytes := bi.Bytes()
|
||||
if len(biBytes) > 255 {
|
||||
return nil, fmt.Errorf("value byte length cannot exceed 255")
|
||||
}
|
||||
val := append([]byte{byte(len(vBytes))}, vBytes...)
|
||||
bFullValue = append(bFullValue, val...)
|
||||
val := append([]byte{byte(len(biBytes))}, biBytes...)
|
||||
serializedBigInts = append(serializedBigInts, val...)
|
||||
}
|
||||
return bFullValue, nil
|
||||
return serializedBigInts, nil
|
||||
}
|
||||
|
||||
// deserializeBigInts deserializes bigints encoded in bytes into a slice
|
||||
// of big.Int values. It iterates over the bytes and extracts
|
||||
// the length of each value and the bytes of the value to build the big.Int
|
||||
// values.
|
||||
func deserializeBigInts(bigints []byte) []*big.Int {
|
||||
values := []*big.Int{}
|
||||
iter := slices.Clone(bigints)
|
||||
func deserializeBigInts(serializedBigInts []byte) []*big.Int {
|
||||
bigints := []*big.Int{}
|
||||
iter := slices.Clone(serializedBigInts)
|
||||
for len(iter) > 0 {
|
||||
lenV := int(iter[0])
|
||||
values = append(values, new(big.Int).SetBytes(iter[1:1+lenV]))
|
||||
bigints = append(bigints, new(big.Int).SetBytes(iter[1:1+lenV]))
|
||||
iter = iter[1+lenV:]
|
||||
}
|
||||
return values
|
||||
return bigints
|
||||
}
|
||||
|
||||
// bigIntsToLeaf converts a big.Int key and a slice of big.Int values into
|
||||
// the bytes of the key, the bytes of the value used to build the tree and the
|
||||
// bytes of the full value encoded
|
||||
func bigIntsToLeaf(hFn HashFunction, keyLen int, key *big.Int, values []*big.Int) (
|
||||
func bigIntsToLeaf(hFn HashFunction, keyLen int, key *big.Int, bigints []*big.Int) (
|
||||
bKey []byte, bValue []byte, serializedBigInts []byte, err error,
|
||||
) {
|
||||
if key == nil {
|
||||
@@ -250,12 +248,12 @@ func bigIntsToLeaf(hFn HashFunction, keyLen int, key *big.Int, values []*big.Int
|
||||
// calculate the bytes of the key
|
||||
bKey = bigIntToLeafKey(key, keyLen)
|
||||
// calculate the bytes of the full values (should be reversible)
|
||||
serializedBigInts, err = serializeBigInts(values)
|
||||
serializedBigInts, err = serializeBigInts(bigints)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
// calculate the value used to build the tree
|
||||
bValue, err = hashBigInts(hFn, values...)
|
||||
bValue, err = hashBigInts(hFn, bigints...)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
@@ -264,9 +262,9 @@ func bigIntsToLeaf(hFn HashFunction, keyLen int, key *big.Int, values []*big.Int
|
||||
|
||||
// hashBigInts hashes the bytes of the big.Int values
|
||||
// using the hash function of the tree. The resulting hash can be used as the leaf value
|
||||
func hashBigInts(hFn HashFunction, values ...*big.Int) ([]byte, error) {
|
||||
chunks := make([][]byte, len(values))
|
||||
for _, v := range values {
|
||||
func hashBigInts(hFn HashFunction, bigints ...*big.Int) ([]byte, error) {
|
||||
chunks := make([][]byte, len(bigints))
|
||||
for _, v := range bigints {
|
||||
value := hFn.SafeBigInt(v)
|
||||
if value == nil {
|
||||
return nil, fmt.Errorf("value cannot be nil")
|
||||
|
||||
Reference in New Issue
Block a user