Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move a constant down the call stack. #2493

Merged
merged 1 commit into from
May 19, 2021
Merged

Move a constant down the call stack. #2493

merged 1 commit into from
May 19, 2021

Conversation

pphaneuf
Copy link
Contributor

@pphaneuf pphaneuf commented May 17, 2021

Part of #2378 and #2245.

Checklist

@pphaneuf pphaneuf marked this pull request as ready for review May 17, 2021 10:48
@pphaneuf pphaneuf requested a review from a team as a code owner May 17, 2021 10:48
@Martin2112
Copy link
Contributor

I don't think that this support should have been removed. It has nothing to do with the signature stuff you were working on.

@pphaneuf
Copy link
Contributor Author

It's already all gone from the API, and is currently hardcoded, just at a higher level:

sequencer := NewSequencer(rfc6962.DefaultHasher, info.TimeSource, s.registry.LogStorage, s.registry.MetricFactory, s.registry.QuotaManager)

@Martin2112
Copy link
Contributor

I know. I didn't get to review that PR so didn't get a chance to raise an issue about it.

@pphaneuf
Copy link
Contributor Author

This was really more of a continuation of the removal of the map code (all the other hashing schemes still there were map-specific, so had been removed already), and removing unused RPCs and fields in RPC request/response protobufs (once there was just one hashing scheme, nothing set this field anymore).

@pphaneuf pphaneuf changed the title Hardcode the only supported hashing scheme (RFC6962). Move a constant down the call stack. May 18, 2021
@pphaneuf
Copy link
Contributor Author

Are we good with this? This is a very mechanical change, it should be easy to validate that it has no effect other than reducing complexity.

@pphaneuf pphaneuf requested a review from Martin2112 May 19, 2021 11:44
@pphaneuf pphaneuf merged commit 21acd35 into google:master May 19, 2021
@pphaneuf pphaneuf deleted the only_rfc6962 branch May 19, 2021 12:03
@pav-kv
Copy link
Contributor

pav-kv commented May 19, 2021

I have a mixed feeling about this PR.

  • I like the idea of reducing the usage of LogHasher interface, as in Go it's generally better to define interfaces where they are used. For example, here I could imagine a sequencer's own interface with only those methods that it uses: HashChildren and EmptyRoot.
  • As a further improvement, I find the EmptyRoot method unnecessary, esp. storing its result in the storage, esp. now that it's not signed. It can be easily handled by upper layers (CTFE), as it's just a constant specific to RFC.
  • So, ideally, the sequencer would only have a HashChildren callback as input, similarly to compact.Range.

Hard-coding the RFC hasher seems a bit too much to me, I would keep it slightly more abstract. It's sometimes convenient for testing to provide a custom "human-readable" hasher, e.g. we have something like this internally:

// nodeHash returns a test "hash" for the given tree node. It looks like
// treeID:[begin,end) where [begin,end) is the leaves range under this node.
func nodeHash(treeID int64, id compact.NodeID) []byte {
	begin, end := id.Index<<id.Level, (id.Index+1)<<id.Level
	return []byte(fmt.Sprintf("%d:[%d,%d)", treeID, begin, end))
}

// glueChildren is a test "hash" that simply concatenates parts of two child
// hashes in such a way that the result corresponds to the string that nodeHash
// function would generate for their parent node.
func glueChildren(left, right []byte) []byte {
	l := bytes.IndexByte(left, ',')
	r := bytes.IndexByte(right, ',')
	return append(append([]byte{}, left[:l]...), right[r:]...)
}

We don't use it here, but I can easily see how it could be used (instead / in addition to "golden" tests with long unreadable hashes).

@pphaneuf
Copy link
Contributor Author

This commit message was initially poorly formulated, and has been updated.

This does not reduce the usage of the LogHasher interface (even though I also agree that it would be a good idea), it only moves a constant down one level. The RFC hasher was already hard-coded, and in practice, there will not be any other hashing scheme until we leave SHA256, which we should apply the YAGNI principle to, and only do it when we do it.

The EmptyRoot method is rather baked into the Trillian principle of a "hashing algorithm", by which we really mean the combination of a hashing algorithm such as SHA256, along with a set of higher-level algorithms around how it is used, which in the case of Trillian as it currently stands, involves what the root hash of an empty tree is supposed to be like, as well as how child hashes are combined and the exact prefix scheme used to protect against 2nd pre-image attacks.

I agree that the particular aspect of dealing with empty trees should probably not be handled by Trillian, but this is a much bigger change, which I am not currently proposing, and should probably not happen with Trillian in its current form (of an out-of-process RPC server), but incorporated into the "next generation" (which is more likely to be packaged as an in-process library).

But all of this is far beyond the scope of this PR, which merely applies constant folding in order to reduce the complexity and the cognitive load for people reading this code. I would gladly review PRs to move towards what you are proposing, though!

@NatalieDoduc
Copy link
Contributor

Good point, Pavel, on potential improvements and the custom hasher for testing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants