diff options
author | Michael Muré <batolettre@gmail.com> | 2021-03-14 18:39:04 +0100 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2021-03-14 18:40:50 +0100 |
commit | f1d4a19af81fcc05ae9d90e018ff141f6521335a (patch) | |
tree | 9d82815e93a2d3a0856962249798f8adac81a1a6 /bug/operation.go | |
parent | bd09541752ef4db008500d238762ebe7f2f7be39 (diff) | |
download | git-bug-f1d4a19af81fcc05ae9d90e018ff141f6521335a.tar.gz |
bug: nonce on all operation to prevent id collision
Diffstat (limited to 'bug/operation.go')
-rw-r--r-- | bug/operation.go | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/bug/operation.go b/bug/operation.go index 0423c229..d01f1cc9 100644 --- a/bug/operation.go +++ b/bug/operation.go @@ -1,6 +1,7 @@ package bug import ( + "crypto/rand" "encoding/json" "fmt" "time" @@ -138,6 +139,12 @@ type OpBase struct { // TODO: part of the data model upgrade, this should eventually be a timestamp + lamport UnixTime int64 `json:"timestamp"` Metadata map[string]string `json:"metadata,omitempty"` + + // mandatory random bytes to ensure a better randomness of the data used to later generate the ID + // len(Nonce) should be > 20 and < 64 bytes + // It has no functional purpose and should be ignored. + Nonce []byte `json:"nonce"` + // Not serialized. Store the op's id in memory. id entity.Id // Not serialized. Store the extra metadata in memory, @@ -151,10 +158,20 @@ func newOpBase(opType OperationType, author identity.Interface, unixTime int64) OperationType: opType, Author_: author, UnixTime: unixTime, + Nonce: makeNonce(20), id: entity.UnsetId, } } +func makeNonce(len int) []byte { + result := make([]byte, len) + _, err := rand.Read(result) + if err != nil { + panic(err) + } + return result +} + func (base *OpBase) UnmarshalJSON(data []byte) error { // Compute the Id when loading the op from disk. base.id = entity.DeriveId(data) @@ -164,6 +181,7 @@ func (base *OpBase) UnmarshalJSON(data []byte) error { Author json.RawMessage `json:"author"` UnixTime int64 `json:"timestamp"` Metadata map[string]string `json:"metadata,omitempty"` + Nonce []byte `json:"nonce"` }{} if err := json.Unmarshal(data, &aux); err != nil { @@ -180,6 +198,7 @@ func (base *OpBase) UnmarshalJSON(data []byte) error { base.Author_ = author base.UnixTime = aux.UnixTime base.Metadata = aux.Metadata + base.Nonce = aux.Nonce return nil } @@ -222,6 +241,13 @@ func (base *OpBase) Validate(op Operation, opType OperationType) error { } } + if len(base.Nonce) > 64 { + return fmt.Errorf("nonce is too big") + } + if len(base.Nonce) < 20 { + return fmt.Errorf("nonce is too small") + } + return nil } |