mit-dci / utreexo

accumulator for bitcoin utxo set
MIT License
323 stars 60 forks source link

Add tests for pollard serialize and deserialize #295

Closed kcalvinalvin closed 3 years ago

kcalvinalvin commented 3 years ago

https://github.com/mit-dci/utreexo/blob/7d436ce11280c3f0e2fd7b4f56e43d012125b811/accumulator/pollardutil.go#L141-L188

We're currently lacking test for pollard serialize and deserialize. It'd be good to add tests for these so that we don't break things in the future.

We already have tests were we generate pollard to run other tests on (notably TestPollardRand() in pollard_test.go).

To test if serialize and deserialize indeed works how we expect them to, we can:

  1. Serialize a pollard object
  2. Save the bytes of this serialization
  3. Deserialize into a pollard object
  4. Re-serialize the pollard object into byte
  5. Use bytes.Compare() to see if the byte serializations are equal
DiptoChakrabarty commented 3 years ago

I get the general idea what to do , however how can I generate a random pollard object . The TestPollardRand tests the generation of pollard using the pollardRandomRemember function in the pollard_test.go

Should the testing for the serialisation and de-serialisation go into the pollardRandomRemember function at the end (as a pollard is generated there) . If the bytes comparison at the step 5 as mentioned above is verified the return nil else return error since return type is error.

kcalvinalvin commented 3 years ago

Should the testing for the serialisation and de-serialisation go into the pollardRandomRemember function at the end (as a pollard is generated there) . If the bytes comparison at the step 5 as mentioned above is verified the return nil else return error since return type is error.

We can do that too. It'd be clearer if the serialization was separated out into its own test though. We also don't need other components of pollardRandomRemember so it'd be good to leave them out to keep the test speeds quick.

Generating a pollard isn't hard to do. We just have to add a slice of Leaf to a pollard object.

A new pollard object can be created in-memory just with a declaration: var pollard Pollard or pollard := new(Pollard).

Then we need a slice of Leaf ([]Leaf) to add to the pollard. https://github.com/mit-dci/utreexo/blob/7d436ce11280c3f0e2fd7b4f56e43d012125b811/accumulator/types.go#L51-L56

Leaf is just a Hash and a bool. Hash is just [32]byte. So we can create a leaf with something like

l := Leaf{
    // Generate some [32]byte slice. We can hash []byte{1} or anything else here.
    Hash: sha512.Sum512_256([]byte{1}),
    // Doesn't matter if it's really just true or false.
    Remember: true,
}

We generate a bunch of these Leaf and make a slice of them.

Then we can just add a slice of Leafs with pollard.add(leafslice). Volia! We now have a pollard we can serialize and deserialize.