diff --git a/account/account.go b/account/account.go index 99b545f21..db80d3be9 100644 --- a/account/account.go +++ b/account/account.go @@ -25,8 +25,9 @@ import ( "fmt" "io" + "github.com/eris-ltd/eris-db/common/sanity" ptypes "github.com/eris-ltd/eris-db/permission/types" - . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" "github.com/tendermint/go-wire" ) @@ -42,7 +43,7 @@ func SignBytes(chainID string, o Signable) []byte { buf, n, err := new(bytes.Buffer), new(int), new(error) o.WriteSignBytes(chainID, buf, n, err) if *err != nil { - PanicCrisis(err) + sanity.PanicCrisis(err) } return buf.Bytes() diff --git a/account/priv_account.go b/account/priv_account.go index 52c0ab771..fe2b0472a 100644 --- a/account/priv_account.go +++ b/account/priv_account.go @@ -21,8 +21,11 @@ package account import ( + "fmt" + + "github.com/eris-ltd/eris-db/common/sanity" + "github.com/tendermint/ed25519" - . "github.com/tendermint/go-common" "github.com/tendermint/go-crypto" "github.com/tendermint/go-wire" ) @@ -49,7 +52,7 @@ func (pA *PrivAccount) Sign(chainID string, o Signable) crypto.Signature { } func (pA *PrivAccount) String() string { - return Fmt("PrivAccount{%X}", pA.Address) + return fmt.Sprintf("PrivAccount{%X}", pA.Address) } //---------------------------------------- @@ -90,7 +93,7 @@ func GenPrivAccountFromSecret(secret string) *PrivAccount { func GenPrivAccountFromPrivKeyBytes(privKeyBytes []byte) *PrivAccount { if len(privKeyBytes) != 64 { - PanicSanity(Fmt("Expected 64 bytes but got %v", len(privKeyBytes))) + sanity.PanicSanity(fmt.Sprintf("Expected 64 bytes but got %v", len(privKeyBytes))) } var privKeyArray [64]byte copy(privKeyArray[:], privKeyBytes) diff --git a/client/cmd/genesis.go b/client/cmd/genesis.go index ad8d01216..124993792 100644 --- a/client/cmd/genesis.go +++ b/client/cmd/genesis.go @@ -3,6 +3,7 @@ package commands import ( "fmt" + "github.com/eris-ltd/eris-db/common/sanity" "github.com/eris-ltd/eris-db/genesis" "github.com/spf13/cobra" @@ -23,7 +24,7 @@ var GenesisGenCmd = &cobra.Command{ // TODO refactor to not panic genesisFile, err := genesis.GenerateKnown(args[0], AccountsPathFlag, ValidatorsPathFlag) if err != nil { - panic(err) + sanity.PanicSanity(err) } fmt.Println(genesisFile) // may want to save somewhere instead }, diff --git a/cmd/serve.go b/cmd/serve.go index 29319b1fd..972ebae61 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -23,13 +23,13 @@ import ( "path" "syscall" - "github.com/spf13/cobra" - "github.com/eris-ltd/eris-db/core" "github.com/eris-ltd/eris-db/definitions" "github.com/eris-ltd/eris-db/logging" "github.com/eris-ltd/eris-db/logging/lifecycle" "github.com/eris-ltd/eris-db/util" + + "github.com/spf13/cobra" ) const ( diff --git a/common/random/random.go b/common/random/random.go new file mode 100644 index 000000000..c066671fe --- /dev/null +++ b/common/random/random.go @@ -0,0 +1,155 @@ +// 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 . + +package random + +import ( + crand "crypto/rand" + "math/rand" + "time" + + "github.com/eris-ltd/eris-db/common/sanity" +) + +const ( + strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters +) + +func init() { + b := cRandBytes(8) + var seed uint64 + for i := 0; i < 8; i++ { + seed |= uint64(b[i]) + seed <<= 8 + } + rand.Seed(int64(seed)) +} + +// Constructs an alphanumeric string of given length. +func RandStr(length int) string { + chars := []byte{} +MAIN_LOOP: + for { + val := rand.Int63() + for i := 0; i < 10; i++ { + v := int(val & 0x3f) // rightmost 6 bits + if v >= 62 { // only 62 characters in strChars + val >>= 6 + continue + } else { + chars = append(chars, strChars[v]) + if len(chars) == length { + break MAIN_LOOP + } + val >>= 6 + } + } + } + + return string(chars) +} + +func RandUint16() uint16 { + return uint16(rand.Uint32() & (1<<16 - 1)) +} + +func RandUint32() uint32 { + return rand.Uint32() +} + +func RandUint64() uint64 { + return uint64(rand.Uint32())<<32 + uint64(rand.Uint32()) +} + +func RandUint() uint { + return uint(rand.Int()) +} + +func RandInt16() int16 { + return int16(rand.Uint32() & (1<<16 - 1)) +} + +func RandInt32() int32 { + return int32(rand.Uint32()) +} + +func RandInt64() int64 { + return int64(rand.Uint32())<<32 + int64(rand.Uint32()) +} + +func RandInt() int { + return rand.Int() +} + +// Distributed pseudo-exponentially to test for various cases +func RandUint16Exp() uint16 { + bits := rand.Uint32() % 16 + if bits == 0 { + return 0 + } + n := uint16(1 << (bits - 1)) + n += uint16(rand.Int31()) & ((1 << (bits - 1)) - 1) + return n +} + +// Distributed pseudo-exponentially to test for various cases +func RandUint32Exp() uint32 { + bits := rand.Uint32() % 32 + if bits == 0 { + return 0 + } + n := uint32(1 << (bits - 1)) + n += uint32(rand.Int31()) & ((1 << (bits - 1)) - 1) + return n +} + +// Distributed pseudo-exponentially to test for various cases +func RandUint64Exp() uint64 { + bits := rand.Uint32() % 64 + if bits == 0 { + return 0 + } + n := uint64(1 << (bits - 1)) + n += uint64(rand.Int63()) & ((1 << (bits - 1)) - 1) + return n +} + +func RandFloat32() float32 { + return rand.Float32() +} + +func RandTime() time.Time { + return time.Unix(int64(RandUint64Exp()), 0) +} + +func RandBytes(n int) []byte { + bs := make([]byte, n) + for i := 0; i < n; i++ { + bs[i] = byte(rand.Intn(256)) + } + return bs +} + +// NOTE: This relies on the os's random number generator. +// For real security, we should salt that with some seed. +// See github.com/tendermint/go-crypto for a more secure reader. +func cRandBytes(numBytes int) []byte { + b := make([]byte, numBytes) + _, err := crand.Read(b) + if err != nil { + sanity.PanicCrisis(err) + } + return b +} diff --git a/common/sanity/sanity.go b/common/sanity/sanity.go new file mode 100644 index 000000000..264eeb7c7 --- /dev/null +++ b/common/sanity/sanity.go @@ -0,0 +1,49 @@ +// 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 . + +package sanity + +import ( + "fmt" +) + +//-------------------------------------------------------------------------------------------------- +// panic wrappers +// NOTE: [ben] Fail fast and fail hard, these are wrappers that point to code that needs +// to be addressed, but simplify finding them in the code; + +// A panic resulting from a sanity check means there is a programmer error +// and some gaurantee is not satisfied. +func PanicSanity(v interface{}) { + panic(fmt.Sprintf("Paniced on a Sanity Check: %v", v)) +} + +// A panic here means something has gone horribly wrong, in the form of data corruption or +// failure of the operating system. In a correct/healthy system, these should never fire. +// If they do, it's indicative of a much more serious problem. +func PanicCrisis(v interface{}) { + panic(fmt.Sprintf("Paniced on a Crisis: %v", v)) +} + +// Indicates a failure of consensus. Someone was malicious or something has +// gone horribly wrong. These should really boot us into an "emergency-recover" mode +func PanicConsensus(v interface{}) { + panic(fmt.Sprintf("Paniced on a Consensus Failure: %v", v)) +} + +// For those times when we're not sure if we should panic +func PanicQ(v interface{}) { + panic(fmt.Sprintf("Paniced questionably: %v", v)) +} diff --git a/manager/eris-mint/accounts.go b/manager/eris-mint/accounts.go index 58a09b0e7..e3a067623 100644 --- a/manager/eris-mint/accounts.go +++ b/manager/eris-mint/accounts.go @@ -24,12 +24,11 @@ import ( "fmt" "sync" - tendermint_common "github.com/tendermint/go-common" - account "github.com/eris-ltd/eris-db/account" core_types "github.com/eris-ltd/eris-db/core/types" definitions "github.com/eris-ltd/eris-db/definitions" event "github.com/eris-ltd/eris-db/event" + word256 "github.com/eris-ltd/eris-db/word256" ) // NOTE [ben] Compiler check to ensure Accounts successfully implements @@ -119,7 +118,7 @@ func (this *accounts) StorageAt(address, key []byte) (*core_types.StorageItem, storageRoot := account.StorageRoot storageTree := state.LoadStorage(storageRoot) - _, value, _ := storageTree.Get(tendermint_common.LeftPadWord256(key).Bytes()) + _, value, _ := storageTree.Get(word256.LeftPadWord256(key).Bytes()) if value == nil { return &core_types.StorageItem{key, []byte{}}, nil } diff --git a/manager/eris-mint/eris-mint.go b/manager/eris-mint/eris-mint.go index 85c3165b3..de217a030 100644 --- a/manager/eris-mint/eris-mint.go +++ b/manager/eris-mint/eris-mint.go @@ -168,7 +168,7 @@ func (app *ErisMint) Commit() (res tmsp.Result) { // flush events to listeners (XXX: note issue with blocking) app.evc.Flush() - // TODO: [ben] over the tendermint 0.6 TMSP interface we have + // TODO: [ben] over the tendermint 0.6 TMSP interface we have // no access to the block header implemented; // On Tendermint v0.8 load the blockheader into the application // state and remove the fixed 2-"seconds" per block internal clock. diff --git a/manager/eris-mint/evm/native.go b/manager/eris-mint/evm/native.go index 860f99bd2..ed4b4f378 100644 --- a/manager/eris-mint/evm/native.go +++ b/manager/eris-mint/evm/native.go @@ -3,9 +3,9 @@ package vm import ( "crypto/sha256" - "golang.org/x/crypto/ripemd160" + . "github.com/eris-ltd/eris-db/word256" - . "github.com/tendermint/go-common" + "golang.org/x/crypto/ripemd160" ) var registeredNativeContracts = make(map[Word256]NativeContract) diff --git a/manager/eris-mint/evm/snative.go b/manager/eris-mint/evm/snative.go index a40bfbb0f..0c03827ea 100644 --- a/manager/eris-mint/evm/snative.go +++ b/manager/eris-mint/evm/snative.go @@ -4,10 +4,10 @@ import ( "encoding/hex" "fmt" + "github.com/eris-ltd/eris-db/common/sanity" "github.com/eris-ltd/eris-db/manager/eris-mint/evm/sha3" ptypes "github.com/eris-ltd/eris-db/permission/types" - - . "github.com/tendermint/go-common" + . "github.com/eris-ltd/eris-db/word256" ) //------------------------------------------------------------------------------------------------ @@ -155,7 +155,7 @@ func set_global(appState AppState, caller *Account, args []byte, gas *int64) (ou permNum, perm := returnTwoArgs(args) vmAcc := appState.GetAccount(ptypes.GlobalPermissionsAddress256) if vmAcc == nil { - PanicSanity("cant find the global permissions account") + sanity.PanicSanity("cant find the global permissions account") } permN := ptypes.PermFlag(Uint64FromWord256(permNum)) if !ValidPermN(permN) { diff --git a/manager/eris-mint/evm/stack.go b/manager/eris-mint/evm/stack.go index 3f3d727f1..52dc63b2d 100644 --- a/manager/eris-mint/evm/stack.go +++ b/manager/eris-mint/evm/stack.go @@ -3,7 +3,9 @@ package vm import ( "fmt" - . "github.com/tendermint/go-common" + "github.com/eris-ltd/eris-db/common/math/integral" + "github.com/eris-ltd/eris-db/common/sanity" + . "github.com/eris-ltd/eris-db/word256" ) // Not goroutine safe @@ -51,7 +53,7 @@ func (st *Stack) Push(d Word256) { // currently only called after Sha3 func (st *Stack) PushBytes(bz []byte) { if len(bz) != 32 { - PanicSanity("Invalid bytes size: expected 32") + sanity.PanicSanity("Invalid bytes size: expected 32") } st.Push(LeftPadWord256(bz)) } @@ -115,7 +117,7 @@ func (st *Stack) Peek() Word256 { func (st *Stack) Print(n int) { fmt.Println("### stack ###") if st.ptr > 0 { - nn := MinInt(n, st.ptr) + nn := integral.MinInt(n, st.ptr) for j, i := 0, st.ptr-1; i > st.ptr-1-nn; i-- { fmt.Printf("%-3d %X\n", j, st.data[i]) j += 1 diff --git a/manager/eris-mint/evm/test/fake_app_state.go b/manager/eris-mint/evm/test/fake_app_state.go index c27e54256..9b7ac96d9 100644 --- a/manager/eris-mint/evm/test/fake_app_state.go +++ b/manager/eris-mint/evm/test/fake_app_state.go @@ -1,9 +1,11 @@ package vm import ( + "fmt" + . "github.com/eris-ltd/eris-db/manager/eris-mint/evm" "github.com/eris-ltd/eris-db/manager/eris-mint/evm/sha3" - . "github.com/tendermint/go-common" + . "github.com/eris-ltd/eris-db/word256" ) type FakeAppState struct { @@ -23,7 +25,7 @@ func (fas *FakeAppState) UpdateAccount(account *Account) { func (fas *FakeAppState) RemoveAccount(account *Account) { _, ok := fas.accounts[account.Address.String()] if !ok { - panic(Fmt("Invalid account addr: %X", account.Address)) + panic(fmt.Sprintf("Invalid account addr: %X", account.Address)) } else { // Remove account delete(fas.accounts, account.Address.String()) @@ -41,14 +43,14 @@ func (fas *FakeAppState) CreateAccount(creator *Account) *Account { Nonce: 0, } } else { - panic(Fmt("Invalid account addr: %X", addr)) + panic(fmt.Sprintf("Invalid account addr: %X", addr)) } } func (fas *FakeAppState) GetStorage(addr Word256, key Word256) Word256 { _, ok := fas.accounts[addr.String()] if !ok { - panic(Fmt("Invalid account addr: %X", addr)) + panic(fmt.Sprintf("Invalid account addr: %X", addr)) } value, ok := fas.storage[addr.String()+key.String()] @@ -62,7 +64,7 @@ func (fas *FakeAppState) GetStorage(addr Word256, key Word256) Word256 { func (fas *FakeAppState) SetStorage(addr Word256, key Word256, value Word256) { _, ok := fas.accounts[addr.String()] if !ok { - panic(Fmt("Invalid account addr: %X", addr)) + panic(fmt.Sprintf("Invalid account addr: %X", addr)) } fas.storage[addr.String()+key.String()] = value diff --git a/manager/eris-mint/evm/test/log_event_test.go b/manager/eris-mint/evm/test/log_event_test.go index 5f1eb2f46..34c8ae330 100644 --- a/manager/eris-mint/evm/test/log_event_test.go +++ b/manager/eris-mint/evm/test/log_event_test.go @@ -8,7 +8,7 @@ import ( . "github.com/eris-ltd/eris-db/manager/eris-mint/evm" . "github.com/eris-ltd/eris-db/manager/eris-mint/evm/opcodes" "github.com/eris-ltd/eris-db/txs" - . "github.com/tendermint/go-common" + . "github.com/eris-ltd/eris-db/word256" "github.com/tendermint/go-events" ) diff --git a/manager/eris-mint/evm/test/vm_test.go b/manager/eris-mint/evm/test/vm_test.go index 53895c0da..248a4377a 100644 --- a/manager/eris-mint/evm/test/vm_test.go +++ b/manager/eris-mint/evm/test/vm_test.go @@ -14,8 +14,8 @@ import ( . "github.com/eris-ltd/eris-db/manager/eris-mint/evm/opcodes" ptypes "github.com/eris-ltd/eris-db/permission/types" "github.com/eris-ltd/eris-db/txs" + . "github.com/eris-ltd/eris-db/word256" "github.com/stretchr/testify/assert" - . "github.com/tendermint/go-common" "github.com/tendermint/go-events" ) diff --git a/manager/eris-mint/evm/types.go b/manager/eris-mint/evm/types.go index a886546e3..074aa3977 100644 --- a/manager/eris-mint/evm/types.go +++ b/manager/eris-mint/evm/types.go @@ -1,8 +1,10 @@ package vm import ( + "fmt" + ptypes "github.com/eris-ltd/eris-db/permission/types" - . "github.com/tendermint/go-common" + . "github.com/eris-ltd/eris-db/word256" ) const ( @@ -23,7 +25,7 @@ func (acc *Account) String() string { if acc == nil { return "nil-VMAccount" } - return Fmt("VMAccount{%X B:%v C:%X N:%v}", + return fmt.Sprintf("VMAccount{%X B:%v C:%X N:%v}", acc.Address, acc.Balance, acc.Code, acc.Nonce) } diff --git a/manager/eris-mint/evm/vm.go b/manager/eris-mint/evm/vm.go index b44bddfec..46823352d 100644 --- a/manager/eris-mint/evm/vm.go +++ b/manager/eris-mint/evm/vm.go @@ -6,11 +6,14 @@ import ( "fmt" "math/big" + "github.com/eris-ltd/eris-db/common/math/integral" + "github.com/eris-ltd/eris-db/common/sanity" . "github.com/eris-ltd/eris-db/manager/eris-mint/evm/opcodes" "github.com/eris-ltd/eris-db/manager/eris-mint/evm/sha3" ptypes "github.com/eris-ltd/eris-db/permission/types" "github.com/eris-ltd/eris-db/txs" - . "github.com/tendermint/go-common" + . "github.com/eris-ltd/eris-db/word256" + "github.com/tendermint/go-events" ) @@ -94,7 +97,7 @@ func HasPermission(appState AppState, acc *Account, perm ptypes.PermFlag) bool { v, err := acc.Permissions.Base.Get(perm) if _, ok := err.(ptypes.ErrValueNotSet); ok { if appState == nil { - log.Warn(Fmt("\n\n***** Unknown permission %b! ********\n\n", perm)) + log.Warn(fmt.Sprintf("\n\n***** Unknown permission %b! ********\n\n", perm)) return false } return HasPermission(nil, appState.GetAccount(ptypes.GlobalPermissionsAddress256), perm) @@ -141,7 +144,7 @@ func (vm *VM) Call(caller, callee *Account, code, input []byte, value int64, gas err := transfer(callee, caller, value) if err != nil { // data has been corrupted in ram - PanicCrisis("Could not return value to caller") + sanity.PanicCrisis("Could not return value to caller") } } } @@ -940,7 +943,7 @@ func copyslice(src []byte) (dest []byte) { } func rightMostBytes(data []byte, n int) []byte { - size := MinInt(len(data), n) + size := integral.MinInt(len(data), n) offset := len(data) - size return data[offset:] } diff --git a/manager/eris-mint/pipe.go b/manager/eris-mint/pipe.go index 014de6620..153f111fc 100644 --- a/manager/eris-mint/pipe.go +++ b/manager/eris-mint/pipe.go @@ -20,7 +20,6 @@ import ( "bytes" "fmt" - tm_common "github.com/tendermint/go-common" crypto "github.com/tendermint/go-crypto" db "github.com/tendermint/go-db" go_events "github.com/tendermint/go-events" @@ -44,6 +43,7 @@ import ( manager_types "github.com/eris-ltd/eris-db/manager/types" rpc_tm_types "github.com/eris-ltd/eris-db/rpc/tendermint/core/types" "github.com/eris-ltd/eris-db/txs" + "github.com/eris-ltd/eris-db/word256" ) type erisMintPipe struct { @@ -380,7 +380,7 @@ func (pipe *erisMintPipe) GetStorage(address, key []byte) (*rpc_tm_types.ResultG storageTree := state.LoadStorage(storageRoot) _, value, exists := storageTree.Get( - tm_common.LeftPadWord256(key).Bytes()) + word256.LeftPadWord256(key).Bytes()) if !exists { // value == nil { return &rpc_tm_types.ResultGetStorage{key, nil}, nil @@ -422,12 +422,12 @@ func (pipe *erisMintPipe) Call(fromAddress, toAddress, data []byte) (*rpc_tm_typ fromAddress = []byte{} } callee := toVMAccount(outAcc) - caller := &vm.Account{Address: tm_common.LeftPadWord256(fromAddress)} + caller := &vm.Account{Address: word256.LeftPadWord256(fromAddress)} txCache := state.NewTxCache(cache) gasLimit := st.GetGasLimit() params := vm.Params{ BlockHeight: int64(st.LastBlockHeight), - BlockHash: tm_common.LeftPadWord256(st.LastBlockHash), + BlockHash: word256.LeftPadWord256(st.LastBlockHash), BlockTime: st.LastBlockTime.Unix(), GasLimit: gasLimit, } @@ -448,13 +448,13 @@ func (pipe *erisMintPipe) CallCode(fromAddress, code, data []byte) (*rpc_tm_type error) { st := pipe.erisMint.GetState() cache := pipe.erisMint.GetCheckCache() - callee := &vm.Account{Address: tm_common.LeftPadWord256(fromAddress)} - caller := &vm.Account{Address: tm_common.LeftPadWord256(fromAddress)} + callee := &vm.Account{Address: word256.LeftPadWord256(fromAddress)} + caller := &vm.Account{Address: word256.LeftPadWord256(fromAddress)} txCache := state.NewTxCache(cache) gasLimit := st.GetGasLimit() params := vm.Params{ BlockHeight: int64(st.LastBlockHeight), - BlockHash: tm_common.LeftPadWord256(st.LastBlockHash), + BlockHash: word256.LeftPadWord256(st.LastBlockHash), BlockTime: st.LastBlockTime.Unix(), GasLimit: gasLimit, } diff --git a/manager/eris-mint/state/block_cache.go b/manager/eris-mint/state/block_cache.go index 31210114e..672edbef4 100644 --- a/manager/eris-mint/state/block_cache.go +++ b/manager/eris-mint/state/block_cache.go @@ -2,14 +2,16 @@ package state import ( "bytes" + "fmt" "sort" - . "github.com/tendermint/go-common" - dbm "github.com/tendermint/go-db" - "github.com/tendermint/go-merkle" - acm "github.com/eris-ltd/eris-db/account" + "github.com/eris-ltd/eris-db/common/sanity" core_types "github.com/eris-ltd/eris-db/core/types" + . "github.com/eris-ltd/eris-db/word256" + + dbm "github.com/tendermint/go-db" + "github.com/tendermint/go-merkle" ) func makeStorage(db dbm.DB, root []byte) merkle.Tree { @@ -61,7 +63,7 @@ func (cache *BlockCache) UpdateAccount(acc *acm.Account) { addr := acc.Address _, storage, removed, _ := cache.accounts[string(addr)].unpack() if removed { - PanicSanity("UpdateAccount on a removed account") + sanity.PanicSanity("UpdateAccount on a removed account") } cache.accounts[string(addr)] = accountInfo{acc, storage, false, true} } @@ -69,7 +71,7 @@ func (cache *BlockCache) UpdateAccount(acc *acm.Account) { func (cache *BlockCache) RemoveAccount(addr []byte) { _, _, removed, _ := cache.accounts[string(addr)].unpack() if removed { - PanicSanity("RemoveAccount on a removed account") + sanity.PanicSanity("RemoveAccount on a removed account") } cache.accounts[string(addr)] = accountInfo{nil, nil, true, false} } @@ -88,7 +90,7 @@ func (cache *BlockCache) GetStorage(addr Word256, key Word256) (value Word256) { // Get or load storage acc, storage, removed, dirty := cache.accounts[string(addr.Postfix(20))].unpack() if removed { - PanicSanity("GetStorage() on removed account") + sanity.PanicSanity("GetStorage() on removed account") } if acc != nil && storage == nil { storage = makeStorage(cache.db, acc.StorageRoot) @@ -111,7 +113,7 @@ func (cache *BlockCache) GetStorage(addr Word256, key Word256) (value Word256) { func (cache *BlockCache) SetStorage(addr Word256, key Word256, value Word256) { _, _, removed, _ := cache.accounts[string(addr.Postfix(20))].unpack() if removed { - PanicSanity("SetStorage() on a removed account") + sanity.PanicSanity("SetStorage() on a removed account") } cache.storages[Tuple256{addr, key}] = storageInfo{value, true} } @@ -141,7 +143,7 @@ func (cache *BlockCache) UpdateNameRegEntry(entry *core_types.NameRegEntry) { func (cache *BlockCache) RemoveNameRegEntry(name string) { _, removed, _ := cache.names[name].unpack() if removed { - PanicSanity("RemoveNameRegEntry on a removed entry") + sanity.PanicSanity("RemoveNameRegEntry on a removed entry") } cache.names[name] = nameInfo{nil, true, false} } @@ -208,7 +210,7 @@ func (cache *BlockCache) Sync() { if removed { removed := cache.backend.RemoveAccount([]byte(addrStr)) if !removed { - PanicCrisis(Fmt("Could not remove account to be removed: %X", acc.Address)) + sanity.PanicCrisis(fmt.Sprintf("Could not remove account to be removed: %X", acc.Address)) } } else { if acc == nil { @@ -241,7 +243,7 @@ func (cache *BlockCache) Sync() { if removed { removed := cache.backend.RemoveNameRegEntry(nameStr) if !removed { - PanicCrisis(Fmt("Could not remove namereg entry to be removed: %s", nameStr)) + sanity.PanicCrisis(fmt.Sprintf("Could not remove namereg entry to be removed: %s", nameStr)) } } else { if entry == nil { diff --git a/manager/eris-mint/state/common.go b/manager/eris-mint/state/common.go index 783156272..51bf1f9ce 100644 --- a/manager/eris-mint/state/common.go +++ b/manager/eris-mint/state/common.go @@ -3,7 +3,7 @@ package state import ( acm "github.com/eris-ltd/eris-db/account" "github.com/eris-ltd/eris-db/manager/eris-mint/evm" - . "github.com/tendermint/go-common" + . "github.com/eris-ltd/eris-db/word256" ) type AccountGetter interface { diff --git a/manager/eris-mint/state/execution.go b/manager/eris-mint/state/execution.go index 9d9fd85bd..9df40dadf 100644 --- a/manager/eris-mint/state/execution.go +++ b/manager/eris-mint/state/execution.go @@ -5,15 +5,15 @@ import ( "errors" "fmt" - . "github.com/tendermint/go-common" - "github.com/tendermint/go-events" - acm "github.com/eris-ltd/eris-db/account" + "github.com/eris-ltd/eris-db/common/sanity" + core_types "github.com/eris-ltd/eris-db/core/types" "github.com/eris-ltd/eris-db/manager/eris-mint/evm" ptypes "github.com/eris-ltd/eris-db/permission/types" // for GlobalPermissionAddress ... - - core_types "github.com/eris-ltd/eris-db/core/types" "github.com/eris-ltd/eris-db/txs" + . "github.com/eris-ltd/eris-db/word256" + + "github.com/tendermint/go-events" ) // ExecBlock stuff is now taken care of by the consensus engine. @@ -228,7 +228,7 @@ func validateInputs(accounts map[string]*acm.Account, signBytes []byte, ins []*t for _, in := range ins { acc := accounts[string(in.Address)] if acc == nil { - PanicSanity("validateInputs() expects account in accounts") + sanity.PanicSanity("validateInputs() expects account in accounts") } err = validateInput(acc, signBytes, in) if err != nil { @@ -279,10 +279,10 @@ func adjustByInputs(accounts map[string]*acm.Account, ins []*txs.TxInput) { for _, in := range ins { acc := accounts[string(in.Address)] if acc == nil { - PanicSanity("adjustByInputs() expects account in accounts") + sanity.PanicSanity("adjustByInputs() expects account in accounts") } if acc.Balance < in.Amount { - PanicSanity("adjustByInputs() expects sufficient funds") + sanity.PanicSanity("adjustByInputs() expects sufficient funds") } acc.Balance -= in.Amount @@ -294,7 +294,7 @@ func adjustByOutputs(accounts map[string]*acm.Account, outs []*txs.TxOutput) { for _, out := range outs { acc := accounts[string(out.Address)] if acc == nil { - PanicSanity("adjustByOutputs() expects account in accounts") + sanity.PanicSanity("adjustByOutputs() expects account in accounts") } acc.Balance += out.Amount } @@ -368,7 +368,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable // Validate input inAcc = blockCache.GetAccount(tx.Input.Address) if inAcc == nil { - log.Info(Fmt("Can't find in account %X", tx.Input.Address)) + log.Info(fmt.Sprintf("Can't find in account %X", tx.Input.Address)) return txs.ErrTxInvalidAddress } @@ -385,24 +385,24 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable // pubKey should be present in either "inAcc" or "tx.Input" if err := checkInputPubKey(inAcc, tx.Input); err != nil { - log.Info(Fmt("Can't find pubkey for %X", tx.Input.Address)) + log.Info(fmt.Sprintf("Can't find pubkey for %X", tx.Input.Address)) return err } signBytes := acm.SignBytes(_s.ChainID, tx) err := validateInput(inAcc, signBytes, tx.Input) if err != nil { - log.Info(Fmt("validateInput failed on %X: %v", tx.Input.Address, err)) + log.Info(fmt.Sprintf("validateInput failed on %X: %v", tx.Input.Address, err)) return err } if tx.Input.Amount < tx.Fee { - log.Info(Fmt("Sender did not send enough to cover the fee %X", tx.Input.Address)) + log.Info(fmt.Sprintf("Sender did not send enough to cover the fee %X", tx.Input.Address)) return txs.ErrTxInsufficientFunds } if !createContract { // Validate output if len(tx.Address) != 20 { - log.Info(Fmt("Destination address is not 20 bytes %X", tx.Address)) + log.Info(fmt.Sprintf("Destination address is not 20 bytes %X", tx.Address)) return txs.ErrTxInvalidAddress } // check if its a native contract @@ -416,7 +416,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable outAcc = blockCache.GetAccount(tx.Address) } - log.Info(Fmt("Out account: %v", outAcc)) + log.Info(fmt.Sprintf("Out account: %v", outAcc)) // Good! value := tx.Input.Amount - tx.Fee @@ -454,10 +454,10 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable // you have to wait a block to avoid a re-ordering attack // that will take your fees if outAcc == nil { - log.Info(Fmt("%X tries to call %X but it does not exist.", + log.Info(fmt.Sprintf("%X tries to call %X but it does not exist.", inAcc.Address, tx.Address)) } else { - log.Info(Fmt("%X tries to call %X but code is blank.", + log.Info(fmt.Sprintf("%X tries to call %X but code is blank.", inAcc.Address, tx.Address)) } err = txs.ErrTxInvalidAddress @@ -468,14 +468,14 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable if createContract { // We already checked for permission callee = txCache.CreateAccount(caller) - log.Info(Fmt("Created new contract %X", callee.Address)) + log.Info(fmt.Sprintf("Created new contract %X", callee.Address)) code = tx.Data } else { callee = toVMAccount(outAcc) - log.Info(Fmt("Calling contract %X with code %X", callee.Address, callee.Code)) + log.Info(fmt.Sprintf("Calling contract %X with code %X", callee.Address, callee.Code)) code = callee.Code } - log.Info(Fmt("Code for this contract: %X", code)) + log.Info(fmt.Sprintf("Code for this contract: %X", code)) // Run VM call and sync txCache to blockCache. { // Capture scope for goto. @@ -488,7 +488,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable ret, err = vmach.Call(caller, callee, code, tx.Data, value, &gas) if err != nil { // Failure. Charge the gas fee. The 'value' was otherwise not transferred. - log.Info(Fmt("Error on execution: %v", err)) + log.Info(fmt.Sprintf("Error on execution: %v", err)) goto CALL_COMPLETE } @@ -534,7 +534,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable // Validate input inAcc = blockCache.GetAccount(tx.Input.Address) if inAcc == nil { - log.Info(Fmt("Can't find in account %X", tx.Input.Address)) + log.Info(fmt.Sprintf("Can't find in account %X", tx.Input.Address)) return txs.ErrTxInvalidAddress } // check permission @@ -543,18 +543,18 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable } // pubKey should be present in either "inAcc" or "tx.Input" if err := checkInputPubKey(inAcc, tx.Input); err != nil { - log.Info(Fmt("Can't find pubkey for %X", tx.Input.Address)) + log.Info(fmt.Sprintf("Can't find pubkey for %X", tx.Input.Address)) return err } signBytes := acm.SignBytes(_s.ChainID, tx) err := validateInput(inAcc, signBytes, tx.Input) if err != nil { - log.Info(Fmt("validateInput failed on %X: %v", tx.Input.Address, err)) + log.Info(fmt.Sprintf("validateInput failed on %X: %v", tx.Input.Address, err)) return err } // fee is in addition to the amount which is used to determine the TTL if tx.Input.Amount < tx.Fee { - log.Info(Fmt("Sender did not send enough to cover the fee %X", tx.Input.Address)) + log.Info(fmt.Sprintf("Sender did not send enough to cover the fee %X", tx.Input.Address)) return txs.ErrTxInsufficientFunds } @@ -582,7 +582,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable if entry.Expires > lastBlockHeight { // ensure we are owner if bytes.Compare(entry.Owner, tx.Input.Address) != 0 { - log.Info(Fmt("Sender %X is trying to update a name (%s) for which he is not owner", tx.Input.Address, tx.Name)) + log.Info(fmt.Sprintf("Sender %X is trying to update a name (%s) for which he is not owner", tx.Input.Address, tx.Name)) return txs.ErrTxPermissionDenied } } else { @@ -600,7 +600,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable // and changing the data if expired { if expiresIn < txs.MinNameRegistrationPeriod { - return errors.New(Fmt("Names must be registered for at least %d blocks", txs.MinNameRegistrationPeriod)) + return errors.New(fmt.Sprintf("Names must be registered for at least %d blocks", txs.MinNameRegistrationPeriod)) } entry.Expires = lastBlockHeight + expiresIn entry.Owner = tx.Input.Address @@ -612,7 +612,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable credit := oldCredit + value expiresIn = int(credit / costPerBlock) if expiresIn < txs.MinNameRegistrationPeriod { - return errors.New(Fmt("Names must be registered for at least %d blocks", txs.MinNameRegistrationPeriod)) + return errors.New(fmt.Sprintf("Names must be registered for at least %d blocks", txs.MinNameRegistrationPeriod)) } entry.Expires = lastBlockHeight + expiresIn log.Info("Updated namereg entry", "name", entry.Name, "expiresIn", expiresIn, "oldCredit", oldCredit, "value", value, "credit", credit) @@ -622,7 +622,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable } } else { if expiresIn < txs.MinNameRegistrationPeriod { - return errors.New(Fmt("Names must be registered for at least %d blocks", txs.MinNameRegistrationPeriod)) + return errors.New(fmt.Sprintf("Names must be registered for at least %d blocks", txs.MinNameRegistrationPeriod)) } // entry does not exist, so create it entry = &core_types.NameRegEntry{ @@ -834,7 +834,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable // Validate input inAcc = blockCache.GetAccount(tx.Input.Address) if inAcc == nil { - log.Debug(Fmt("Can't find in account %X", tx.Input.Address)) + log.Debug(fmt.Sprintf("Can't find in account %X", tx.Input.Address)) return txs.ErrTxInvalidAddress } @@ -846,13 +846,13 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable // pubKey should be present in either "inAcc" or "tx.Input" if err := checkInputPubKey(inAcc, tx.Input); err != nil { - log.Debug(Fmt("Can't find pubkey for %X", tx.Input.Address)) + log.Debug(fmt.Sprintf("Can't find pubkey for %X", tx.Input.Address)) return err } signBytes := acm.SignBytes(_s.ChainID, tx) err := validateInput(inAcc, signBytes, tx.Input) if err != nil { - log.Debug(Fmt("validateInput failed on %X: %v", tx.Input.Address, err)) + log.Debug(fmt.Sprintf("validateInput failed on %X: %v", tx.Input.Address, err)) return err } @@ -877,7 +877,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable err = permAcc.Permissions.Base.Unset(args.Permission) case *ptypes.SetGlobalArgs: if permAcc = blockCache.GetAccount(ptypes.GlobalPermissionsAddress); permAcc == nil { - PanicSanity("can't find global permissions account") + sanity.PanicSanity("can't find global permissions account") } err = permAcc.Permissions.Base.Set(args.Permission, args.Value) case *ptypes.HasRoleArgs: @@ -897,7 +897,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable return fmt.Errorf("Role (%s) does not exist for account %X", args.Role, args.Address) } default: - PanicSanity(Fmt("invalid permission function: %s", ptypes.PermFlagToString(permFlag))) + sanity.PanicSanity(fmt.Sprintf("invalid permission function: %s", ptypes.PermFlagToString(permFlag))) } // TODO: maybe we want to take funds on error and allow txs in that don't do anythingi? @@ -922,7 +922,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable default: // binary decoding should not let this happen - PanicSanity("Unknown Tx type") + sanity.PanicSanity("Unknown Tx type") return nil } } @@ -932,7 +932,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable // Get permission on an account or fall back to global value func HasPermission(state AccountGetter, acc *acm.Account, perm ptypes.PermFlag) bool { if perm > ptypes.AllPermFlags { - PanicSanity("Checking an unknown permission in state should never happen") + sanity.PanicSanity("Checking an unknown permission in state should never happen") } if acc == nil { @@ -945,14 +945,14 @@ func HasPermission(state AccountGetter, acc *acm.Account, perm ptypes.PermFlag) v, err := acc.Permissions.Base.Get(perm) if _, ok := err.(ptypes.ErrValueNotSet); ok { if state == nil { - PanicSanity("All known global permissions should be set!") + sanity.PanicSanity("All known global permissions should be set!") } log.Info("Permission for account is not set. Querying GlobalPermissionsAddress", "perm", permString) return HasPermission(nil, state.GetAccount(ptypes.GlobalPermissionsAddress), perm) } else if v { - log.Info("Account has permission", "address", Fmt("%X", acc.Address), "perm", permString) + log.Info("Account has permission", "address", fmt.Sprintf("%X", acc.Address), "perm", permString) } else { - log.Info("Account does not have permission", "address", Fmt("%X", acc.Address), "perm", permString) + log.Info("Account does not have permission", "address", fmt.Sprintf("%X", acc.Address), "perm", permString) } return v } @@ -1011,5 +1011,5 @@ type InvalidTxError struct { } func (txErr InvalidTxError) Error() string { - return Fmt("Invalid tx: [%v] reason: [%v]", txErr.Tx, txErr.Reason) + return fmt.Sprintf("Invalid tx: [%v] reason: [%v]", txErr.Tx, txErr.Reason) } diff --git a/manager/eris-mint/state/genesis_test.go b/manager/eris-mint/state/genesis_test.go index 3bc2fdf00..c9305ed4b 100644 --- a/manager/eris-mint/state/genesis_test.go +++ b/manager/eris-mint/state/genesis_test.go @@ -9,10 +9,10 @@ import ( "time" acm "github.com/eris-ltd/eris-db/account" + "github.com/eris-ltd/eris-db/common/random" genesis "github.com/eris-ltd/eris-db/genesis" ptypes "github.com/eris-ltd/eris-db/permission/types" - . "github.com/tendermint/go-common" tdb "github.com/tendermint/go-db" "github.com/tendermint/tendermint/types" ) @@ -108,12 +108,12 @@ func RandAccount(randBalance bool, minBalance int64) (*acm.Account, *acm.PrivAcc acc := &acm.Account{ Address: privAccount.PubKey.Address(), PubKey: privAccount.PubKey, - Sequence: RandInt(), + Sequence: random.RandInt(), Balance: minBalance, Permissions: perms, } if randBalance { - acc.Balance += int64(RandUint32()) + acc.Balance += int64(random.RandUint32()) } return acc, privAccount } diff --git a/manager/eris-mint/state/permissions_test.go b/manager/eris-mint/state/permissions_test.go index 863231364..fd4dd4219 100644 --- a/manager/eris-mint/state/permissions_test.go +++ b/manager/eris-mint/state/permissions_test.go @@ -11,15 +11,14 @@ import ( acm "github.com/eris-ltd/eris-db/account" genesis "github.com/eris-ltd/eris-db/genesis" "github.com/eris-ltd/eris-db/manager/eris-mint/evm" + . "github.com/eris-ltd/eris-db/manager/eris-mint/evm/opcodes" ptypes "github.com/eris-ltd/eris-db/permission/types" "github.com/eris-ltd/eris-db/txs" + . "github.com/eris-ltd/eris-db/word256" - . "github.com/eris-ltd/eris-db/manager/eris-mint/evm/opcodes" - . "github.com/tendermint/go-common" "github.com/tendermint/go-crypto" dbm "github.com/tendermint/go-db" "github.com/tendermint/go-events" - "github.com/tendermint/tendermint/config/tendermint_test" ) @@ -1210,7 +1209,7 @@ func snativePermTestInputCALL(name string, user *acm.PrivAccount, perm ptypes.Pe data = append(permNameToFuncID(name), data...) var err error if pF, err = ptypes.PermStringToFlag(name); err != nil { - panic(Fmt("failed to convert perm string (%s) to flag", name)) + panic(fmt.Sprintf("failed to convert perm string (%s) to flag", name)) } return } @@ -1237,7 +1236,7 @@ func snativeRoleTestInputCALL(name string, user *acm.PrivAccount, role string) ( var err error if pF, err = ptypes.PermStringToFlag(name); err != nil { - panic(Fmt("failed to convert perm string (%s) to flag", name)) + panic(fmt.Sprintf("failed to convert perm string (%s) to flag", name)) } return } diff --git a/manager/eris-mint/state/state_test.go b/manager/eris-mint/state/state_test.go index dd6e07b9b..5af67700f 100644 --- a/manager/eris-mint/state/state_test.go +++ b/manager/eris-mint/state/state_test.go @@ -4,15 +4,13 @@ import ( "bytes" "encoding/hex" "testing" - //"time" - - "github.com/tendermint/go-common" - "github.com/tendermint/tendermint/config/tendermint_test" - // tmtypes "github.com/tendermint/tendermint/types" core_types "github.com/eris-ltd/eris-db/core/types" evm "github.com/eris-ltd/eris-db/manager/eris-mint/evm" "github.com/eris-ltd/eris-db/txs" + "github.com/eris-ltd/eris-db/word256" + + "github.com/tendermint/tendermint/config/tendermint_test" ) func init() { @@ -429,7 +427,7 @@ func TestCreates(t *testing.T) { state.UpdateAccount(newAcc1) state.UpdateAccount(newAcc2) - createData = append(createData, common.LeftPadBytes(acc2.Address, 32)...) + createData = append(createData, word256.LeftPadBytes(acc2.Address, 32)...) // call the pre-factory, triggering the factory to run a create tx := &txs.CallTx{ @@ -452,7 +450,7 @@ func TestCreates(t *testing.T) { acc1 = state.GetAccount(acc1.Address) storage := state.LoadStorage(acc1.StorageRoot) - _, firstCreatedAddress, _ := storage.Get(common.LeftPadBytes([]byte{0}, 32)) + _, firstCreatedAddress, _ := storage.Get(word256.LeftPadBytes([]byte{0}, 32)) acc0 = state.GetAccount(acc0.Address) // call the pre-factory, triggering the factory to run a create @@ -476,7 +474,7 @@ func TestCreates(t *testing.T) { acc1 = state.GetAccount(acc1.Address) storage = state.LoadStorage(acc1.StorageRoot) - _, secondCreatedAddress, _ := storage.Get(common.LeftPadBytes([]byte{0}, 32)) + _, secondCreatedAddress, _ := storage.Get(word256.LeftPadBytes([]byte{0}, 32)) if bytes.Equal(firstCreatedAddress, secondCreatedAddress) { t.Errorf("Multiple contracts created with the same address!") @@ -507,7 +505,7 @@ func TestContractSend(t *testing.T) { newAcc1.Code = callerCode state.UpdateAccount(newAcc1) - sendData = append(sendData, common.LeftPadBytes(acc2.Address, 32)...) + sendData = append(sendData, word256.LeftPadBytes(acc2.Address, 32)...) sendAmt := int64(10) acc2Balance := acc2.Balance diff --git a/manager/eris-mint/state/tx_cache.go b/manager/eris-mint/state/tx_cache.go index 858dc68d7..87ccd9133 100644 --- a/manager/eris-mint/state/tx_cache.go +++ b/manager/eris-mint/state/tx_cache.go @@ -1,12 +1,15 @@ package state import ( + "fmt" + acm "github.com/eris-ltd/eris-db/account" + "github.com/eris-ltd/eris-db/common/sanity" "github.com/eris-ltd/eris-db/manager/eris-mint/evm" ptypes "github.com/eris-ltd/eris-db/permission/types" // for GlobalPermissionAddress ... "github.com/eris-ltd/eris-db/txs" + . "github.com/eris-ltd/eris-db/word256" - . "github.com/tendermint/go-common" "github.com/tendermint/go-crypto" ) @@ -44,7 +47,7 @@ func (cache *TxCache) UpdateAccount(acc *vm.Account) { addr := acc.Address _, removed := cache.accounts[addr].unpack() if removed { - PanicSanity("UpdateAccount on a removed account") + sanity.PanicSanity("UpdateAccount on a removed account") } cache.accounts[addr] = vmAccountInfo{acc, false} } @@ -53,7 +56,7 @@ func (cache *TxCache) RemoveAccount(acc *vm.Account) { addr := acc.Address _, removed := cache.accounts[addr].unpack() if removed { - PanicSanity("RemoveAccount on a removed account") + sanity.PanicSanity("RemoveAccount on a removed account") } cache.accounts[addr] = vmAccountInfo{acc, true} } @@ -85,7 +88,7 @@ func (cache *TxCache) CreateAccount(creator *vm.Account) *vm.Account { return account } else { // either we've messed up nonce handling, or sha3 is broken - PanicSanity(Fmt("Could not create account, address already exists: %X", addr)) + sanity.PanicSanity(fmt.Sprintf("Could not create account, address already exists: %X", addr)) return nil } } @@ -109,7 +112,7 @@ func (cache *TxCache) GetStorage(addr Word256, key Word256) Word256 { func (cache *TxCache) SetStorage(addr Word256, key Word256, value Word256) { _, removed := cache.accounts[addr].unpack() if removed { - PanicSanity("SetStorage() on a removed account") + sanity.PanicSanity("SetStorage() on a removed account") } cache.storages[Tuple256{addr, key}] = value } diff --git a/manager/eris-mint/state/types/genesis.go b/manager/eris-mint/state/types/genesis.go index 806d701b2..90d54cf72 100644 --- a/manager/eris-mint/state/types/genesis.go +++ b/manager/eris-mint/state/types/genesis.go @@ -1,10 +1,12 @@ package types import ( + "fmt" "time" + "github.com/eris-ltd/eris-db/common/sanity" ptypes "github.com/eris-ltd/eris-db/permission/types" - . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" "github.com/tendermint/go-wire" ) @@ -55,7 +57,7 @@ func GenesisDocFromJSON(jsonBlob []byte) (genState *GenesisDoc) { var err error wire.ReadJSONPtr(&genState, jsonBlob, &err) if err != nil { - Exit(Fmt("Couldn't read GenesisDoc: %v", err)) + sanity.PanicCrisis(fmt.Sprintf("Couldn't read GenesisDoc: %v", err)) } return } diff --git a/manager/eris-mint/transactor.go b/manager/eris-mint/transactor.go index 953c519f4..72eddde1e 100644 --- a/manager/eris-mint/transactor.go +++ b/manager/eris-mint/transactor.go @@ -25,16 +25,16 @@ import ( "sync" "time" - cmn "github.com/tendermint/go-common" - "github.com/tendermint/go-crypto" - tEvents "github.com/tendermint/go-events" - "github.com/eris-ltd/eris-db/account" core_types "github.com/eris-ltd/eris-db/core/types" event "github.com/eris-ltd/eris-db/event" "github.com/eris-ltd/eris-db/manager/eris-mint/evm" "github.com/eris-ltd/eris-db/manager/eris-mint/state" "github.com/eris-ltd/eris-db/txs" + "github.com/eris-ltd/eris-db/word256" + + "github.com/tendermint/go-crypto" + tEvents "github.com/tendermint/go-events" ) type transactor struct { @@ -77,12 +77,12 @@ func (this *transactor) Call(fromAddress, toAddress, data []byte) ( fromAddress = []byte{} } callee := toVMAccount(outAcc) - caller := &vm.Account{Address: cmn.LeftPadWord256(fromAddress)} + caller := &vm.Account{Address: word256.LeftPadWord256(fromAddress)} txCache := state.NewTxCache(cache) gasLimit := st.GetGasLimit() params := vm.Params{ BlockHeight: int64(st.LastBlockHeight), - BlockHash: cmn.LeftPadWord256(st.LastBlockHash), + BlockHash: word256.LeftPadWord256(st.LastBlockHash), BlockTime: st.LastBlockTime.Unix(), GasLimit: gasLimit, } @@ -108,14 +108,14 @@ func (this *transactor) CallCode(fromAddress, code, data []byte) ( fromAddress = []byte{} } cache := this.erisMint.GetCheckCache() // XXX: DON'T MUTATE THIS CACHE (used internally for CheckTx) - callee := &vm.Account{Address: cmn.LeftPadWord256(fromAddress)} - caller := &vm.Account{Address: cmn.LeftPadWord256(fromAddress)} + callee := &vm.Account{Address: word256.LeftPadWord256(fromAddress)} + caller := &vm.Account{Address: word256.LeftPadWord256(fromAddress)} txCache := state.NewTxCache(cache) st := this.erisMint.GetState() // for block height, time gasLimit := st.GetGasLimit() params := vm.Params{ BlockHeight: int64(st.LastBlockHeight), - BlockHash: cmn.LeftPadWord256(st.LastBlockHash), + BlockHash: word256.LeftPadWord256(st.LastBlockHash), BlockTime: st.LastBlockTime.Unix(), GasLimit: gasLimit, } @@ -424,7 +424,7 @@ func (this *transactor) SignTx(tx txs.Tx, privAccounts []*account.PrivAccount) ( // No idea what this does. func toVMAccount(acc *account.Account) *vm.Account { return &vm.Account{ - Address: cmn.LeftPadWord256(acc.Address), + Address: word256.LeftPadWord256(acc.Address), Balance: acc.Balance, Code: acc.Code, Nonce: int64(acc.Sequence), diff --git a/permission/types/permissions.go b/permission/types/permissions.go index 5cdcdaf8c..15706c9f8 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 57315ac93..a1a2b0848 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 . + 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/rpc/tendermint/test/rpc_client_test.go b/rpc/tendermint/test/rpc_client_test.go index 7183f2df8..228fc58e3 100644 --- a/rpc/tendermint/test/rpc_client_test.go +++ b/rpc/tendermint/test/rpc_client_test.go @@ -6,17 +6,16 @@ package test import ( "bytes" "fmt" - "testing" - "golang.org/x/crypto/ripemd160" - + "testing" "time" consensus_types "github.com/eris-ltd/eris-db/consensus/types" edbcli "github.com/eris-ltd/eris-db/rpc/tendermint/client" "github.com/eris-ltd/eris-db/txs" + "github.com/eris-ltd/eris-db/word256" + "github.com/stretchr/testify/assert" - tm_common "github.com/tendermint/go-common" rpcclient "github.com/tendermint/go-rpc/client" _ "github.com/tendermint/tendermint/config/tendermint_test" ) @@ -123,8 +122,8 @@ func TestGetStorage(t *testing.T) { " created a contract but the contract address is empty") v := getStorage(t, client, contractAddr, []byte{0x1}) - got := tm_common.LeftPadWord256(v) - expected := tm_common.LeftPadWord256([]byte{0x5}) + got := word256.LeftPadWord256(v) + expected := word256.LeftPadWord256([]byte{0x5}) if got.Compare(expected) != 0 { t.Fatalf("Wrong storage value. Got %x, expected %x", got.Bytes(), expected.Bytes()) @@ -148,8 +147,8 @@ func TestCallCode(t *testing.T) { // pass two ints as calldata, add, and return the result code = []byte{0x60, 0x0, 0x35, 0x60, 0x20, 0x35, 0x1, 0x60, 0x0, 0x52, 0x60, 0x20, 0x60, 0x0, 0xf3} - data = append(tm_common.LeftPadWord256([]byte{0x5}).Bytes(), - tm_common.LeftPadWord256([]byte{0x6}).Bytes()...) + data = append(word256.LeftPadWord256([]byte{0x5}).Bytes(), + word256.LeftPadWord256([]byte{0x6}).Bytes()...) expected = []byte{0xb} callCode(t, client, user[0].PubKey.Address(), code, data, expected) }) diff --git a/rpc/tendermint/test/shared.go b/rpc/tendermint/test/shared.go index 8c01b6a2f..a3d0310cc 100644 --- a/rpc/tendermint/test/shared.go +++ b/rpc/tendermint/test/shared.go @@ -3,28 +3,26 @@ package test import ( "bytes" "hash/fnv" + "path" "strconv" "testing" acm "github.com/eris-ltd/eris-db/account" "github.com/eris-ltd/eris-db/core" core_types "github.com/eris-ltd/eris-db/core/types" + "github.com/eris-ltd/eris-db/logging/lifecycle" edbcli "github.com/eris-ltd/eris-db/rpc/tendermint/client" rpc_core "github.com/eris-ltd/eris-db/rpc/tendermint/core" rpc_types "github.com/eris-ltd/eris-db/rpc/tendermint/core/types" "github.com/eris-ltd/eris-db/server" "github.com/eris-ltd/eris-db/test/fixtures" "github.com/eris-ltd/eris-db/txs" + "github.com/eris-ltd/eris-db/word256" - "github.com/tendermint/go-crypto" - rpcclient "github.com/tendermint/go-rpc/client" - - "path" - - "github.com/eris-ltd/eris-db/logging/lifecycle" state_types "github.com/eris-ltd/eris-db/manager/eris-mint/state/types" "github.com/spf13/viper" - tm_common "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" + rpcclient "github.com/tendermint/go-rpc/client" "github.com/tendermint/tendermint/types" ) @@ -242,7 +240,7 @@ func callCode(t *testing.T, client rpcclient.Client, fromAddress, code, data, } ret := resp.Return // NOTE: we don't flip memory when it comes out of RETURN (?!) - if bytes.Compare(ret, tm_common.LeftPadWord256(expected).Bytes()) != 0 { + if bytes.Compare(ret, word256.LeftPadWord256(expected).Bytes()) != 0 { t.Fatalf("Conflicting return value. Got %x, expected %x", ret, expected) } } @@ -255,7 +253,7 @@ func callContract(t *testing.T, client rpcclient.Client, fromAddress, toAddress, } ret := resp.Return // NOTE: we don't flip memory when it comes out of RETURN (?!) - if bytes.Compare(ret, tm_common.LeftPadWord256(expected).Bytes()) != 0 { + if bytes.Compare(ret, word256.LeftPadWord256(expected).Bytes()) != 0 { t.Fatalf("Conflicting return value. Got %x, expected %x", ret, expected) } } @@ -294,14 +292,14 @@ func simpleContract() ([]byte, []byte, []byte) { // push code to the stack //code := append([]byte{byte(0x60 + lenCode - 1)}, RightPadWord256(contractCode).Bytes()...) code := append([]byte{0x7f}, - tm_common.RightPadWord256(contractCode).Bytes()...) + word256.RightPadWord256(contractCode).Bytes()...) // store it in memory code = append(code, []byte{0x60, 0x0, 0x52}...) // return whats in memory //code = append(code, []byte{0x60, byte(32 - lenCode), 0x60, byte(lenCode), 0xf3}...) code = append(code, []byte{0x60, byte(lenCode), 0x60, 0x0, 0xf3}...) // return init code, contract code, expected return - return code, contractCode, tm_common.LeftPadBytes([]byte{0xb}, 32) + return code, contractCode, word256.LeftPadBytes([]byte{0xb}, 32) } // simple call contract calls another contract @@ -329,5 +327,5 @@ func simpleCallContract(addr []byte) ([]byte, []byte, []byte) { code = append(code, []byte{0x60, byte(lenCode), 0x60, 0x0, 0xf3}...) code = append(code, contractCode...) // return init code, contract code, expected return - return code, contractCode, tm_common.LeftPadBytes([]byte{0xb}, 32) + return code, contractCode, word256.LeftPadBytes([]byte{0xb}, 32) } diff --git a/txs/events.go b/txs/events.go index 4cb7e656c..3dc93e0f8 100644 --- a/txs/events.go +++ b/txs/events.go @@ -4,9 +4,9 @@ import ( "fmt" "time" - . "github.com/tendermint/go-common" - "github.com/tendermint/go-wire" + . "github.com/eris-ltd/eris-db/word256" + "github.com/tendermint/go-wire" tm_types "github.com/tendermint/tendermint/types" // Block ) diff --git a/word256/byteslice.go b/word256/byteslice.go new file mode 100644 index 000000000..3c391042f --- /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 . + +// 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 000000000..09232fd67 --- /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 . + +// 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 000000000..2537830eb --- /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 . + +// 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) }