aboutsummaryrefslogtreecommitdiffstats
path: root/state
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2015-03-13 23:29:04 +0800
committerobscuren <geffobscura@gmail.com>2015-03-13 23:29:04 +0800
commitf1fcda4f2fe05e46e3d350cb89a52fd33df3767f (patch)
tree3e714df981ccdaedabad2ebb8f684c8889a1c544 /state
parentcda88ce31a45af001443c71fb16bdb2bbe1efbc7 (diff)
downloadgo-tangerine-f1fcda4f2fe05e46e3d350cb89a52fd33df3767f.tar.gz
go-tangerine-f1fcda4f2fe05e46e3d350cb89a52fd33df3767f.tar.zst
go-tangerine-f1fcda4f2fe05e46e3d350cb89a52fd33df3767f.zip
Implemented managed state
* Reimplemented nonce management for known accounts.
Diffstat (limited to 'state')
-rw-r--r--state/managed_state.go50
-rw-r--r--state/managed_state_test.go54
2 files changed, 86 insertions, 18 deletions
diff --git a/state/managed_state.go b/state/managed_state.go
index b0a129af0..1914e977a 100644
--- a/state/managed_state.go
+++ b/state/managed_state.go
@@ -2,44 +2,53 @@ package state
import "sync"
+type account struct {
+ stateObject *StateObject
+ nstart uint64
+ nonces []bool
+}
+
type ManagedState struct {
*StateDB
mu sync.RWMutex
- accounts map[string]*StateObject
+ accounts map[string]*account
}
func ManageState(statedb *StateDB) *ManagedState {
return &ManagedState{
StateDB: statedb,
- accounts: make(map[string]*StateObject),
+ accounts: make(map[string]*account),
}
}
-func (ms *ManagedState) IncrementNonce(addr []byte) {
- ms.mu.Lock()
- defer ms.mu.Unlock()
-
- ms.getAccount(addr).nonce++
-}
-
-func (ms *ManagedState) DecrementNonce(addr []byte) {
- // Decrementing a nonce does not mean we are interested in the account
- // incrementing only happens if you control the account, therefor
- // incrementing behaves differently from decrementing
+func (ms *ManagedState) RemoveNonce(addr []byte, n uint64) {
if ms.hasAccount(addr) {
ms.mu.Lock()
defer ms.mu.Unlock()
- ms.getAccount(addr).nonce--
+ account := ms.getAccount(addr)
+ if n-account.nstart < uint64(len(account.nonces)) {
+ reslice := make([]bool, n-account.nstart)
+ copy(reslice, account.nonces[:n-account.nstart])
+ account.nonces = reslice
+ }
}
}
-func (ms *ManagedState) GetNonce(addr []byte) uint64 {
+func (ms *ManagedState) NewNonce(addr []byte) uint64 {
ms.mu.RLock()
defer ms.mu.RUnlock()
- return ms.getAccount(addr).nonce
+
+ account := ms.getAccount(addr)
+ for i, nonce := range account.nonces {
+ if !nonce {
+ return account.nstart + uint64(i)
+ }
+ }
+ account.nonces = append(account.nonces, false)
+ return uint64(len(account.nonces)) + account.nstart
}
func (ms *ManagedState) hasAccount(addr []byte) bool {
@@ -47,10 +56,15 @@ func (ms *ManagedState) hasAccount(addr []byte) bool {
return ok
}
-func (ms *ManagedState) getAccount(addr []byte) *StateObject {
+func (ms *ManagedState) getAccount(addr []byte) *account {
if _, ok := ms.accounts[string(addr)]; !ok {
- ms.accounts[string(addr)] = ms.GetOrNewStateObject(addr)
+ so := ms.GetOrNewStateObject(addr)
+ ms.accounts[string(addr)] = newAccount(so)
}
return ms.accounts[string(addr)]
}
+
+func newAccount(so *StateObject) *account {
+ return &account{so, so.nonce - 1, nil}
+}
diff --git a/state/managed_state_test.go b/state/managed_state_test.go
new file mode 100644
index 000000000..ae374f728
--- /dev/null
+++ b/state/managed_state_test.go
@@ -0,0 +1,54 @@
+package state
+
+import "testing"
+
+var addr = []byte("test")
+
+func create() (*ManagedState, *account) {
+ ms := ManageState(nil)
+ ms.accounts[string(addr)] = newAccount(&StateObject{nonce: 100})
+
+ return ms, ms.accounts[string(addr)]
+}
+
+func TestNewNonce(t *testing.T) {
+ ms, _ := create()
+
+ nonce := ms.NewNonce(addr)
+ if nonce != 100 {
+ t.Error("expected nonce 101. got", nonce)
+ }
+}
+
+func TestRemove(t *testing.T) {
+ ms, account := create()
+
+ nn := make([]bool, 10)
+ for i, _ := range nn {
+ nn[i] = true
+ }
+ account.nonces = append(account.nonces, nn...)
+
+ i := uint64(5)
+ ms.RemoveNonce(addr, account.nstart+i)
+ if len(account.nonces) != 5 {
+ t.Error("expected", i, "'th index to be false")
+ }
+}
+
+func TestReuse(t *testing.T) {
+ ms, account := create()
+
+ nn := make([]bool, 10)
+ for i, _ := range nn {
+ nn[i] = true
+ }
+ account.nonces = append(account.nonces, nn...)
+
+ i := uint64(5)
+ ms.RemoveNonce(addr, account.nstart+i)
+ nonce := ms.NewNonce(addr)
+ if nonce != 105 {
+ t.Error("expected nonce to be 105. got", nonce)
+ }
+}