diff --git a/cmd/tools/vochaininspector/inspector.go b/cmd/tools/vochaininspector/inspector.go index d2401d2eb..0a449e072 100644 --- a/cmd/tools/vochaininspector/inspector.go +++ b/cmd/tools/vochaininspector/inspector.go @@ -207,7 +207,7 @@ func openStateAtHeight(height int64, stateDir string) *statedb.TreeView { if err != nil { log.Fatalf("Can't open DB: %v", err) } - sdb := statedb.NewStateDB(database) + sdb := statedb.New(database) lastHeight, err := sdb.Version() if err != nil { log.Fatal("Can't get last height") diff --git a/statedb/statedb.go b/statedb/statedb.go index 8907ca087..c2bc21566 100644 --- a/statedb/statedb.go +++ b/statedb/statedb.go @@ -187,10 +187,10 @@ func (c *TreeConfig) HashFunc() arbo.HashFunction { return c.hashFunc } -// mainTreeCfg is the subTree configuration of the mainTree. It doesn't have a +// MainTreeCfg is the subTree configuration of the mainTree. It doesn't have a // kindID because it's the top level tree. For the same reason, it doesn't // contain functions to work with the parent leaf: it doesn't have a parent. -var mainTreeCfg = NewTreeSingletonConfig(TreeParams{ +var MainTreeCfg = NewTreeSingletonConfig(TreeParams{ HashFunc: arbo.HashFunctionSha256, KindID: "", MaxLevels: 256, @@ -209,10 +209,10 @@ type StateDB struct { NoStateReadTx db.Reader } -// NewStateDB returns an instance of the StateDB. -func NewStateDB(db db.Database) *StateDB { +// New returns an instance of the StateDB. +func New(db db.Database) *StateDB { return &StateDB{ - hashLen: mainTreeCfg.hashFunc.Len(), + hashLen: MainTreeCfg.hashFunc.Len(), db: db, } } @@ -285,7 +285,7 @@ func (s *StateDB) Hash() ([]byte, error) { // either call treeTx.Commit or treeTx.Discard if BeginTx doesn't return an // error. Calling treeTx.Discard after treeTx.Commit is ok. func (s *StateDB) BeginTx() (treeTx *TreeTx, err error) { - cfg := mainTreeCfg + cfg := MainTreeCfg // NOTE(Edu): The introduction of Batched Txs here came from the fact // that Badger takes a lot of memory and as a preconfigured maximum // memory allocated for a Tx, which we were easily reaching. But by @@ -379,7 +379,7 @@ func (*readOnlyWriteTx) Discard() {} // TreeView returns the mainTree opened at root as a TreeView for read-only. // If root is nil, the last version's root is used. func (s *StateDB) TreeView(root []byte) (*TreeView, error) { - cfg := mainTreeCfg + cfg := MainTreeCfg if root == nil { var err error @@ -403,6 +403,6 @@ func (s *StateDB) TreeView(root []byte) (*TreeView, error) { return &TreeView{ db: s.db, tree: tree, - cfg: mainTreeCfg, + cfg: MainTreeCfg, }, nil } diff --git a/statedb/statedb_test.go b/statedb/statedb_test.go index b3e99024c..669593810 100644 --- a/statedb/statedb_test.go +++ b/statedb/statedb_test.go @@ -16,7 +16,7 @@ import ( var emptyHash = make([]byte, 32) func TestVersion(t *testing.T) { - sdb := NewStateDB(metadb.NewTest(t)) + sdb := New(metadb.NewTest(t)) version, err := sdb.Version() qt.Assert(t, err, qt.IsNil) qt.Assert(t, version, qt.Equals, uint32(0)) @@ -43,7 +43,7 @@ func TestVersion(t *testing.T) { } func TestStateDB(t *testing.T) { - sdb := NewStateDB(metadb.NewTest(t)) + sdb := New(metadb.NewTest(t)) version, err := sdb.Version() qt.Assert(t, err, qt.IsNil) qt.Assert(t, version, qt.Equals, uint32(0)) @@ -210,7 +210,7 @@ func TestSubTree(t *testing.T) { // - an instance of two non-singleton subTrees (multiACfg, multiBCfg) // in a single leaf at path `id`. The leaf of the mainTree at path // `id` == multiA_id.Root | multiB_id.Root - sdb := NewStateDB(metadb.NewTest(t)) + sdb := New(metadb.NewTest(t)) mainTree, err := sdb.BeginTx() qt.Assert(t, err, qt.IsNil) @@ -311,7 +311,7 @@ func TestSubTree(t *testing.T) { } func TestNoState(t *testing.T) { - sdb := NewStateDB(metadb.NewTest(t)) + sdb := New(metadb.NewTest(t)) mainTree, err := sdb.BeginTx() qt.Assert(t, err, qt.IsNil) @@ -451,7 +451,7 @@ func TestTree(t *testing.T) { } func TestBigUpdate(t *testing.T) { - sdb := NewStateDB(metadb.NewTest(t)) + sdb := New(metadb.NewTest(t)) mainTree, err := sdb.BeginTx() qt.Assert(t, err, qt.IsNil) @@ -468,7 +468,7 @@ func TestBigUpdate(t *testing.T) { } func TestBigUpdateDiscard(t *testing.T) { - sdb := NewStateDB(metadb.NewTest(t)) + sdb := New(metadb.NewTest(t)) mainTree, err := sdb.BeginTx() qt.Assert(t, err, qt.IsNil) diff --git a/statedb/treeupdate.go b/statedb/treeupdate.go index ea5d6e0a3..ab1358a30 100644 --- a/statedb/treeupdate.go +++ b/statedb/treeupdate.go @@ -314,7 +314,7 @@ func (t *TreeTx) Commit(version uint32) error { if err := t.CommitOnTx(version); err != nil { return err } - return t.tx.Commit() + return t.SaveWithoutCommit() } // CommitOnTx do as Commit but without committing the transaction to database. diff --git a/statedb/treeview.go b/statedb/treeview.go index f96991869..301c9e8e4 100644 --- a/statedb/treeview.go +++ b/statedb/treeview.go @@ -150,7 +150,7 @@ func (v *TreeView) SubTree(cfg TreeConfig) (treeView TreeViewer, err error) { return &TreeView{ db: db, tree: tree, - cfg: mainTreeCfg, + cfg: MainTreeCfg, }, nil } diff --git a/test/testcommon/vochain.go b/test/testcommon/vochain.go index 89114e435..0d2ae5c7b 100644 --- a/test/testcommon/vochain.go +++ b/test/testcommon/vochain.go @@ -51,7 +51,7 @@ var ( ) func NewVochainState(tb testing.TB) *state.State { - s, err := state.NewState(db.TypePebble, tb.TempDir()) + s, err := state.New(db.TypePebble, tb.TempDir()) if err != nil { tb.Fatal(err) } diff --git a/vochain/app.go b/vochain/app.go index 46d7b808e..5ba5a3dd5 100644 --- a/vochain/app.go +++ b/vochain/app.go @@ -125,7 +125,7 @@ type ExecuteBlockResponse struct { // Node still needs to be initialized with SetNode. // Callback functions still need to be initialized. func NewBaseApplication(vochainCfg *config.VochainCfg) (*BaseApplication, error) { - state, err := vstate.NewState(vochainCfg.DBType, vochainCfg.DataDir) + state, err := vstate.New(vochainCfg.DBType, vochainCfg.DataDir) if err != nil { return nil, fmt.Errorf("cannot create state: (%v)", err) } diff --git a/vochain/ist/ist_test.go b/vochain/ist/ist_test.go index 43e5d853b..96d7c96b4 100644 --- a/vochain/ist/ist_test.go +++ b/vochain/ist/ist_test.go @@ -14,7 +14,7 @@ import ( func TestISTCschedule(t *testing.T) { rng := testutil.NewRandom(0) - s, err := state.NewState(db.TypePebble, t.TempDir()) + s, err := state.New(db.TypePebble, t.TempDir()) qt.Assert(t, err, qt.IsNil) defer s.Close() err = s.SetTimestamp(0) @@ -86,7 +86,7 @@ func TestISTCschedule(t *testing.T) { func TestISTCsyncing(t *testing.T) { rng := testutil.NewRandom(0) - s, err := state.NewState(db.TypePebble, t.TempDir()) + s, err := state.New(db.TypePebble, t.TempDir()) qt.Assert(t, err, qt.IsNil) defer s.Close() diff --git a/vochain/state/processblockregistry_test.go b/vochain/state/processblockregistry_test.go index 822d24fb9..c522fdee0 100644 --- a/vochain/state/processblockregistry_test.go +++ b/vochain/state/processblockregistry_test.go @@ -28,7 +28,7 @@ func TestSetStartBlock(t *testing.T) { c := qt.New(t) // create a state for testing dir := t.TempDir() - s, err := NewState(db.TypePebble, dir) + s, err := New(db.TypePebble, dir) qt.Assert(t, err, qt.IsNil) // set a start block for a random electionId pid := util.RandomBytes(32) @@ -44,7 +44,7 @@ func TestDeleteStartBlock(t *testing.T) { c := qt.New(t) // create a state for testing dir := t.TempDir() - s, err := NewState(db.TypePebble, dir) + s, err := New(db.TypePebble, dir) qt.Assert(t, err, qt.IsNil) // set a start block for a random electionId and delete it then pid := util.RandomBytes(32) @@ -60,7 +60,7 @@ func TestMinStartBlock(t *testing.T) { c := qt.New(t) // create a state for testing dir := t.TempDir() - s, err := NewState(db.TypePebble, dir) + s, err := New(db.TypePebble, dir) qt.Assert(t, err, qt.IsNil) fromBlock := uint32(100) // check min start block without create any election, fromBlock value @@ -85,7 +85,7 @@ func TestMaxEndBlock(t *testing.T) { c := qt.New(t) // create a state for testing dir := t.TempDir() - s, err := NewState(db.TypePebble, dir) + s, err := New(db.TypePebble, dir) qt.Assert(t, err, qt.IsNil) fromBlock := uint32(100) // check max endBlock without create any election, fromBlock value diff --git a/vochain/state/sik_test.go b/vochain/state/sik_test.go index 77a335cfc..c415ec098 100644 --- a/vochain/state/sik_test.go +++ b/vochain/state/sik_test.go @@ -19,7 +19,7 @@ func TestSetAddressSIK(t *testing.T) { c := qt.New(t) // create a tree for testing dir := t.TempDir() - s, err := NewState(db.TypePebble, dir) + s, err := New(db.TypePebble, dir) qt.Assert(t, err, qt.IsNil) // create a valid leaf address := common.HexToAddress("0xF3668000B66c61aAa08aBC559a8C78Ae7E007C2e") @@ -40,7 +40,7 @@ func TestDelSIK(t *testing.T) { c := qt.New(t) // create a state for testing dir := t.TempDir() - s, err := NewState(db.TypePebble, dir) + s, err := New(db.TypePebble, dir) qt.Assert(t, err, qt.IsNil) // create a valid leaf address := common.HexToAddress("0xF3668000B66c61aAa08aBC559a8C78Ae7E007C2e") @@ -68,7 +68,7 @@ func Test_registerSIKCounter(t *testing.T) { c := qt.New(t) // create a state for testing dir := t.TempDir() - s, err := NewState(db.TypePebble, dir) + s, err := New(db.TypePebble, dir) c.Assert(err, qt.IsNil) pid := util.RandomBytes(32) @@ -93,7 +93,7 @@ func Test_sikRoots(t *testing.T) { c := qt.New(t) // create a state for testing dir := t.TempDir() - s, err := NewState(db.TypePebble, dir) + s, err := New(db.TypePebble, dir) qt.Assert(t, err, qt.IsNil) // mock height and new sik and update the valid roots address1 := common.HexToAddress("0xF3668000B66c61aAa08aBC559a8C78Ae7E007C2e") @@ -149,7 +149,7 @@ func TestAssignSIKToElectionAndPurge(t *testing.T) { c := qt.New(t) // create a state for testing dir := t.TempDir() - s, err := NewState(db.TypePebble, dir) + s, err := New(db.TypePebble, dir) qt.Assert(t, err, qt.IsNil) // mock an account testAccount := ethereum.NewSignKeys() @@ -212,7 +212,7 @@ func TestSIKDataRace(t *testing.T) { c := qt.New(t) // create a state for testing dir := t.TempDir() - s, err := NewState(db.TypePebble, dir) + s, err := New(db.TypePebble, dir) qt.Assert(t, err, qt.IsNil) // create some siks diff --git a/vochain/state/state.go b/vochain/state/state.go index be0224f22..c2ebc311c 100644 --- a/vochain/state/state.go +++ b/vochain/state/state.go @@ -80,8 +80,8 @@ type State struct { mtxValidSIKRoots sync.Mutex } -// NewState creates a new State -func NewState(dbType, dataDir string) (*State, error) { +// New creates a new State +func New(dbType, dataDir string) (*State, error) { database, err := metadb.New(dbType, filepath.Join(dataDir, storageDirectory)) if err != nil { return nil, err @@ -136,7 +136,7 @@ func NewState(dbType, dataDir string) (*State, error) { // initStateDB initializes the StateDB with the default subTrees func initStateDB(database db.Database) (*statedb.StateDB, error) { log.Infof("initializing StateDB") - sdb := statedb.NewStateDB(database) + sdb := statedb.New(database) startTime := time.Now() defer func() { log.Infof("state database load took %s", time.Since(startTime)) }() root, err := sdb.Hash() @@ -152,59 +152,20 @@ func initStateDB(database db.Database) (*statedb.StateDB, error) { return nil, err } defer update.Discard() - // Create the Extra, Validators and Processes subtrees (from + // Create the all the Main subtrees (from // mainTree) by adding leaves in the mainTree that contain the // corresponding tree roots, and opening the subTrees for the first // time. - treeCfg := StateTreeCfg(TreeExtra) - if err := update.Add(treeCfg.Key(), - make([]byte, treeCfg.HashFunc().Len())); err != nil { - return nil, err - } - if _, err := update.SubTree(treeCfg); err != nil { - return nil, err - } - treeCfg = StateTreeCfg(TreeValidators) - if err := update.Add(treeCfg.Key(), - make([]byte, treeCfg.HashFunc().Len())); err != nil { - return nil, err - } - if _, err := update.SubTree(treeCfg); err != nil { - return nil, err - } - treeCfg = StateTreeCfg(TreeProcess) - if err := update.Add(treeCfg.Key(), - make([]byte, treeCfg.HashFunc().Len())); err != nil { - return nil, err - } - if _, err := update.SubTree(treeCfg); err != nil { - return nil, err - } - treeCfg = StateTreeCfg(TreeAccounts) - if err := update.Add(treeCfg.Key(), - make([]byte, treeCfg.HashFunc().Len())); err != nil { - return nil, err - } - if _, err := update.SubTree(treeCfg); err != nil { - return nil, err - } - treeCfg = StateTreeCfg(TreeFaucet) - if err := update.Add(treeCfg.Key(), - make([]byte, treeCfg.HashFunc().Len())); err != nil { - return nil, err - } - if _, err := update.SubTree(treeCfg); err != nil { - return nil, err - } - treeCfg = StateTreeCfg(TreeSIK) - if err := update.Add(treeCfg.Key(), - make([]byte, treeCfg.HashFunc().Len())); err != nil { - return nil, err - } - if _, err := update.SubTree(treeCfg); err != nil { - return nil, err + for name := range MainTrees { + treeCfg := StateTreeCfg(name) + if err := update.Add(treeCfg.Key(), + make([]byte, treeCfg.HashFunc().Len())); err != nil { + return nil, err + } + if _, err := update.SubTree(treeCfg); err != nil { + return nil, err + } } - return sdb, update.Commit(0) } diff --git a/vochain/state/state_snapshot_test.go b/vochain/state/state_snapshot_test.go index 084944f8b..1eaa6bfdd 100644 --- a/vochain/state/state_snapshot_test.go +++ b/vochain/state/state_snapshot_test.go @@ -155,7 +155,7 @@ func newEmptyTreeForTest(t *testing.T) *tree.Tree { } func newStateForTest(t *testing.T) *State { - state, err := NewState(db.TypePebble, t.TempDir()) + state, err := New(db.TypePebble, t.TempDir()) qt.Assert(t, err, qt.IsNil) return state } diff --git a/vochain/state/state_test.go b/vochain/state/state_test.go index f61b51914..e95157b01 100644 --- a/vochain/state/state_test.go +++ b/vochain/state/state_test.go @@ -25,14 +25,14 @@ func testSaveState(t *testing.T, s *State) []byte { func TestStateReopen(t *testing.T) { dir := t.TempDir() - s, err := NewState(db.TypePebble, dir) + s, err := New(db.TypePebble, dir) qt.Assert(t, err, qt.IsNil) hash1Before := testSaveState(t, s) qt.Assert(t, err, qt.IsNil) s.Close() - s, err = NewState(db.TypePebble, dir) + s, err = New(db.TypePebble, dir) qt.Assert(t, err, qt.IsNil) hash1After, err := s.store.Hash() qt.Assert(t, err, qt.IsNil) @@ -44,7 +44,7 @@ func TestStateReopen(t *testing.T) { func TestStateBasic(t *testing.T) { rng := testutil.NewRandom(0) log.Init("info", "stdout", nil) - s, err := NewState(db.TypePebble, t.TempDir()) + s, err := New(db.TypePebble, t.TempDir()) if err != nil { t.Fatal(err) } @@ -116,7 +116,7 @@ func TestStateBasic(t *testing.T) { func TestBalanceTransfer(t *testing.T) { log.Init("info", "stdout", nil) - s, err := NewState(db.TypePebble, t.TempDir()) + s, err := New(db.TypePebble, t.TempDir()) qt.Assert(t, err, qt.IsNil) defer s.Close() addr1 := ethereum.SignKeys{} @@ -204,7 +204,7 @@ func (*Listener) Rollback() {} func TestOnProcessStart(t *testing.T) { log.Init("info", "stdout", nil) - s, err := NewState(db.TypePebble, t.TempDir()) + s, err := New(db.TypePebble, t.TempDir()) qt.Assert(t, err, qt.IsNil) defer s.Close() rng := testutil.NewRandom(0) @@ -246,7 +246,7 @@ func TestOnProcessStart(t *testing.T) { func TestBlockMemoryUsage(t *testing.T) { rng := testutil.NewRandom(0) log.Init("info", "stdout", nil) - s, err := NewState(db.TypePebble, t.TempDir()) + s, err := New(db.TypePebble, t.TempDir()) qt.Assert(t, err, qt.IsNil) defer s.Close() @@ -303,7 +303,7 @@ func TestBlockMemoryUsage(t *testing.T) { func TestStateSetGetTxCostByTxType(t *testing.T) { log.Init("info", "stdout", nil) - s, err := NewState(db.TypePebble, t.TempDir()) + s, err := New(db.TypePebble, t.TempDir()) qt.Assert(t, err, qt.IsNil) defer s.Close() @@ -318,7 +318,7 @@ func TestStateSetGetTxCostByTxType(t *testing.T) { } func TestNoState(t *testing.T) { - s, err := NewState(db.TypePebble, t.TempDir()) + s, err := New(db.TypePebble, t.TempDir()) qt.Assert(t, err, qt.IsNil) defer func() { _ = s.Close() diff --git a/vochain/state/trees.go b/vochain/state/trees.go index b98742e54..ce83dee78 100644 --- a/vochain/state/trees.go +++ b/vochain/state/trees.go @@ -23,6 +23,7 @@ import ( // - FaucetNonce (key: hash(address + identifier), value: nil) const ( + TreeMain = "Main" TreeProcess = "Processes" TreeExtra = "Extra" TreeValidators = "Validators" @@ -71,8 +72,8 @@ func (v *State) mainTreeViewer(committed bool) statedb.TreeViewer { var ( // MainTrees contains the configuration for the singleton state trees MainTrees = map[string]statedb.TreeConfig{ - // Extra is the Extra subTree configuration. - "Extra": statedb.NewTreeSingletonConfig(statedb.TreeParams{ + // TreeExtra is the Extra subTree configuration. + TreeExtra: statedb.NewTreeSingletonConfig(statedb.TreeParams{ HashFunc: arbo.HashFunctionSha256, KindID: "xtra", MaxLevels: 256, @@ -80,8 +81,8 @@ var ( ParentLeafSetRoot: rootLeafSetRoot, }), - // Validators is the Validators subTree configuration. - "Validators": statedb.NewTreeSingletonConfig(statedb.TreeParams{ + // TreeValidators is the Validators subTree configuration. + TreeValidators: statedb.NewTreeSingletonConfig(statedb.TreeParams{ HashFunc: arbo.HashFunctionSha256, KindID: "valids", MaxLevels: 256, @@ -89,8 +90,8 @@ var ( ParentLeafSetRoot: rootLeafSetRoot, }), - // Processes is the Processes subTree configuration. - "Processes": statedb.NewTreeSingletonConfig(statedb.TreeParams{ + // TreeProcess is the Processes subTree configuration. + TreeProcess: statedb.NewTreeSingletonConfig(statedb.TreeParams{ HashFunc: arbo.HashFunctionSha256, KindID: "procs", MaxLevels: 256, @@ -98,8 +99,8 @@ var ( ParentLeafSetRoot: rootLeafSetRoot, }), - // Accounts is the Accounts subTree configuration. - "Accounts": statedb.NewTreeSingletonConfig(statedb.TreeParams{ + // TreeAccounts is the Accounts subTree configuration. + TreeAccounts: statedb.NewTreeSingletonConfig(statedb.TreeParams{ HashFunc: arbo.HashFunctionSha256, KindID: "balan", MaxLevels: 256, @@ -107,8 +108,8 @@ var ( ParentLeafSetRoot: rootLeafSetRoot, }), - // FaucetNonce is the Accounts used Faucet Nonce subTree configuration - "FaucetNonce": statedb.NewTreeSingletonConfig(statedb.TreeParams{ + // TreeFaucet is the Accounts used Faucet Nonce subTree configuration + TreeFaucet: statedb.NewTreeSingletonConfig(statedb.TreeParams{ HashFunc: arbo.HashFunctionSha256, KindID: "faucet", MaxLevels: 256, @@ -116,8 +117,8 @@ var ( ParentLeafSetRoot: rootLeafSetRoot, }), - // CensusSIK is the Secret Identity Keys subTree configuration - "CensusSIK": statedb.NewTreeSingletonConfig(statedb.TreeParams{ + // TreeSIK is the Secret Identity Keys subTree configuration + TreeSIK: statedb.NewTreeSingletonConfig(statedb.TreeParams{ HashFunc: arbo.HashFunctionPoseidon, KindID: "sik", MaxLevels: censustree.DefaultMaxLevels, @@ -128,8 +129,8 @@ var ( // ChildTrees contains the configuration for the state trees dependent on a main tree. ChildTrees = map[string]*statedb.TreeNonSingletonConfig{ - // Votes is the Votes subTree (found under a Process leaf) configuration. - "Votes": statedb.NewTreeNonSingletonConfig(statedb.TreeParams{ + // ChildTreeVotes is the Votes subTree (found under a Process leaf) configuration. + ChildTreeVotes: statedb.NewTreeNonSingletonConfig(statedb.TreeParams{ HashFunc: arbo.HashFunctionSha256, KindID: "votes", MaxLevels: 256, @@ -141,6 +142,9 @@ var ( // StateTreeCfg returns the state merkle tree with name. func StateTreeCfg(name string) statedb.TreeConfig { + if name == TreeMain { + return statedb.MainTreeCfg + } t, ok := MainTrees[name] if !ok { panic(fmt.Sprintf("state tree %s does not exist", name))