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) }