func (t *TrackingState) Hash() (*chainhash.Hash, error) {
	var out *chainhash.Hash
	err := t.View(func(a csmt.TreeTransactionAccess) error {
		outHash, err := a.Hash()
		if err != nil {
			return err
		}
		out = outHash
		return nil
	})
	if err != nil {
		return nil, err
	}
	return out, err
}
Hash returns the current tree root.
package state
import (
	"fmt"
	"sync"
	"github.com/phoreproject/synapse/bls"
	"github.com/phoreproject/synapse/chainhash"
	"github.com/phoreproject/synapse/csmt"
	"github.com/phoreproject/synapse/primitives"
)
type State struct {
	SmartContractRoot chainhash.Hash
	LastCrosslinkHash chainhash.Hash
	ProposerAssignments []bls.PublicKey
}
type FullContractState struct {
	tree csmt.Tree
}
func (s *FullContractState) Hash() (*chainhash.Hash, error) {
	var out *chainhash.Hash
	err := s.View(func(a AccessInterface) error {
		outHash, err := a.Hash()
		if err != nil {
			return err
		}
		out = outHash
		return nil
	})
	if err != nil {
		return nil, err
	}
	return out, err
}
func NewFullShardState(tree csmt.Tree) *FullContractState {
	return &FullContractState{tree}
}
func (s *FullContractState) Update(cb func(AccessInterface) error) error {
	return s.tree.Update(func(tx csmt.TreeTransactionAccess) error {
		return cb(newFullShardStateAccess(tx.(*csmt.TreeTransaction)))
	})
}
func (s *FullContractState) View(cb func(AccessInterface) error) error {
	return s.tree.View(func(tx csmt.TreeTransactionAccess) error {
		return cb(newFullShardStateAccess(tx.(*csmt.TreeTransaction)))
	})
}
type FullShardStateAccess struct {
	tree *csmt.TreeTransaction
}
func newFullShardStateAccess(treeTX *csmt.TreeTransaction) *FullShardStateAccess {
	return &FullShardStateAccess{
		tree: treeTX,
	}
}
func (s *FullShardStateAccess) Set(key chainhash.Hash, value chainhash.Hash) error {
	return s.tree.Set(key, value)
}
func (s *FullShardStateAccess) Get(key chainhash.Hash) (*chainhash.Hash, error) {
	return s.tree.Get(key)
}
func (s *FullShardStateAccess) SetWithWitness(key chainhash.Hash, value chainhash.Hash) (*primitives.UpdateWitness, error) {
	return s.tree.SetWithWitness(key, value)
}
func (s *FullShardStateAccess) VerifyWitness(key chainhash.Hash) (*primitives.VerificationWitness, error) {
	return s.tree.Prove(key)
}
func (s *FullShardStateAccess) Hash() (*chainhash.Hash, error) {
	return s.tree.Hash()
}
type PartialShardStateAccess struct {
	stateRoot             chainhash.Hash
	verificationWitnesses []primitives.VerificationWitness
	updateWitnesses       []primitives.UpdateWitness
}
func (p PartialShardStateAccess) Hash() (*chainhash.Hash, error) {
	return &p.stateRoot, nil
}
func NewPartialShardState(root chainhash.Hash, vWitnesses []primitives.VerificationWitness, uWitnesses []primitives.UpdateWitness) *PartialShardStateAccess {
	return &PartialShardStateAccess{
		stateRoot:             root,
		verificationWitnesses: vWitnesses,
		updateWitnesses:       uWitnesses,
	}
}
func (p *PartialShardStateAccess) Get(key chainhash.Hash) (*chainhash.Hash, error) {
	if len(p.verificationWitnesses) == 0 {
		return nil, fmt.Errorf("no witnesses left")
	}
	vw := p.verificationWitnesses[0]
	if vw.Key != key {
		return nil, fmt.Errorf("incorrect witness; expected key: %s, got key: %s", vw.Key, key)
	}
	pass := csmt.CheckWitness(&vw, p.stateRoot)
	if !pass {
		return nil, fmt.Errorf("witness did not validate for key: %s", key)
	}
	p.verificationWitnesses = p.verificationWitnesses[1:]
	return &vw.Value, nil
}
func (p *PartialShardStateAccess) Set(key chainhash.Hash, value chainhash.Hash) error {
	if len(p.updateWitnesses) == 0 {
		return fmt.Errorf("no witnesses left")
	}
	uw := p.updateWitnesses[0]
	if uw.Key != key {
		return fmt.Errorf("incorrect witness; expected key: %s, got key: %s", uw.Key, key)
	}
	if uw.NewValue != value {
		return fmt.Errorf("incorrect witness; expected key: %s, got key: %s", uw.NewValue, value)
	}
	newStateRoot, err := csmt.ApplyWitness(uw, p.stateRoot)
	if err != nil {
		return err
	}
	p.stateRoot = *newStateRoot
	p.updateWitnesses = p.updateWitnesses[1:]
	return nil
}
type TrackingState struct {
	fullState             csmt.Tree
	verificationWitnesses []primitives.VerificationWitness
	updateWitnesses       []primitives.UpdateWitness
	initialRoot           chainhash.Hash
	lock *sync.RWMutex
}