From 55ba5427909ae9efefcf37180ccc2876ed659a3a Mon Sep 17 00:00:00 2001 From: Benjamin Bollen <ben@monax.io> Date: Wed, 15 Feb 2017 18:50:44 +0100 Subject: [PATCH] word256: pull tendermint/go-common relating to word256 into eris-db for permissions and eris-mint (TODO) --- permission/types/permissions.go | 12 ++-- permission/types/snatives.go | 19 ++++++ word256/byteslice.go | 62 ++++++++++++++++++ word256/int.go | 75 +++++++++++++++++++++ word256/word.go | 111 ++++++++++++++++++++++++++++++++ 5 files changed, 273 insertions(+), 6 deletions(-) create mode 100644 word256/byteslice.go create mode 100644 word256/int.go create mode 100644 word256/word.go diff --git a/permission/types/permissions.go b/permission/types/permissions.go index 5cdcdaf8..15706c9f 100644 --- a/permission/types/permissions.go +++ b/permission/types/permissions.go @@ -3,14 +3,14 @@ package types import ( "fmt" - . "github.com/tendermint/go-common" + "github.com/eris-ltd/eris-db/word256" ) //------------------------------------------------------------------------------------------------ var ( - GlobalPermissionsAddress = Zero256[:20] - GlobalPermissionsAddress256 = Zero256 + GlobalPermissionsAddress = word256.Zero256[:20] + GlobalPermissionsAddress256 = word256.Zero256 ) // A particular permission @@ -125,7 +125,7 @@ type AccountPermissions struct { // Returns true if the role is found func (aP *AccountPermissions) HasRole(role string) bool { - role = string(RightPadBytes([]byte(role), 32)) + role = string(word256.RightPadBytes([]byte(role), 32)) for _, r := range aP.Roles { if r == role { return true @@ -136,7 +136,7 @@ func (aP *AccountPermissions) HasRole(role string) bool { // Returns true if the role is added, and false if it already exists func (aP *AccountPermissions) AddRole(role string) bool { - role = string(RightPadBytes([]byte(role), 32)) + role = string(word256.RightPadBytes([]byte(role), 32)) for _, r := range aP.Roles { if r == role { return false @@ -148,7 +148,7 @@ func (aP *AccountPermissions) AddRole(role string) bool { // Returns true if the role is removed, and false if it is not found func (aP *AccountPermissions) RmRole(role string) bool { - role = string(RightPadBytes([]byte(role), 32)) + role = string(word256.RightPadBytes([]byte(role), 32)) for i, r := range aP.Roles { if r == role { post := []string{} diff --git a/permission/types/snatives.go b/permission/types/snatives.go index 57315ac9..a1a2b084 100644 --- a/permission/types/snatives.go +++ b/permission/types/snatives.go @@ -1,3 +1,18 @@ +// Copyright 2015-2017 Monax Industries Limited. +// This file is part of the Monax platform (Monax) + +// Monax is free software: you can use, redistribute it and/or modify +// it only under the terms of the GNU General Public License, version +// 3, as published by the Free Software Foundation. + +// Monax is distributed WITHOUT ANY WARRANTY pursuant to +// the terms of the Gnu General Public Licence, version 3, including +// (but not limited to) Clause 15 thereof. See the text of the +// GNU General Public License, version 3 for full terms. + +// You should have received a copy of the GNU General Public License, +// version 3, with Monax. If not, see <http://www.gnu.org/licenses/>. + package types import ( @@ -25,6 +40,10 @@ const ( PermArgsTypeRmRole = byte(0x07) ) +// TODO: [ben] this registration needs to be lifted up +// and centralised in core; here it pulls in go-wire dependency +// while it suffices to have the type bytes defined; +// --- // for wire.readReflect var _ = wire.RegisterInterface( struct{ PermArgs }{}, diff --git a/word256/byteslice.go b/word256/byteslice.go new file mode 100644 index 00000000..3c391042 --- /dev/null +++ b/word256/byteslice.go @@ -0,0 +1,62 @@ +// Copyright 2015-2017 Monax Industries Limited. +// This file is part of the Monax platform (Monax) + +// Monax is free software: you can use, redistribute it and/or modify +// it only under the terms of the GNU General Public License, version +// 3, as published by the Free Software Foundation. + +// Monax is distributed WITHOUT ANY WARRANTY pursuant to +// the terms of the Gnu General Public Licence, version 3, including +// (but not limited to) Clause 15 thereof. See the text of the +// GNU General Public License, version 3 for full terms. + +// You should have received a copy of the GNU General Public License, +// version 3, with Monax. If not, see <http://www.gnu.org/licenses/>. + +// TODO: [ben] this is not specific for word256, but it is used exclusively +// for word256 (and for word160* 20byte addresses) so consider stronger typing. + +package word256 + +import ( + "bytes" +) + +func Fingerprint(slice []byte) []byte { + fingerprint := make([]byte, 6) + copy(fingerprint, slice) + return fingerprint +} + +func IsZeros(slice []byte) bool { + for _, byt := range slice { + if byt != byte(0) { + return false + } + } + return true +} + +func RightPadBytes(slice []byte, l int) []byte { + if l < len(slice) { + return slice + } + padded := make([]byte, l) + copy(padded[0:len(slice)], slice) + return padded +} + +func LeftPadBytes(slice []byte, l int) []byte { + if l < len(slice) { + return slice + } + padded := make([]byte, l) + copy(padded[l-len(slice):], slice) + return padded +} + +func TrimmedString(b []byte) string { + trimSet := string([]byte{0}) + return string(bytes.TrimLeft(b, trimSet)) + +} diff --git a/word256/int.go b/word256/int.go new file mode 100644 index 00000000..09232fd6 --- /dev/null +++ b/word256/int.go @@ -0,0 +1,75 @@ +// Copyright 2015-2017 Monax Industries Limited. +// This file is part of the Monax platform (Monax) + +// Monax is free software: you can use, redistribute it and/or modify +// it only under the terms of the GNU General Public License, version +// 3, as published by the Free Software Foundation. + +// Monax is distributed WITHOUT ANY WARRANTY pursuant to +// the terms of the Gnu General Public Licence, version 3, including +// (but not limited to) Clause 15 thereof. See the text of the +// GNU General Public License, version 3 for full terms. + +// You should have received a copy of the GNU General Public License, +// version 3, with Monax. If not, see <http://www.gnu.org/licenses/>. + +// NOTE: [ben] this used to be in tendermint/go-common but should be +// isolated and cleaned up and tested. Should be used in permissions +// and manager/eris-mint +// TODO: [ben] cleanup, but also write unit-tests + +package word256 + +import ( + "encoding/binary" + "sort" +) + +// Sort for []uint64 + +type Uint64Slice []uint64 + +func (p Uint64Slice) Len() int { return len(p) } +func (p Uint64Slice) Less(i, j int) bool { return p[i] < p[j] } +func (p Uint64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } +func (p Uint64Slice) Sort() { sort.Sort(p) } + +func SearchUint64s(a []uint64, x uint64) int { + return sort.Search(len(a), func(i int) bool { return a[i] >= x }) +} + +func (p Uint64Slice) Search(x uint64) int { return SearchUint64s(p, x) } + +//-------------------------------------------------------------------------------- + +func PutUint64LE(dest []byte, i uint64) { + binary.LittleEndian.PutUint64(dest, i) +} + +func GetUint64LE(src []byte) uint64 { + return binary.LittleEndian.Uint64(src) +} + +func PutUint64BE(dest []byte, i uint64) { + binary.BigEndian.PutUint64(dest, i) +} + +func GetUint64BE(src []byte) uint64 { + return binary.BigEndian.Uint64(src) +} + +func PutInt64LE(dest []byte, i int64) { + binary.LittleEndian.PutUint64(dest, uint64(i)) +} + +func GetInt64LE(src []byte) int64 { + return int64(binary.LittleEndian.Uint64(src)) +} + +func PutInt64BE(dest []byte, i int64) { + binary.BigEndian.PutUint64(dest, uint64(i)) +} + +func GetInt64BE(src []byte) int64 { + return int64(binary.BigEndian.Uint64(src)) +} diff --git a/word256/word.go b/word256/word.go new file mode 100644 index 00000000..2537830e --- /dev/null +++ b/word256/word.go @@ -0,0 +1,111 @@ +// Copyright 2015-2017 Monax Industries Limited. +// This file is part of the Monax platform (Monax) + +// Monax is free software: you can use, redistribute it and/or modify +// it only under the terms of the GNU General Public License, version +// 3, as published by the Free Software Foundation. + +// Monax is distributed WITHOUT ANY WARRANTY pursuant to +// the terms of the Gnu General Public Licence, version 3, including +// (but not limited to) Clause 15 thereof. See the text of the +// GNU General Public License, version 3 for full terms. + +// You should have received a copy of the GNU General Public License, +// version 3, with Monax. If not, see <http://www.gnu.org/licenses/>. + +// NOTE: [ben] this used to be in tendermint/go-common but should be +// isolated and cleaned up and tested. Should be used in permissions +// and manager/eris-mint +// TODO: [ben] cleanup, but also write unit-tests + +package word256 + +import ( + "bytes" + "sort" +) + +var ( + Zero256 = Word256{0} + One256 = Word256{1} +) + +type Word256 [32]byte + +func (w Word256) String() string { return string(w[:]) } +func (w Word256) TrimmedString() string { return TrimmedString(w.Bytes()) } +func (w Word256) Copy() Word256 { return w } +func (w Word256) Bytes() []byte { return w[:] } // copied. +func (w Word256) Prefix(n int) []byte { return w[:n] } +func (w Word256) Postfix(n int) []byte { return w[32-n:] } +func (w Word256) IsZero() bool { + accum := byte(0) + for _, byt := range w { + accum |= byt + } + return accum == 0 +} +func (w Word256) Compare(other Word256) int { + return bytes.Compare(w[:], other[:]) +} + +func Uint64ToWord256(i uint64) Word256 { + buf := [8]byte{} + PutUint64BE(buf[:], i) + return LeftPadWord256(buf[:]) +} + +func Int64ToWord256(i int64) Word256 { + buf := [8]byte{} + PutInt64BE(buf[:], i) + return LeftPadWord256(buf[:]) +} + +func RightPadWord256(bz []byte) (word Word256) { + copy(word[:], bz) + return +} + +func LeftPadWord256(bz []byte) (word Word256) { + copy(word[32-len(bz):], bz) + return +} + +func Uint64FromWord256(word Word256) uint64 { + buf := word.Postfix(8) + return GetUint64BE(buf) +} + +func Int64FromWord256(word Word256) int64 { + buf := word.Postfix(8) + return GetInt64BE(buf) +} + +//------------------------------------- + +type Tuple256 struct { + First Word256 + Second Word256 +} + +func (tuple Tuple256) Compare(other Tuple256) int { + firstCompare := tuple.First.Compare(other.First) + if firstCompare == 0 { + return tuple.Second.Compare(other.Second) + } else { + return firstCompare + } +} + +func Tuple256Split(t Tuple256) (Word256, Word256) { + return t.First, t.Second +} + +type Tuple256Slice []Tuple256 + +func (p Tuple256Slice) Len() int { return len(p) } +func (p Tuple256Slice) Less(i, j int) bool { + return p[i].Compare(p[j]) < 0 +} +func (p Tuple256Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } +func (p Tuple256Slice) Sort() { sort.Sort(p) } -- GitLab