From 46692d25f70af9c4499969e4ee95763e601522f8 Mon Sep 17 00:00:00 2001 From: bianning Date: Wed, 29 Jun 2022 17:04:44 +0800 Subject: [PATCH 01/20] feat: add common types and func --- common/big.go | 14 ++++++++++++ common/bytes.go | 11 ++++++++++ common/types.go | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 common/big.go create mode 100644 common/bytes.go create mode 100644 common/types.go diff --git a/common/big.go b/common/big.go new file mode 100644 index 0000000..56080f7 --- /dev/null +++ b/common/big.go @@ -0,0 +1,14 @@ +package common + +import "math/big" + +// Common big integers often used +var ( + Big1 = big.NewInt(1) + Big2 = big.NewInt(2) + Big3 = big.NewInt(3) + Big0 = big.NewInt(0) + Big32 = big.NewInt(32) + Big256 = big.NewInt(0xff) + Big257 = big.NewInt(257) +) diff --git a/common/bytes.go b/common/bytes.go new file mode 100644 index 0000000..01ec1c4 --- /dev/null +++ b/common/bytes.go @@ -0,0 +1,11 @@ +package common + +func CopyBytes(b []byte) (copiedBytes []byte) { + if b == nil { + return nil + } + copiedBytes = make([]byte, len(b)) + copy(copiedBytes, b) + + return +} diff --git a/common/types.go b/common/types.go new file mode 100644 index 0000000..ece94d1 --- /dev/null +++ b/common/types.go @@ -0,0 +1,57 @@ +package common + +import "encoding/hex" + +const ( + HashLength = 32 + AddressLength = 20 +) + +type Hash [HashLength]byte +type Address [AddressLength]byte + +func (h Hash) Bytes() []byte { return h[:] } + +func HexToHash(s string) Hash { return BytesToHash(FromHex(s)) } + +func BytesToHash(b []byte) Hash { + var h Hash + h.SetBytes(b) + return h +} + +func FromHex(s string) []byte { + if len(s) > 1 { + if s[0:2] == "0x" || s[0:2] == "0X" { + s = s[2:] + } + if len(s)%2 == 1 { + s = "0" + s + } + h, _ := hex.DecodeString(s) + return h + + } + return nil +} + +func (h *Hash) SetBytes(b []byte) { + if len(b) > len(h) { + b = b[len(b)-HashLength:] + } + + copy(h[HashLength-len(b):], b) +} + +func BytesToAddress(b []byte) Address { + var a Address + a.SetBytes(b) + return a +} + +func (a *Address) SetBytes(b []byte) { + if len(b) > len(a) { + b = b[len(b)-AddressLength:] + } + copy(a[AddressLength-len(b):], b) +} From d436c7a4c514cc2228d0f6cddac0721cfa601d58 Mon Sep 17 00:00:00 2001 From: bianning Date: Wed, 29 Jun 2022 17:05:20 +0800 Subject: [PATCH 02/20] feat: add MPT --- dataStructure/trie/encoding.go | 76 +++++ dataStructure/trie/errors.go | 15 + dataStructure/trie/hasher.go | 161 ++++++++++ dataStructure/trie/iterator.go | 497 ++++++++++++++++++++++++++++++ dataStructure/trie/node.go | 191 ++++++++++++ dataStructure/trie/secure_trie.go | 138 +++++++++ dataStructure/trie/trie.go | 354 +++++++++++++++++++++ 7 files changed, 1432 insertions(+) create mode 100644 dataStructure/trie/encoding.go create mode 100644 dataStructure/trie/errors.go create mode 100644 dataStructure/trie/hasher.go create mode 100644 dataStructure/trie/iterator.go create mode 100644 dataStructure/trie/node.go create mode 100644 dataStructure/trie/secure_trie.go create mode 100644 dataStructure/trie/trie.go diff --git a/dataStructure/trie/encoding.go b/dataStructure/trie/encoding.go new file mode 100644 index 0000000..343dd86 --- /dev/null +++ b/dataStructure/trie/encoding.go @@ -0,0 +1,76 @@ +package trie + +func compactToHex(compact []byte) []byte { + base := keyBytesToHex(compact) + base = base[:len(base)-1] + // apply terminator flag + if base[0] >= 2 { + base = append(base, 16) + } + // apply odd flag + chop := 2 - base[0]&1 + return base[chop:] +} + +func hexToCompact(hex []byte) []byte { + terminator := byte(0) + if hasTerm(hex) { + terminator = 1 + hex = hex[:len(hex)-1] + } + buf := make([]byte, len(hex)/2+1) + buf[0] = terminator << 5 // the flag byte + if len(hex)&1 == 1 { + buf[0] |= 1 << 4 // odd flag + buf[0] |= hex[0] // first nibble is contained in the first byte + hex = hex[1:] + } + decodeNibbles(hex, buf[1:]) + return buf +} + +func hexToKeyBytes(hex []byte) []byte { + if hasTerm(hex) { + hex = hex[:len(hex)-1] + } + if len(hex)&1 != 0 { + panic("can't convert hex key of odd length") + } + key := make([]byte, (len(hex)+1)/2) + decodeNibbles(hex, key) + return key +} + +func decodeNibbles(nibbles []byte, bytes []byte) { + for bi, ni := 0, 0; ni < len(nibbles); bi, ni = bi+1, ni+2 { + bytes[bi] = nibbles[ni]<<4 | nibbles[ni+1] + } +} + +func keyBytesToHex(str []byte) []byte { + l := len(str)*2 + 1 + var nibbles = make([]byte, l) + for i, b := range str { + nibbles[i*2] = b / 16 + nibbles[i*2+1] = b % 16 + } + nibbles[l-1] = 16 + return nibbles +} + +func hasTerm(s []byte) bool { + return len(s) > 0 && s[len(s)-1] == 16 +} + +func prefixLen(a, b []byte) int { + var i, length = 0, len(a) + if len(b) < length { + length = len(b) + } + for ; i < length; i++ { + if a[i] != b[i] { + break + } + } + return i +} diff --git a/dataStructure/trie/errors.go b/dataStructure/trie/errors.go new file mode 100644 index 0000000..d6f62d9 --- /dev/null +++ b/dataStructure/trie/errors.go @@ -0,0 +1,15 @@ +package trie + +import ( + "fmt" + "github.com/SealSC/SealABC/common" +) + +type MissingNodeError struct { + NodeHash common.Hash // hash of the missing node + Path []byte // hex-encoded path to the missing node +} + +func (err *MissingNodeError) Error() string { + return fmt.Sprintf("missing trie node %x (path %x)", err.NodeHash, err.Path) +} diff --git a/dataStructure/trie/hasher.go b/dataStructure/trie/hasher.go new file mode 100644 index 0000000..832c01b --- /dev/null +++ b/dataStructure/trie/hasher.go @@ -0,0 +1,161 @@ +package trie + +import ( + "bytes" + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/crypto/hashes/sha3" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" + "github.com/ethereum/go-ethereum/rlp" + "hash" + + "sync" +) + +type hasher struct { + tmp *bytes.Buffer + sha hash.Hash + cacheGen, cacheLimit uint16 +} + +var hasherPool = sync.Pool{ + New: func() interface{} { + //todo: hash + return &hasher{tmp: new(bytes.Buffer), sha: sha3.Keccak256.OriginalHash()()} + }, +} + +func newHasher(cacheGen, cacheLimit uint16) *hasher { + h := hasherPool.Get().(*hasher) + h.cacheGen, h.cacheLimit = cacheGen, cacheLimit + return h +} + +func returnHasherToPool(h *hasher) { + hasherPool.Put(h) +} + +// hash collapses a node down into a hash node, also returning a copy of the +// original node initialized with the computed hash to replace the original one. +func (h *hasher) hash(n node, db kvDatabase.IDriver, force bool) (node, node, error) { + // If we're not storing the node, just hashing, use available cached data + if hash, dirty := n.cache(); hash != nil { + if db == nil { + return hash, n, nil + } + if n.canUnload(h.cacheGen, h.cacheLimit) { + // Unload the node from cache. All of its subnodes will have a lower or equal + // cache generation number. + cacheUnloadCounter.Inc(1) + return hash, hash, nil + } + if !dirty { + return hash, n, nil + } + } + // Trie not processed yet or needs storage, walk the children + collapsed, cached, err := h.hashChildren(n, db) + if err != nil { + return hashNode{}, n, err + } + hashed, err := h.store(collapsed, db, force) + if err != nil { + return hashNode{}, n, err + } + // Cache the hash of the node for later reuse and remove + // the dirty flag in commit mode. It's fine to assign these values directly + // without copying the node first because hashChildren copies it. + cachedHash, _ := hashed.(hashNode) + switch cn := cached.(type) { + case *shortNode: + cn.flags.hash = cachedHash + if db != nil { + cn.flags.dirty = false + } + case *fullNode: + cn.flags.hash = cachedHash + if db != nil { + cn.flags.dirty = false + } + } + return hashed, cached, nil +} + +// hashChildren replaces the children of a node with their hashes if the encoded +// size of the child is larger than a hash, returning the collapsed node as well +// as a replacement for the original node with the child hashes cached in. +func (h *hasher) hashChildren(original node, db kvDatabase.IDriver) (node, node, error) { + var err error + + switch n := original.(type) { + case *shortNode: + // Hash the short node's child, caching the newly hashed subtree + collapsed, cached := n.copy(), n.copy() + collapsed.Key = hexToCompact(n.Key) + cached.Key = common.CopyBytes(n.Key) + + if _, ok := n.Val.(valueNode); !ok { + collapsed.Val, cached.Val, err = h.hash(n.Val, db, false) + if err != nil { + return original, original, err + } + } + if collapsed.Val == nil { + collapsed.Val = valueNode(nil) // Ensure that nil children are encoded as empty strings. + } + return collapsed, cached, nil + + case *fullNode: + // Hash the full node's children, caching the newly hashed subtrees + collapsed, cached := n.copy(), n.copy() + + for i := 0; i < 16; i++ { + if n.Children[i] != nil { + collapsed.Children[i], cached.Children[i], err = h.hash(n.Children[i], db, false) + if err != nil { + return original, original, err + } + } else { + collapsed.Children[i] = valueNode(nil) // Ensure that nil children are encoded as empty strings. + } + } + cached.Children[16] = n.Children[16] + if collapsed.Children[16] == nil { + collapsed.Children[16] = valueNode(nil) + } + return collapsed, cached, nil + + default: + // Value and hash nodes don't have children so they're left as were + return n, original, nil + } +} + +func (h *hasher) store(n node, db kvDatabase.IDriver, force bool) (node, error) { + // Don't store hashes or empty nodes. + if _, isHash := n.(hashNode); n == nil || isHash { + return n, nil + } + // Generate the RLP encoding of the node + h.tmp.Reset() + if err := rlp.Encode(h.tmp, n); err != nil { + panic("encode error: " + err.Error()) + } + + if h.tmp.Len() < 32 && !force { + return n, nil // Nodes smaller than 32 bytes are stored inside their parent + } + // Larger nodes are replaced by their hash and stored in the database. + hash, _ := n.cache() + if hash == nil { + h.sha.Reset() + h.sha.Write(h.tmp.Bytes()) + hash = hashNode(h.sha.Sum(nil)) + } + if db != nil { + return hash, db.Put(kvDatabase.KVItem{ + Key: hash, + Data: h.tmp.Bytes(), + }) + } + return hash, nil +} diff --git a/dataStructure/trie/iterator.go b/dataStructure/trie/iterator.go new file mode 100644 index 0000000..1584bb6 --- /dev/null +++ b/dataStructure/trie/iterator.go @@ -0,0 +1,497 @@ +package trie + +import ( + "bytes" + "container/heap" + "errors" + "github.com/SealSC/SealABC/common" +) + +// Iterator is a key-value trie iterator that traverses a Trie. +type Iterator struct { + nodeIt NodeIterator + + Key []byte // Current data key on which the iterator is positioned on + Value []byte // Current data value on which the iterator is positioned on + Err error +} + +// NewIterator creates a new key-value iterator from a node iterator +func NewIterator(it NodeIterator) *Iterator { + return &Iterator{ + nodeIt: it, + } +} + +// Next moves the iterator forward one key-value entry. +func (it *Iterator) Next() bool { + for it.nodeIt.Next(true) { + if it.nodeIt.Leaf() { + it.Key = it.nodeIt.LeafKey() + it.Value = it.nodeIt.LeafBlob() + return true + } + } + it.Key = nil + it.Value = nil + it.Err = it.nodeIt.Error() + return false +} + +type NodeIterator interface { + Next(bool) bool + + Error() error + + Hash() common.Hash + Parent() common.Hash + + Path() []byte + + Leaf() bool + LeafBlob() []byte + LeafKey() []byte +} + +type nodeIteratorState struct { + hash common.Hash + node node + parent common.Hash + index int + pathLen int +} + +type nodeIterator struct { + trie *Trie + stack []*nodeIteratorState + path []byte + err error +} + +// iteratorEnd is stored in nodeIterator.err when iteration is done. +var iteratorEnd = errors.New("end of iteration") + +// seekError is stored in nodeIterator.err if the initial seek has failed. +type seekError struct { + key []byte + err error +} + +func (e seekError) Error() string { + return "seek error: " + e.err.Error() +} + +func newNodeIterator(trie *Trie, start []byte) NodeIterator { + if trie.Hash() == emptyState { + return new(nodeIterator) + } + it := &nodeIterator{trie: trie} + it.err = it.seek(start) + return it +} + +func (it *nodeIterator) Hash() common.Hash { + if len(it.stack) == 0 { + return common.Hash{} + } + return it.stack[len(it.stack)-1].hash +} + +func (it *nodeIterator) Parent() common.Hash { + if len(it.stack) == 0 { + return common.Hash{} + } + return it.stack[len(it.stack)-1].parent +} + +func (it *nodeIterator) Leaf() bool { + return hasTerm(it.path) +} + +func (it *nodeIterator) LeafBlob() []byte { + if len(it.stack) > 0 { + if node, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { + return []byte(node) + } + } + panic("not at leaf") +} + +func (it *nodeIterator) LeafKey() []byte { + if len(it.stack) > 0 { + if _, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { + return hexToKeyBytes(it.path) + } + } + panic("not at leaf") +} + +func (it *nodeIterator) Path() []byte { + return it.path +} + +func (it *nodeIterator) Error() error { + if it.err == iteratorEnd { + return nil + } + if seek, ok := it.err.(seekError); ok { + return seek.err + } + return it.err +} + +// Next moves the iterator to the next node, returning whether there are any +// further nodes. In case of an internal error this method returns false and +// sets the Error field to the encountered failure. If `descend` is false, +// skips iterating over any subnodes of the current node. +func (it *nodeIterator) Next(descend bool) bool { + if it.err == iteratorEnd { + return false + } + if seek, ok := it.err.(seekError); ok { + if it.err = it.seek(seek.key); it.err != nil { + return false + } + } + // Otherwise step forward with the iterator and report any errors. + state, parentIndex, path, err := it.peek(descend) + it.err = err + if it.err != nil { + return false + } + it.push(state, parentIndex, path) + return true +} + +func (it *nodeIterator) seek(prefix []byte) error { + // The path we're looking for is the hex encoded key without terminator. + key := keyBytesToHex(prefix) + key = key[:len(key)-1] + // Move forward until we're just before the closest match to key. + for { + state, parentIndex, path, err := it.peek(bytes.HasPrefix(key, it.path)) + if err == iteratorEnd { + return iteratorEnd + } else if err != nil { + return seekError{prefix, err} + } else if bytes.Compare(path, key) >= 0 { + return nil + } + it.push(state, parentIndex, path) + } +} + +// peek creates the next state of the iterator. +func (it *nodeIterator) peek(descend bool) (*nodeIteratorState, *int, []byte, error) { + if len(it.stack) == 0 { + // Initialize the iterator if we've just started. + root := it.trie.Hash() + state := &nodeIteratorState{node: it.trie.root, index: -1} + if root != emptyRoot { + state.hash = root + } + err := state.resolve(it.trie, nil) + return state, nil, nil, err + } + if !descend { + // If we're skipping children, pop the current node first + it.pop() + } + + // Continue iteration to the next child + for len(it.stack) > 0 { + parent := it.stack[len(it.stack)-1] + ancestor := parent.hash + if (ancestor == common.Hash{}) { + ancestor = parent.parent + } + state, path, ok := it.nextChild(parent, ancestor) + if ok { + if err := state.resolve(it.trie, path); err != nil { + return parent, &parent.index, path, err + } + return state, &parent.index, path, nil + } + // No more child nodes, move back up. + it.pop() + } + return nil, nil, nil, iteratorEnd +} + +func (st *nodeIteratorState) resolve(tr *Trie, path []byte) error { + if hash, ok := st.node.(hashNode); ok { + resolved, err := tr.resolveHash(hash, path) + if err != nil { + return err + } + st.node = resolved + st.hash = common.BytesToHash(hash) + } + return nil +} + +func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Hash) (*nodeIteratorState, []byte, bool) { + switch node := parent.node.(type) { + case *fullNode: + // Full node, move to the first non-nil child. + for i := parent.index + 1; i < len(node.Children); i++ { + child := node.Children[i] + if child != nil { + hash, _ := child.cache() + state := &nodeIteratorState{ + hash: common.BytesToHash(hash), + node: child, + parent: ancestor, + index: -1, + pathLen: len(it.path), + } + path := append(it.path, byte(i)) + parent.index = i - 1 + return state, path, true + } + } + case *shortNode: + // Short node, return the pointer singleton child + if parent.index < 0 { + hash, _ := node.Val.cache() + state := &nodeIteratorState{ + hash: common.BytesToHash(hash), + node: node.Val, + parent: ancestor, + index: -1, + pathLen: len(it.path), + } + path := append(it.path, node.Key...) + return state, path, true + } + } + return parent, it.path, false +} + +func (it *nodeIterator) push(state *nodeIteratorState, parentIndex *int, path []byte) { + it.path = path + it.stack = append(it.stack, state) + if parentIndex != nil { + *parentIndex += 1 + } +} + +func (it *nodeIterator) pop() { + parent := it.stack[len(it.stack)-1] + it.path = it.path[:parent.pathLen] + it.stack = it.stack[:len(it.stack)-1] +} + +func compareNodes(a, b NodeIterator) int { + if cmp := bytes.Compare(a.Path(), b.Path()); cmp != 0 { + return cmp + } + if a.Leaf() && !b.Leaf() { + return -1 + } else if b.Leaf() && !a.Leaf() { + return 1 + } + if cmp := bytes.Compare(a.Hash().Bytes(), b.Hash().Bytes()); cmp != 0 { + return cmp + } + if a.Leaf() && b.Leaf() { + return bytes.Compare(a.LeafBlob(), b.LeafBlob()) + } + return 0 +} + +type differenceIterator struct { + a, b NodeIterator // Nodes returned are those in b - a. + eof bool // Indicates a has run out of elements + count int // Number of nodes scanned on either trie +} + +// NewDifferenceIterator constructs a NodeIterator that iterates over elements in b that +// are not in a. Returns the iterator, and a pointer to an integer recording the number +// of nodes seen. +func NewDifferenceIterator(a, b NodeIterator) (NodeIterator, *int) { + a.Next(true) + it := &differenceIterator{ + a: a, + b: b, + } + return it, &it.count +} + +func (it *differenceIterator) Hash() common.Hash { + return it.b.Hash() +} + +func (it *differenceIterator) Parent() common.Hash { + return it.b.Parent() +} + +func (it *differenceIterator) Leaf() bool { + return it.b.Leaf() +} + +func (it *differenceIterator) LeafBlob() []byte { + return it.b.LeafBlob() +} + +func (it *differenceIterator) LeafKey() []byte { + return it.b.LeafKey() +} + +func (it *differenceIterator) Path() []byte { + return it.b.Path() +} + +func (it *differenceIterator) Next(bool) bool { + // Invariants: + // - We always advance at least one element in b. + // - At the start of this function, a's path is lexically greater than b's. + if !it.b.Next(true) { + return false + } + it.count += 1 + + if it.eof { + // a has reached eof, so we just return all elements from b + return true + } + + for { + switch compareNodes(it.a, it.b) { + case -1: + // b jumped past a; advance a + if !it.a.Next(true) { + it.eof = true + return true + } + it.count += 1 + case 1: + // b is before a + return true + case 0: + // a and b are identical; skip this whole subtree if the nodes have hashes + hasHash := it.a.Hash() == common.Hash{} + if !it.b.Next(hasHash) { + return false + } + it.count += 1 + if !it.a.Next(hasHash) { + it.eof = true + return true + } + it.count += 1 + } + } +} + +func (it *differenceIterator) Error() error { + if err := it.a.Error(); err != nil { + return err + } + return it.b.Error() +} + +type nodeIteratorHeap []NodeIterator + +func (h nodeIteratorHeap) Len() int { return len(h) } +func (h nodeIteratorHeap) Less(i, j int) bool { return compareNodes(h[i], h[j]) < 0 } +func (h nodeIteratorHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } +func (h *nodeIteratorHeap) Push(x interface{}) { *h = append(*h, x.(NodeIterator)) } +func (h *nodeIteratorHeap) Pop() interface{} { + n := len(*h) + x := (*h)[n-1] + *h = (*h)[0 : n-1] + return x +} + +type unionIterator struct { + items *nodeIteratorHeap // Nodes returned are the union of the ones in these iterators + count int // Number of nodes scanned across all tries +} + +// NewUnionIterator constructs a NodeIterator that iterates over elements in the union +// of the provided NodeIterators. Returns the iterator, and a pointer to an integer +// recording the number of nodes visited. +func NewUnionIterator(iters []NodeIterator) (NodeIterator, *int) { + h := make(nodeIteratorHeap, len(iters)) + copy(h, iters) + heap.Init(&h) + + ui := &unionIterator{items: &h} + return ui, &ui.count +} + +func (it *unionIterator) Hash() common.Hash { + return (*it.items)[0].Hash() +} + +func (it *unionIterator) Parent() common.Hash { + return (*it.items)[0].Parent() +} + +func (it *unionIterator) Leaf() bool { + return (*it.items)[0].Leaf() +} + +func (it *unionIterator) LeafBlob() []byte { + return (*it.items)[0].LeafBlob() +} + +func (it *unionIterator) LeafKey() []byte { + return (*it.items)[0].LeafKey() +} + +func (it *unionIterator) Path() []byte { + return (*it.items)[0].Path() +} + +// Next returns the next node in the union of tries being iterated over. +// +// It does this by maintaining a heap of iterators, sorted by the iteration +// order of their next elements, with one entry for each source trie. Each +// time Next() is called, it takes the least element from the heap to return, +// advancing any other iterators that also point to that same element. These +// iterators are called with descend=false, since we know that any nodes under +// these nodes will also be duplicates, found in the currently selected iterator. +// Whenever an iterator is advanced, it is pushed back into the heap if it still +// has elements remaining. +// +// In the case that descend=false - eg, we're asked to ignore all subnodes of the +// current node - we also advance any iterators in the heap that have the current +// path as a prefix. +func (it *unionIterator) Next(descend bool) bool { + if len(*it.items) == 0 { + return false + } + + // Get the next key from the union + least := heap.Pop(it.items).(NodeIterator) + + // Skip over other nodes as long as they're identical, or, if we're not descending, as + // long as they have the same prefix as the current node. + for len(*it.items) > 0 && ((!descend && bytes.HasPrefix((*it.items)[0].Path(), least.Path())) || compareNodes(least, (*it.items)[0]) == 0) { + skipped := heap.Pop(it.items).(NodeIterator) + // Skip the whole subtree if the nodes have hashes; otherwise just skip this node + if skipped.Next(skipped.Hash() == common.Hash{}) { + it.count += 1 + // If there are more elements, push the iterator back on the heap + heap.Push(it.items, skipped) + } + } + + if least.Next(descend) { + it.count += 1 + heap.Push(it.items, least) + } + + return len(*it.items) > 0 +} + +func (it *unionIterator) Error() error { + for i := 0; i < len(*it.items); i++ { + if err := (*it.items)[i].Error(); err != nil { + return err + } + } + return nil +} diff --git a/dataStructure/trie/node.go b/dataStructure/trie/node.go new file mode 100644 index 0000000..439ef4a --- /dev/null +++ b/dataStructure/trie/node.go @@ -0,0 +1,191 @@ +package trie + +import ( + "fmt" + "github.com/SealSC/SealABC/common" + "github.com/ethereum/go-ethereum/rlp" + "io" + "strings" +) + +var indices = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "[17]"} + +type node interface { + fString(string) string + cache() (hashNode, bool) + canUnload(cacheGen, cacheLimit uint16) bool +} + +type ( + fullNode struct { + Children [17]node + flags nodeFlag + } + shortNode struct { + Key []byte + Val node + flags nodeFlag + } + hashNode []byte + valueNode []byte +) + +func (n *fullNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) } +func (n *shortNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) } +func (n hashNode) canUnload(uint16, uint16) bool { return false } +func (n valueNode) canUnload(uint16, uint16) bool { return false } + +func (n *fullNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirty } +func (n *shortNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirty } +func (n hashNode) cache() (hashNode, bool) { return nil, true } +func (n valueNode) cache() (hashNode, bool) { return nil, true } + +// Pretty printing. +func (n *fullNode) String() string { return n.fString("") } +func (n *shortNode) String() string { return n.fString("") } +func (n hashNode) String() string { return n.fString("") } +func (n valueNode) String() string { return n.fString("") } + +func (n *fullNode) fString(ind string) string { + resp := fmt.Sprintf("[\n%s ", ind) + for i, node := range n.Children { + if node == nil { + resp += fmt.Sprintf("%s: ", indices[i]) + } else { + resp += fmt.Sprintf("%s: %v", indices[i], node.fString(ind+" ")) + } + } + return resp + fmt.Sprintf("\n%s] ", ind) +} +func (n *shortNode) fString(ind string) string { + return fmt.Sprintf("{%x: %v} ", n.Key, n.Val.fString(ind+" ")) +} +func (n hashNode) fString(ind string) string { + return fmt.Sprintf("<%x> ", []byte(n)) +} +func (n valueNode) fString(ind string) string { + return fmt.Sprintf("%x ", []byte(n)) +} + +func (n *fullNode) copy() *fullNode { cn := *n; return &cn } +func (n *shortNode) copy() *shortNode { cn := *n; return &cn } + +func (n *fullNode) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, n.Children) +} + +type nodeFlag struct { + hash hashNode + gen uint16 + dirty bool +} + +func (n *nodeFlag) canUnload(cacheGen, cacheLimit uint16) bool { + return !n.dirty && cacheGen-n.gen >= cacheLimit +} + +func decodeNode(hash, buf []byte, cacheGen uint16) (node, error) { + if len(buf) == 0 { + return nil, io.ErrUnexpectedEOF + } + elems, _, err := rlp.SplitList(buf) + if err != nil { + return nil, fmt.Errorf("decode error: %v", err) + } + switch c, _ := rlp.CountValues(elems); c { + case 2: + n, err := decodeShort(hash, buf, elems, cacheGen) + return n, wrapError(err, "short") + case 17: + n, err := decodeFull(hash, buf, elems, cacheGen) + return n, wrapError(err, "full") + default: + return nil, fmt.Errorf("invalid number of list elements: %v", c) + } +} + +func decodeShort(hash, buf, elems []byte, cachegen uint16) (node, error) { + kBuf, rest, err := rlp.SplitString(elems) + if err != nil { + return nil, err + } + flag := nodeFlag{hash: hash, gen: cachegen} + key := compactToHex(kBuf) + if hasTerm(key) { + // value node + val, _, err := rlp.SplitString(rest) + if err != nil { + return nil, fmt.Errorf("invalid value node: %v", err) + } + return &shortNode{key, append(valueNode{}, val...), flag}, nil + } + r, _, err := decodeRef(rest, cachegen) + if err != nil { + return nil, wrapError(err, "val") + } + return &shortNode{key, r, flag}, nil +} + +func decodeFull(hash, buf, elems []byte, cachegen uint16) (*fullNode, error) { + n := &fullNode{flags: nodeFlag{hash: hash, gen: cachegen}} + for i := 0; i < 16; i++ { + cld, rest, err := decodeRef(elems, cachegen) + if err != nil { + return n, wrapError(err, fmt.Sprintf("[%d]", i)) + } + n.Children[i], elems = cld, rest + } + val, _, err := rlp.SplitString(elems) + if err != nil { + return n, err + } + if len(val) > 0 { + n.Children[16] = append(valueNode{}, val...) + } + return n, nil +} + +func decodeRef(buf []byte, cachegen uint16) (node, []byte, error) { + kind, val, rest, err := rlp.Split(buf) + if err != nil { + return nil, buf, err + } + switch { + case kind == rlp.List: + // 'embedded' node reference. The encoding must be smaller + // than a hash in order to be valid. + if size := len(buf) - len(rest); size > common.HashLength { + err := fmt.Errorf("oversized embedded node (size is %d bytes, want size < %d)", size, common.HashLength) + return nil, buf, err + } + n, err := decodeNode(nil, buf, cachegen) + return n, rest, err + case kind == rlp.String && len(val) == 0: + // empty node + return nil, rest, nil + case kind == rlp.String && len(val) == 32: + return append(hashNode{}, val...), rest, nil + default: + return nil, nil, fmt.Errorf("invalid RLP string size %d (want 0 or 32)", len(val)) + } +} + +type decodeError struct { + what error + stack []string +} + +func wrapError(err error, ctx string) error { + if err == nil { + return nil + } + if decErr, ok := err.(*decodeError); ok { + decErr.stack = append(decErr.stack, ctx) + return decErr + } + return &decodeError{err, []string{ctx}} +} + +func (err *decodeError) Error() string { + return fmt.Sprintf("%v (decode path: %s)", err.what, strings.Join(err.stack, "<-")) +} diff --git a/dataStructure/trie/secure_trie.go b/dataStructure/trie/secure_trie.go new file mode 100644 index 0000000..bf80b26 --- /dev/null +++ b/dataStructure/trie/secure_trie.go @@ -0,0 +1,138 @@ +package trie + +import ( + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" +) + +var secureKeyPrefix = []byte("secure-key-") + +const secureKeyLength = 11 + 32 + +type SecureTrie struct { + trie Trie + hashKeyBuf [secureKeyLength]byte + secKeyBuf [200]byte + secKeyCache map[string][]byte + secKeyCacheOwner *SecureTrie +} + +func NewSecure(root common.Hash, db kvDatabase.IDriver, cacheLimit uint16) (*SecureTrie, error) { + if db == nil { + panic("NewSecure called with nil database") + } + trie, err := New(root, db) + if err != nil { + return nil, err + } + trie.SetCacheLimit(cacheLimit) + return &SecureTrie{trie: *trie}, nil +} + +func (t *SecureTrie) Get(key []byte) []byte { + res, err := t.TryGet(key) + if err != nil { + log.Log.Errorf("Unhandled trie error: %v", err) + } + return res +} + +func (t *SecureTrie) TryGet(key []byte) ([]byte, error) { + return t.trie.TryGet(t.hashKey(key)) +} + +func (t *SecureTrie) Update(key, value []byte) { + if err := t.TryUpdate(key, value); err != nil { + log.Log.Errorf("Unhandled trie error: %v", err) + } +} + +func (t *SecureTrie) TryUpdate(key, value []byte) error { + hk := t.hashKey(key) + err := t.trie.TryUpdate(hk, value) + if err != nil { + return err + } + t.getSecKeyCache()[string(hk)] = common.CopyBytes(key) + return nil +} + +func (t *SecureTrie) Delete(key []byte) { + if err := t.TryDelete(key); err != nil { + log.Log.Errorf("Unhandled trie error: %v", err) + } +} + +func (t *SecureTrie) TryDelete(key []byte) error { + hk := t.hashKey(key) + delete(t.getSecKeyCache(), string(hk)) + return t.trie.TryDelete(hk) +} + +func (t *SecureTrie) GetKey(shaKey []byte) []byte { + if key, ok := t.getSecKeyCache()[string(shaKey)]; ok { + return key + } + key, _ := t.trie.db.Get(t.secKey(shaKey)) + return key.Data +} + +func (t *SecureTrie) Commit() (root common.Hash, err error) { + return t.CommitTo(t.trie.db) +} + +func (t *SecureTrie) Hash() common.Hash { + return t.trie.Hash() +} + +func (t *SecureTrie) Root() []byte { + return t.trie.Root() +} + +func (t *SecureTrie) Copy() *SecureTrie { + cpy := *t + return &cpy +} + +func (t *SecureTrie) NodeIterator(start []byte) NodeIterator { + return t.trie.NodeIterator(start) +} + +func (t *SecureTrie) CommitTo(db kvDatabase.IDriver) (root common.Hash, err error) { + if len(t.getSecKeyCache()) > 0 { + for hk, key := range t.secKeyCache { + if err := db.Put(kvDatabase.KVItem{ + Key: t.secKey([]byte(hk)), + Data: key, + }); err != nil { + return common.Hash{}, err + } + } + t.secKeyCache = make(map[string][]byte) + } + return t.trie.CommitTo(db) +} + +func (t *SecureTrie) secKey(key []byte) []byte { + buf := append(t.secKeyBuf[:0], secureKeyPrefix...) + buf = append(buf, key...) + return buf +} + +func (t *SecureTrie) hashKey(key []byte) []byte { + h := newHasher(0, 0) + h.sha.Reset() + h.sha.Write(key) + buf := h.sha.Sum(t.hashKeyBuf[:0]) + returnHasherToPool(h) + return buf +} + +func (t *SecureTrie) getSecKeyCache() map[string][]byte { + if t != t.secKeyCacheOwner { + t.secKeyCacheOwner = t + t.secKeyCache = make(map[string][]byte) + } + return t.secKeyCache +} diff --git a/dataStructure/trie/trie.go b/dataStructure/trie/trie.go new file mode 100644 index 0000000..ee716e0 --- /dev/null +++ b/dataStructure/trie/trie.go @@ -0,0 +1,354 @@ +package trie + +import ( + "bytes" + "fmt" + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" + "github.com/ethereum/go-ethereum/metrics" +) + +var ( + emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") + + emptyState common.Hash +) + +var ( + cacheMissCounter = metrics.NewRegisteredCounter("trie/cachemiss", nil) + cacheUnloadCounter = metrics.NewRegisteredCounter("trie/cacheunload", nil) +) + +type Trie struct { + root node + db kvDatabase.IDriver + originalRoot common.Hash + + cacheGen uint16 + cacheLimit uint16 +} + +func New(root common.Hash, db kvDatabase.IDriver) (*Trie, error) { + trie := &Trie{db: db, originalRoot: root} + if (root != common.Hash{}) && root != emptyRoot { + if db == nil { + panic("trie.New: cannot use existing root without a database") + } + rootNode, err := trie.resolveHash(root[:], nil) + if err != nil { + return nil, err + } + trie.root = rootNode + } + return trie, nil +} + +func (t *Trie) NodeIterator(start []byte) NodeIterator { + return newNodeIterator(t, start) +} + +func (t *Trie) Get(key []byte) []byte { + res, err := t.TryGet(key) + if err != nil { + log.Log.Errorf("Unhandled trie error: %v", err) + } + return res +} + +func (t *Trie) TryGet(key []byte) ([]byte, error) { + key = keyBytesToHex(key) + value, newRoot, didResolve, err := t.tryGet(t.root, key, 0) + if err == nil && didResolve { + t.root = newRoot + } + return value, err +} + +func (t *Trie) tryGet(origNode node, key []byte, pos int) (value []byte, newnode node, didResolve bool, err error) { + switch n := (origNode).(type) { + case nil: + return nil, nil, false, nil + case valueNode: + return n, n, false, nil + case *shortNode: + if len(key)-pos < len(n.Key) || !bytes.Equal(n.Key, key[pos:pos+len(n.Key)]) { + // key not found in trie + return nil, n, false, nil + } + value, newnode, didResolve, err = t.tryGet(n.Val, key, pos+len(n.Key)) + if err == nil && didResolve { + n = n.copy() + n.Val = newnode + n.flags.gen = t.cacheGen + } + return value, n, didResolve, err + case *fullNode: + value, newnode, didResolve, err = t.tryGet(n.Children[key[pos]], key, pos+1) + if err == nil && didResolve { + n = n.copy() + n.flags.gen = t.cacheGen + n.Children[key[pos]] = newnode + } + return value, n, didResolve, err + case hashNode: + child, err := t.resolveHash(n, key[:pos]) + if err != nil { + return nil, n, true, err + } + value, newNode, _, err := t.tryGet(child, key, pos) + return value, newNode, true, err + default: + panic(fmt.Sprintf("%T: invalid node: %v", origNode, origNode)) + } +} + +func (t *Trie) Update(key, value []byte) { + if err := t.TryUpdate(key, value); err != nil { + log.Log.Errorf("Unhandled trie error: %v", err) + } +} + +func (t *Trie) TryUpdate(key, value []byte) error { + k := keyBytesToHex(key) + if len(value) != 0 { + _, n, err := t.insert(t.root, nil, k, valueNode(value)) + if err != nil { + return err + } + t.root = n + } else { + _, n, err := t.delete(t.root, nil, k) + if err != nil { + return err + } + t.root = n + } + return nil +} + +func (t *Trie) insert(n node, prefix, key []byte, value node) (bool, node, error) { + if len(key) == 0 { + if v, ok := n.(valueNode); ok { + return !bytes.Equal(v, value.(valueNode)), value, nil + } + return true, value, nil + } + switch n := n.(type) { + case *shortNode: + matchLen := prefixLen(key, n.Key) + if matchLen == len(n.Key) { + dirty, nn, err := t.insert(n.Val, append(prefix, key[:matchLen]...), key[matchLen:], value) + if !dirty || err != nil { + return false, n, err + } + return true, &shortNode{n.Key, nn, t.newFlag()}, nil + } + branch := &fullNode{flags: t.newFlag()} + var err error + _, branch.Children[n.Key[matchLen]], err = t.insert(nil, append(prefix, n.Key[:matchLen+1]...), n.Key[matchLen+1:], n.Val) + if err != nil { + return false, nil, err + } + _, branch.Children[key[matchLen]], err = t.insert(nil, append(prefix, key[:matchLen+1]...), key[matchLen+1:], value) + if err != nil { + return false, nil, err + } + if matchLen == 0 { + return true, branch, nil + } + return true, &shortNode{key[:matchLen], branch, t.newFlag()}, nil + + case *fullNode: + dirty, nn, err := t.insert(n.Children[key[0]], append(prefix, key[0]), key[1:], value) + if !dirty || err != nil { + return false, n, err + } + n = n.copy() + n.flags = t.newFlag() + n.Children[key[0]] = nn + return true, n, nil + + case nil: + return true, &shortNode{key, value, t.newFlag()}, nil + + case hashNode: + rn, err := t.resolveHash(n, prefix) + if err != nil { + return false, nil, err + } + dirty, nn, err := t.insert(rn, prefix, key, value) + if !dirty || err != nil { + return false, rn, err + } + return true, nn, nil + + default: + panic(fmt.Sprintf("%T: invalid node: %v", n, n)) + } +} + +func (t *Trie) Delete(key []byte) { + if err := t.TryDelete(key); err != nil { + log.Log.Errorf("Unhandled trie error: %v", err) + } +} + +func (t *Trie) TryDelete(key []byte) error { + k := keyBytesToHex(key) + _, n, err := t.delete(t.root, nil, k) + if err != nil { + return err + } + t.root = n + return nil +} + +func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) { + switch n := n.(type) { + case *shortNode: + matchLen := prefixLen(key, n.Key) + if matchLen < len(n.Key) { + return false, n, nil + } + if matchLen == len(key) { + return true, nil, nil + } + + dirty, child, err := t.delete(n.Val, append(prefix, key[:len(n.Key)]...), key[len(n.Key):]) + if !dirty || err != nil { + return false, n, err + } + switch child := child.(type) { + case *shortNode: + return true, &shortNode{concat(n.Key, child.Key...), child.Val, t.newFlag()}, nil + default: + return true, &shortNode{n.Key, child, t.newFlag()}, nil + } + + case *fullNode: + dirty, nn, err := t.delete(n.Children[key[0]], append(prefix, key[0]), key[1:]) + if !dirty || err != nil { + return false, n, err + } + n = n.copy() + n.flags = t.newFlag() + n.Children[key[0]] = nn + + pos := -1 + for i, cld := range n.Children { + if cld != nil { + if pos == -1 { + pos = i + } else { + pos = -2 + break + } + } + } + if pos >= 0 { + if pos != 16 { + cNode, err := t.resolve(n.Children[pos], prefix) + if err != nil { + return false, nil, err + } + if cNode, ok := cNode.(*shortNode); ok { + k := append([]byte{byte(pos)}, cNode.Key...) + return true, &shortNode{k, cNode.Val, t.newFlag()}, nil + } + } + + return true, &shortNode{[]byte{byte(pos)}, n.Children[pos], t.newFlag()}, nil + } + + return true, n, nil + + case valueNode: + return true, nil, nil + + case nil: + return false, nil, nil + + case hashNode: + rn, err := t.resolveHash(n, prefix) + if err != nil { + return false, nil, err + } + dirty, nn, err := t.delete(rn, prefix, key) + if !dirty || err != nil { + return false, rn, err + } + return true, nn, nil + + default: + panic(fmt.Sprintf("%T: invalid node: %v (%v)", n, n, key)) + } +} + +func (t *Trie) Root() []byte { return t.Hash().Bytes() } + +func (t *Trie) Hash() common.Hash { + hash, cached, _ := t.hashRoot(nil) + t.root = cached + return common.BytesToHash(hash.(hashNode)) +} + +func concat(s1 []byte, s2 ...byte) []byte { + r := make([]byte, len(s1)+len(s2)) + copy(r, s1) + copy(r[len(s1):], s2) + return r +} + +func (t *Trie) resolve(n node, prefix []byte) (node, error) { + if n, ok := n.(hashNode); ok { + return t.resolveHash(n, prefix) + } + return n, nil +} + +func (t *Trie) hashRoot(db kvDatabase.IDriver) (node, node, error) { + if t.root == nil { + return hashNode(emptyRoot.Bytes()), nil, nil + } + h := newHasher(t.cacheGen, t.cacheLimit) + defer returnHasherToPool(h) + return h.hash(t.root, db, true) +} + +func (t *Trie) SetCacheLimit(l uint16) { + t.cacheLimit = l +} + +func (t *Trie) newFlag() nodeFlag { + return nodeFlag{dirty: true, gen: t.cacheGen} +} + +func (t *Trie) resolveHash(n hashNode, prefix []byte) (node, error) { + cacheMissCounter.Inc(1) + + enc, err := t.db.Get(n) + if err != nil || !enc.Exists { + return nil, &MissingNodeError{NodeHash: common.BytesToHash(n), Path: prefix} + } + dec := mustDecodeNode(n, enc.Data, t.cacheGen) + return dec, nil +} + +func mustDecodeNode(hash, buf []byte, cacheGen uint16) node { + n, err := decodeNode(hash, buf, cacheGen) + if err != nil { + panic(fmt.Sprintf("node %x: %v", hash, err)) + } + return n +} + +func (t *Trie) CommitTo(db kvDatabase.IDriver) (root common.Hash, err error) { + hash, cached, err := t.hashRoot(db) + if err != nil { + return common.Hash{}, err + } + t.root = cached + t.cacheGen++ + return common.BytesToHash(hash.(hashNode)), nil +} From f8e69b27357334c70882d8c2baae6cc508f08d06 Mon Sep 17 00:00:00 2001 From: bianning Date: Wed, 29 Jun 2022 17:06:51 +0800 Subject: [PATCH 03/20] feat: add state --- dataStructure/state/database.go | 123 +++++++++ dataStructure/state/managed_state.go | 124 +++++++++ dataStructure/state/state_object.go | 300 +++++++++++++++++++++ dataStructure/state/state_test.go | 44 ++++ dataStructure/state/statedb.go | 377 +++++++++++++++++++++++++++ 5 files changed, 968 insertions(+) create mode 100644 dataStructure/state/database.go create mode 100644 dataStructure/state/managed_state.go create mode 100644 dataStructure/state/state_object.go create mode 100644 dataStructure/state/state_test.go create mode 100644 dataStructure/state/statedb.go diff --git a/dataStructure/state/database.go b/dataStructure/state/database.go new file mode 100644 index 0000000..ff2c57b --- /dev/null +++ b/dataStructure/state/database.go @@ -0,0 +1,123 @@ +package state + +import ( + "fmt" + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/dataStructure/trie" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" + lru "github.com/hashicorp/golang-lru" + "sync" +) + +var MaxTrieCacheGen = uint16(120) + +const ( + maxPastTries = 12 + codeSizeCacheSize = 100000 +) + +type Database interface { + OpenTrie(root common.Hash) (Trie, error) + OpenStorageTrie(addrHash, root common.Hash) (Trie, error) + ContractCode(addrHash, codeHash common.Hash) ([]byte, error) + ContractCodeSize(addrHash, codeHash common.Hash) (int, error) + + CopyTrie(Trie) Trie +} + +type Trie interface { + TryGet(key []byte) ([]byte, error) + TryUpdate(key, value []byte) error + TryDelete(key []byte) error + CommitTo(kvDatabase.IDriver) (common.Hash, error) + Hash() common.Hash + NodeIterator(startKey []byte) trie.NodeIterator + GetKey([]byte) []byte +} + +func NewDatabase(db kvDatabase.IDriver) Database { + csc, _ := lru.New(codeSizeCacheSize) + return &cachingDB{db: db, codeSizeCache: csc} +} + +type cachingDB struct { + db kvDatabase.IDriver + mu sync.Mutex + pastTries []*trie.SecureTrie + codeSizeCache *lru.Cache +} + +func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) { + db.mu.Lock() + defer db.mu.Unlock() + + for i := len(db.pastTries) - 1; i >= 0; i-- { + if db.pastTries[i].Hash() == root { + return cachedTrie{db.pastTries[i].Copy(), db}, nil + } + } + tr, err := trie.NewSecure(root, db.db, MaxTrieCacheGen) + if err != nil { + return nil, err + } + return cachedTrie{tr, db}, nil +} + +func (db *cachingDB) pushTrie(t *trie.SecureTrie) { + db.mu.Lock() + defer db.mu.Unlock() + + if len(db.pastTries) >= maxPastTries { + copy(db.pastTries, db.pastTries[1:]) + db.pastTries[len(db.pastTries)-1] = t + } else { + db.pastTries = append(db.pastTries, t) + } +} + +func (db *cachingDB) OpenStorageTrie(addrHash, root common.Hash) (Trie, error) { + return trie.NewSecure(root, db.db, 0) +} + +func (db *cachingDB) CopyTrie(t Trie) Trie { + switch t := t.(type) { + case cachedTrie: + return cachedTrie{t.SecureTrie.Copy(), db} + case *trie.SecureTrie: + return t.Copy() + default: + panic(fmt.Errorf("unknown trie type %T", t)) + } +} + +func (db *cachingDB) ContractCode(addrHash, codeHash common.Hash) ([]byte, error) { + code, err := db.db.Get(codeHash[:]) + if err == nil { + db.codeSizeCache.Add(codeHash, len(code.Data)) + } + return code.Data, err +} + +func (db *cachingDB) ContractCodeSize(addrHash, codeHash common.Hash) (int, error) { + if cached, ok := db.codeSizeCache.Get(codeHash); ok { + return cached.(int), nil + } + code, err := db.ContractCode(addrHash, codeHash) + if err == nil { + db.codeSizeCache.Add(codeHash, len(code)) + } + return len(code), err +} + +type cachedTrie struct { + *trie.SecureTrie + db *cachingDB +} + +func (m cachedTrie) CommitTo(db kvDatabase.IDriver) (common.Hash, error) { + root, err := m.SecureTrie.CommitTo(db) + if err == nil { + m.db.pushTrie(m.SecureTrie) + } + return root, err +} diff --git a/dataStructure/state/managed_state.go b/dataStructure/state/managed_state.go new file mode 100644 index 0000000..2e73fdc --- /dev/null +++ b/dataStructure/state/managed_state.go @@ -0,0 +1,124 @@ +package state + +import "sync" +import "github.com/SealSC/SealABC/common" + +type account struct { + stateObject *stateObject + nStart uint64 + nonces []bool +} + +type ManagedState struct { + *StateDB + + mu sync.RWMutex + + accounts map[common.Address]*account +} + +// ManagedState returns a new managed state with the statedb as it's backing layer +func ManageState(statedb *StateDB) *ManagedState { + return &ManagedState{ + StateDB: statedb.Copy(), + accounts: make(map[common.Address]*account), + } +} + +// SetState sets the backing layer of the managed state +func (ms *ManagedState) SetState(statedb *StateDB) { + ms.mu.Lock() + defer ms.mu.Unlock() + ms.StateDB = statedb +} + +// RemoveNonce removed the nonce from the managed state and all future pending nonces +func (ms *ManagedState) RemoveNonce(addr common.Address, n uint64) { + if ms.hasAccount(addr) { + ms.mu.Lock() + defer ms.mu.Unlock() + + 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 + } + } +} + +// NewNonce returns the new canonical nonce for the managed account +func (ms *ManagedState) NewNonce(addr common.Address) uint64 { + ms.mu.Lock() + defer ms.mu.Unlock() + + account := ms.getAccount(addr) + for i, nonce := range account.nonces { + if !nonce { + return account.nStart + uint64(i) + } + } + account.nonces = append(account.nonces, true) + + return uint64(len(account.nonces)-1) + account.nStart +} + +// GetNonce returns the canonical nonce for the managed or unmanaged account. +// +// Because GetNonce mutates the DB, we must take a write lock. +func (ms *ManagedState) GetNonce(addr common.Address) uint64 { + ms.mu.Lock() + defer ms.mu.Unlock() + + if ms.hasAccount(addr) { + account := ms.getAccount(addr) + return uint64(len(account.nonces)) + account.nStart + } else { + return ms.StateDB.GetNonce(addr) + } +} + +// SetNonce sets the new canonical nonce for the managed state +func (ms *ManagedState) SetNonce(addr common.Address, nonce uint64) { + ms.mu.Lock() + defer ms.mu.Unlock() + + so := ms.GetOrNewStateObject(addr) + so.SetNonce(nonce) + + ms.accounts[addr] = newAccount(so) +} + +// HasAccount returns whether the given address is managed or not +func (ms *ManagedState) HasAccount(addr common.Address) bool { + ms.mu.RLock() + defer ms.mu.RUnlock() + return ms.hasAccount(addr) +} + +func (ms *ManagedState) hasAccount(addr common.Address) bool { + _, ok := ms.accounts[addr] + return ok +} + +// populate the managed state +func (ms *ManagedState) getAccount(addr common.Address) *account { + if account, ok := ms.accounts[addr]; !ok { + so := ms.GetOrNewStateObject(addr) + ms.accounts[addr] = newAccount(so) + } else { + // Always make sure the state account nonce isn't actually higher + // than the tracked one. + so := ms.StateDB.getStateObject(addr) + if so != nil && uint64(len(account.nonces))+account.nStart < so.Nonce() { + ms.accounts[addr] = newAccount(so) + } + + } + + return ms.accounts[addr] +} + +func newAccount(so *stateObject) *account { + return &account{so, so.Nonce(), nil} +} diff --git a/dataStructure/state/state_object.go b/dataStructure/state/state_object.go new file mode 100644 index 0000000..b1bac72 --- /dev/null +++ b/dataStructure/state/state_object.go @@ -0,0 +1,300 @@ +package state + +import ( + "bytes" + "fmt" + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rlp" + "io" + "math/big" +) + +//todo: Hash +var emptyCodeHash = crypto.Keccak256(nil) + +type Code []byte + +func (c Code) String() string { + return string(c) +} + +type Storage map[common.Hash]common.Hash + +func (s Storage) String() (str string) { + for key, value := range s { + str += fmt.Sprintf("%X : %X\n", key, value) + } + + return +} + +func (s Storage) Copy() Storage { + cpy := make(Storage) + for key, value := range s { + cpy[key] = value + } + + return cpy +} + +type stateObject struct { + address common.Address + addrHash common.Hash + data Account + db *StateDB + + dbErr error + + trie Trie + code Code + + cachedStorage Storage // Storage entry cache to avoid duplicate reads + dirtyStorage Storage // Storage entries that need to be flushed to disk + + dirtyCode bool // true if the code was updated + suicided bool + touched bool + deleted bool + onDirty func(addr common.Address) // Callback method to mark a state object newly dirty +} + +type Account struct { + Nonce uint64 + Balance *big.Int + Root common.Hash + CodeHash []byte +} + +func newObject(db *StateDB, address common.Address, data Account, onDirty func(addr common.Address)) *stateObject { + if data.Balance == nil { + data.Balance = new(big.Int) + } + if data.CodeHash == nil { + data.CodeHash = emptyCodeHash + } + return &stateObject{ + db: db, + address: address, + //todo: Hash + addrHash: common.Hash(crypto.Keccak256Hash(address[:])), + data: data, + cachedStorage: make(Storage), + dirtyStorage: make(Storage), + onDirty: onDirty, + } +} + +func (s *stateObject) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, s.data) +} + +func (s *stateObject) empty() bool { + return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash) +} + +func (s *stateObject) Address() common.Address { + return s.address +} + +func (s *stateObject) setError(err error) { + if s.dbErr == nil { + s.dbErr = err + } +} + +func (s *stateObject) Code(db Database) []byte { + if s.code != nil { + return s.code + } + if bytes.Equal(s.CodeHash(), emptyCodeHash) { + return nil + } + code, err := db.ContractCode(s.addrHash, common.BytesToHash(s.CodeHash())) + if err != nil { + s.setError(fmt.Errorf("can't load code hash %x: %v", s.CodeHash(), err)) + } + s.code = code + return code +} + +func (s *stateObject) SetCode(codeHash common.Hash, code []byte) { + s.setCode(codeHash, code) +} + +func (s *stateObject) setCode(codeHash common.Hash, code []byte) { + s.code = code + s.data.CodeHash = codeHash[:] + s.dirtyCode = true + if s.onDirty != nil { + s.onDirty(s.Address()) + s.onDirty = nil + } +} + +func (s *stateObject) SetNonce(nonce uint64) { + s.setNonce(nonce) +} + +func (s *stateObject) setNonce(nonce uint64) { + s.data.Nonce = nonce + if s.onDirty != nil { + s.onDirty(s.Address()) + s.onDirty = nil + } +} + +func (s *stateObject) CodeHash() []byte { + return s.data.CodeHash +} + +func (s *stateObject) Balance() *big.Int { + return s.data.Balance +} + +func (s *stateObject) Nonce() uint64 { + return s.data.Nonce +} + +func (s *stateObject) getTrie(db Database) Trie { + if s.trie == nil { + var err error + s.trie, err = db.OpenStorageTrie(s.addrHash, s.data.Root) + if err != nil { + s.trie, _ = db.OpenStorageTrie(s.addrHash, common.Hash{}) + s.setError(fmt.Errorf("can't create storage trie: %v", err)) + } + } + return s.trie +} + +func (s *stateObject) GetState(db Database, key common.Hash) common.Hash { + value, exists := s.cachedStorage[key] + if exists { + return value + } + enc, err := s.getTrie(db).TryGet(key[:]) + if err != nil { + s.setError(err) + return common.Hash{} + } + if len(enc) > 0 { + _, content, _, err := rlp.Split(enc) + if err != nil { + s.setError(err) + } + value.SetBytes(content) + } + if (value != common.Hash{}) { + s.cachedStorage[key] = value + } + return value +} + +func (s *stateObject) SetState(db Database, key, value common.Hash) { + s.setState(key, value) +} + +func (s *stateObject) setState(key, value common.Hash) { + s.cachedStorage[key] = value + s.dirtyStorage[key] = value + + if s.onDirty != nil { + s.onDirty(s.Address()) + s.onDirty = nil + } +} + +func (s *stateObject) updateTrie(db Database) Trie { + tr := s.getTrie(db) + for key, value := range s.dirtyStorage { + delete(s.dirtyStorage, key) + if (value == common.Hash{}) { + s.setError(tr.TryDelete(key[:])) + continue + } + v, _ := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00")) + s.setError(tr.TryUpdate(key[:], v)) + } + return tr +} + +func (s *stateObject) updateRoot(db Database) { + s.updateTrie(db) + s.data.Root = s.trie.Hash() +} + +func (s *stateObject) CommitTrie(db Database, db2 kvDatabase.IDriver) error { + s.updateTrie(db) + if s.dbErr != nil { + return s.dbErr + } + root, err := s.trie.CommitTo(db2) + if err == nil { + s.data.Root = root + } + return err +} + +func (s *stateObject) markSuicided() { + s.suicided = true + if s.onDirty != nil { + s.onDirty(s.Address()) + s.onDirty = nil + } +} + +func (s *stateObject) touch() { + if s.onDirty != nil { + s.onDirty(s.Address()) + s.onDirty = nil + } + s.touched = true +} + +func (s *stateObject) AddBalance(amount *big.Int) { + if amount.Sign() == 0 { + if s.empty() { + s.touch() + } + + return + } + s.SetBalance(new(big.Int).Add(s.Balance(), amount)) +} + +func (s *stateObject) SubBalance(amount *big.Int) { + if amount.Sign() == 0 { + return + } + s.SetBalance(new(big.Int).Sub(s.Balance(), amount)) +} + +func (s *stateObject) SetBalance(amount *big.Int) { + s.setBalance(amount) +} + +func (s *stateObject) setBalance(amount *big.Int) { + s.data.Balance = amount + if s.onDirty != nil { + s.onDirty(s.Address()) + s.onDirty = nil + } +} + +func (s *stateObject) ReturnGas(gas *big.Int) {} + +func (s *stateObject) deepCopy(db *StateDB, onDirty func(addr common.Address)) *stateObject { + stateObject := newObject(db, s.address, s.data, onDirty) + if s.trie != nil { + stateObject.trie = db.db.CopyTrie(s.trie) + } + stateObject.code = s.code + stateObject.dirtyStorage = s.dirtyStorage.Copy() + stateObject.cachedStorage = s.dirtyStorage.Copy() + stateObject.suicided = s.suicided + stateObject.dirtyCode = s.dirtyCode + stateObject.deleted = s.deleted + return stateObject +} diff --git a/dataStructure/state/state_test.go b/dataStructure/state/state_test.go new file mode 100644 index 0000000..1e3e05e --- /dev/null +++ b/dataStructure/state/state_test.go @@ -0,0 +1,44 @@ +package state + +import ( + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/crypto/hashes" + "github.com/SealSC/SealABC/storage/db" + "github.com/SealSC/SealABC/storage/db/dbDrivers/levelDB" + "github.com/SealSC/SealABC/storage/db/dbInterface" + "math/big" + "testing" +) + +func Test(t *testing.T) { + hashes.Load() + driver, _ := db.NewKVDatabaseDriver(dbInterface.LevelDB, levelDB.Config{ + DBFilePath: "/Users/bianning/Project/Seal/TestDemo/et/temp/nodes/n1-1/chain", + }) + state, _ := New(common.Hash{}, NewDatabase(driver)) + + stateobjaddr0 := common.BytesToAddress([]byte("so0")) + stateobjaddr1 := common.BytesToAddress([]byte("so1")) + var storageaddr common.Hash + + data0 := common.BytesToHash([]byte{17}) + data1 := common.BytesToHash([]byte{18}) + + state.SetState(stateobjaddr0, storageaddr, data0) + state.SetState(stateobjaddr1, storageaddr, data1) + + // db, trie are already non-empty values + so0 := state.getStateObject(stateobjaddr0) + so0.SetBalance(big.NewInt(42)) + so0.SetNonce(43) + //so0.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'}) + so0.suicided = false + so0.deleted = false + state.setStateObject(so0) + + root, _ := state.CommitTo(driver, false) + + t.Log(root) + + t.Log(driver.Stat()) +} diff --git a/dataStructure/state/statedb.go b/dataStructure/state/statedb.go new file mode 100644 index 0000000..5c9457f --- /dev/null +++ b/dataStructure/state/statedb.go @@ -0,0 +1,377 @@ +package state + +import ( + "fmt" + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/dataStructure/trie" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rlp" + + "math/big" + "sync" +) + +type StateDB struct { + db Database + trie Trie + + stateObjects map[common.Address]*stateObject + stateObjectsDirty map[common.Address]struct{} + + dbErr error + + tHash, bHash common.Hash + txIndex int + + lock sync.Mutex +} + +func New(root common.Hash, db Database) (*StateDB, error) { + tr, err := db.OpenTrie(root) + if err != nil { + return nil, err + } + + return &StateDB{ + db: db, + trie: tr, + stateObjects: make(map[common.Address]*stateObject), + stateObjectsDirty: make(map[common.Address]struct{}), + }, nil +} + +func (s *StateDB) setError(err error) { + if s.dbErr == nil { + s.dbErr = err + } +} + +func (s *StateDB) Error() error { + return s.dbErr +} + +func (s *StateDB) Reset(root common.Hash) error { + tr, err := s.db.OpenTrie(root) + if err != nil { + return err + } + s.trie = tr + s.stateObjects = make(map[common.Address]*stateObject) + s.stateObjectsDirty = make(map[common.Address]struct{}) + s.tHash = common.Hash{} + s.bHash = common.Hash{} + s.txIndex = 0 + return nil +} + +func (s *StateDB) Exist(addr common.Address) bool { + return s.getStateObject(addr) != nil +} + +func (s *StateDB) Empty(addr common.Address) bool { + so := s.getStateObject(addr) + return so == nil || so.empty() +} + +func (s *StateDB) GetBalance(addr common.Address) *big.Int { + stateObject := s.getStateObject(addr) + if stateObject != nil { + return stateObject.Balance() + } + return common.Big0 +} + +func (s *StateDB) GetNonce(addr common.Address) uint64 { + stateObject := s.getStateObject(addr) + if stateObject != nil { + return stateObject.Nonce() + } + + return 0 +} + +func (s *StateDB) GetCode(addr common.Address) []byte { + stateObject := s.getStateObject(addr) + if stateObject != nil { + return stateObject.Code(s.db) + } + return nil +} + +func (s *StateDB) GetCodeSize(addr common.Address) int { + stateObject := s.getStateObject(addr) + if stateObject == nil { + return 0 + } + if stateObject.code != nil { + return len(stateObject.code) + } + size, err := s.db.ContractCodeSize(stateObject.addrHash, common.BytesToHash(stateObject.CodeHash())) + if err != nil { + s.setError(err) + } + return size +} + +func (s *StateDB) GetCodeHash(addr common.Address) common.Hash { + stateObject := s.getStateObject(addr) + if stateObject == nil { + return common.Hash{} + } + return common.BytesToHash(stateObject.CodeHash()) +} + +func (s *StateDB) GetState(a common.Address, b common.Hash) common.Hash { + stateObject := s.getStateObject(a) + if stateObject != nil { + return stateObject.GetState(s.db, b) + } + return common.Hash{} +} + +func (s *StateDB) StorageTrie(a common.Address) Trie { + stateObject := s.getStateObject(a) + if stateObject == nil { + return nil + } + cpy := stateObject.deepCopy(s, nil) + return cpy.updateTrie(s.db) +} + +func (s *StateDB) HasSuicided(addr common.Address) bool { + stateObject := s.getStateObject(addr) + if stateObject != nil { + return stateObject.suicided + } + return false +} + +func (s *StateDB) AddBalance(addr common.Address, amount *big.Int) { + stateObject := s.GetOrNewStateObject(addr) + if stateObject != nil { + stateObject.AddBalance(amount) + } +} + +func (s *StateDB) SubBalance(addr common.Address, amount *big.Int) { + stateObject := s.GetOrNewStateObject(addr) + if stateObject != nil { + stateObject.SubBalance(amount) + } +} + +func (s *StateDB) SetBalance(addr common.Address, amount *big.Int) { + stateObject := s.GetOrNewStateObject(addr) + if stateObject != nil { + stateObject.SetBalance(amount) + } +} + +func (s *StateDB) SetNonce(addr common.Address, nonce uint64) { + stateObject := s.GetOrNewStateObject(addr) + if stateObject != nil { + stateObject.SetNonce(nonce) + } +} + +func (s *StateDB) SetCode(addr common.Address, code []byte) { + stateObject := s.GetOrNewStateObject(addr) + if stateObject != nil { + stateObject.SetCode(common.Hash(crypto.Keccak256Hash(code)), code) + } +} + +func (s *StateDB) SetState(addr common.Address, key common.Hash, value common.Hash) { + stateObject := s.GetOrNewStateObject(addr) + if stateObject != nil { + stateObject.SetState(s.db, key, value) + } +} + +func (s *StateDB) Suicide(addr common.Address) bool { + stateObject := s.getStateObject(addr) + if stateObject == nil { + return false + } + stateObject.markSuicided() + stateObject.data.Balance = new(big.Int) + + return true +} + +func (s *StateDB) updateStateObject(stateObject *stateObject) { + addr := stateObject.Address() + data, err := rlp.EncodeToBytes(stateObject) + if err != nil { + panic(fmt.Errorf("can't encode object at %x: %v", addr[:], err)) + } + s.setError(s.trie.TryUpdate(addr[:], data)) +} + +func (s *StateDB) deleteStateObject(stateObject *stateObject) { + stateObject.deleted = true + addr := stateObject.Address() + s.setError(s.trie.TryDelete(addr[:])) +} + +func (s *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) { + if obj := s.stateObjects[addr]; obj != nil { + if obj.deleted { + return nil + } + return obj + } + + enc, err := s.trie.TryGet(addr[:]) + if len(enc) == 0 { + s.setError(err) + return nil + } + var data Account + if err := rlp.DecodeBytes(enc, &data); err != nil { + log.Log.Error("Failed to decode state object", "addr", addr, "err", err) + return nil + } + // Insert into the live set. + obj := newObject(s, addr, data, s.MarkStateObjectDirty) + s.setStateObject(obj) + return obj +} + +func (s *StateDB) setStateObject(object *stateObject) { + s.stateObjects[object.Address()] = object +} + +func (s *StateDB) GetOrNewStateObject(addr common.Address) *stateObject { + stateObject := s.getStateObject(addr) + if stateObject == nil || stateObject.deleted { + stateObject, _ = s.createObject(addr) + } + return stateObject +} + +func (s *StateDB) MarkStateObjectDirty(addr common.Address) { + s.stateObjectsDirty[addr] = struct{}{} +} + +func (s *StateDB) createObject(addr common.Address) (newObj, prev *stateObject) { + prev = s.getStateObject(addr) + newObj = newObject(s, addr, Account{}, s.MarkStateObjectDirty) + newObj.setNonce(0) + s.setStateObject(newObj) + return newObj, prev +} + +func (s *StateDB) CreateAccount(addr common.Address) { + newObj, prev := s.createObject(addr) + if prev != nil { + newObj.setBalance(prev.data.Balance) + } +} + +func (s *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) { + so := s.getStateObject(addr) + if so == nil { + return + } + + for h, value := range so.cachedStorage { + cb(h, value) + } + + it := trie.NewIterator(so.getTrie(s.db).NodeIterator(nil)) + for it.Next() { + key := common.BytesToHash(s.trie.GetKey(it.Key)) + if _, ok := so.cachedStorage[key]; !ok { + cb(key, common.BytesToHash(it.Value)) + } + } +} + +func (s *StateDB) Copy() *StateDB { + s.lock.Lock() + defer s.lock.Unlock() + + state := &StateDB{ + db: s.db, + trie: s.trie, + stateObjects: make(map[common.Address]*stateObject, len(s.stateObjectsDirty)), + stateObjectsDirty: make(map[common.Address]struct{}, len(s.stateObjectsDirty)), + } + for addr := range s.stateObjectsDirty { + state.stateObjects[addr] = s.stateObjects[addr].deepCopy(state, state.MarkStateObjectDirty) + state.stateObjectsDirty[addr] = struct{}{} + } + return state +} + +func (s *StateDB) Finalise(deleteEmptyObjects bool) { + for addr := range s.stateObjectsDirty { + stateObject := s.stateObjects[addr] + if stateObject.suicided || (deleteEmptyObjects && stateObject.empty()) { + s.deleteStateObject(stateObject) + } else { + stateObject.updateRoot(s.db) + s.updateStateObject(stateObject) + } + } +} + +func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { + s.Finalise(deleteEmptyObjects) + return s.trie.Hash() +} + +func (s *StateDB) Prepare(tHash, bHash common.Hash, ti int) { + s.tHash = tHash + s.bHash = bHash + s.txIndex = ti +} + +func (s *StateDB) DeleteSuicides() { + + for addr := range s.stateObjectsDirty { + stateObject := s.stateObjects[addr] + + if stateObject.suicided { + stateObject.deleted = true + } + delete(s.stateObjectsDirty, addr) + } +} + +func (s *StateDB) CommitTo(db kvDatabase.IDriver, deleteEmptyObjects bool) (root common.Hash, err error) { + var kvList []kvDatabase.KVItem + for addr, stateObject := range s.stateObjects { + _, isDirty := s.stateObjectsDirty[addr] + switch { + case stateObject.suicided || (isDirty && deleteEmptyObjects && stateObject.empty()): + s.deleteStateObject(stateObject) + case isDirty: + if stateObject.code != nil && stateObject.dirtyCode { + kvList = append(kvList, kvDatabase.KVItem{ + Key: stateObject.CodeHash(), + Data: stateObject.code, + }) + stateObject.dirtyCode = false + } + if err := stateObject.CommitTrie(s.db, db); err != nil { + return common.Hash{}, err + } + s.updateStateObject(stateObject) + } + + delete(s.stateObjectsDirty, addr) + } + + err = db.BatchPut(kvList) + if err != nil { + return common.Hash{}, err + } + + root, err = s.trie.CommitTo(db) + + return root, err +} From 3c8c2665ff8d5aab6a0b957a8133161ad1d54985 Mon Sep 17 00:00:00 2001 From: bianning Date: Wed, 29 Jun 2022 17:14:29 +0800 Subject: [PATCH 04/20] feat: add stateroot to metadata --- metadata/block/entity.go | 30 +++++------ metadata/seal/entity.go | 110 +++++++++++++++++++-------------------- 2 files changed, 70 insertions(+), 70 deletions(-) diff --git a/metadata/block/entity.go b/metadata/block/entity.go index 1ce93d9..f482e32 100644 --- a/metadata/block/entity.go +++ b/metadata/block/entity.go @@ -18,32 +18,32 @@ package block import ( - "github.com/SealSC/SealABC/metadata/blockchainRequest" - "github.com/SealSC/SealABC/metadata/seal" + "github.com/SealSC/SealABC/metadata/blockchainRequest" + "github.com/SealSC/SealABC/metadata/seal" ) type Header struct { - Version string - Height uint64 - PrevBlock []byte - TransactionsRoot []byte - Timestamp uint64 + Version string + Height uint64 + PrevBlock []byte + TransactionsRoot []byte + StateRoot []byte + Timestamp uint64 } type Body struct { - RequestsCount int - Requests []blockchainRequest.Entity + RequestsCount int + Requests []blockchainRequest.Entity } type EntityData struct { - Header Header - Body Body + Header Header + Body Body } type Entity struct { - EntityData + EntityData - Seal seal.Entity - BlankSeal seal.Entity + Seal seal.Entity + BlankSeal seal.Entity } - diff --git a/metadata/seal/entity.go b/metadata/seal/entity.go index 3fc3890..c1724c8 100644 --- a/metadata/seal/entity.go +++ b/metadata/seal/entity.go @@ -18,83 +18,83 @@ package seal import ( - "github.com/SealSC/SealABC/crypto" - "github.com/SealSC/SealABC/crypto/hashes" - "github.com/SealSC/SealABC/crypto/signers" - "bytes" - "encoding/hex" - "errors" + "bytes" + "encoding/hex" + "errors" + "github.com/SealSC/SealABC/crypto" + "github.com/SealSC/SealABC/crypto/hashes" + "github.com/SealSC/SealABC/crypto/signers" ) type Entity struct { - Hash []byte - Signature []byte - SignerPublicKey []byte - SignerAlgorithm string + Hash []byte + Signature []byte + SignerPublicKey []byte + SignerAlgorithm string } func (e *Entity) IsPureEmpty() bool { - return len(e.Hash) == 0 && - len(e.Signature) == 0 && - len(e.SignerPublicKey) == 0 && - e.SignerAlgorithm == "" + return len(e.Hash) == 0 && + len(e.Signature) == 0 && + len(e.SignerPublicKey) == 0 && + e.SignerAlgorithm == "" } func (e *Entity) HexHash() string { - return hex.EncodeToString(e.Hash) + return hex.EncodeToString(e.Hash) } func (e *Entity) HexPublicKey() string { - return hex.EncodeToString(e.SignerPublicKey) + return hex.EncodeToString(e.SignerPublicKey) } func (e *Entity) HexSignature() string { - return hex.EncodeToString(e.Signature) + return hex.EncodeToString(e.Signature) } func (e *Entity) Sign(orgData []byte, tools crypto.Tools, privateKey interface{}) (err error) { - s, err := tools.SignerGenerator.FromRawPrivateKey(privateKey) - if err != nil { - return - } + s, err := tools.SignerGenerator.FromRawPrivateKey(privateKey) + if err != nil { + return + } - e.Hash = tools.HashCalculator.Sum(orgData) - e.Signature, err = s.Sign(e.Hash) - if err != nil { - return - } + e.Hash = tools.HashCalculator.Sum(orgData) + e.Signature, err = s.Sign(e.Hash) + if err != nil { + return + } - e.SignerAlgorithm = tools.SignerGenerator.Type() - e.SignerPublicKey = s.PublicKeyBytes() + e.SignerAlgorithm = tools.SignerGenerator.Type() + e.SignerPublicKey = s.PublicKeyBytes() - return + return } func (e Entity) Verify(orgData []byte, hashCalc hashes.IHashCalculator) (passed bool, err error) { - passed = false - - hash := hashCalc.Sum(orgData) - if !bytes.Equal(hash, e.Hash) { - err = errors.New("hash not equal: " + hex.EncodeToString(hash) + " vs " + hex.EncodeToString(e.Hash) ) - return - } - - signerGen := signers.SignerGeneratorByAlgorithmType(e.SignerAlgorithm) - if signerGen == nil { - err = errors.New("unsupported signature algorithm:" + e.SignerAlgorithm) - return - } - - signer, err := signerGen.FromRawPublicKey(e.SignerPublicKey) - if err != nil { - err = errors.New("invalid seal's public key") - return - } - - passed, err = signer.Verify(hash, e.Signature) - if !passed { - err = errors.New("invalid seal signature") - } - - return + passed = false + + hash := hashCalc.Sum(orgData) + if !bytes.Equal(hash, e.Hash) { + err = errors.New("hash not equal: " + hex.EncodeToString(hash) + " vs " + hex.EncodeToString(e.Hash)) + return + } + + signerGen := signers.SignerGeneratorByAlgorithmType(e.SignerAlgorithm) + if signerGen == nil { + err = errors.New("unsupported signature algorithm:" + e.SignerAlgorithm) + return + } + + signer, err := signerGen.FromRawPublicKey(e.SignerPublicKey) + if err != nil { + err = errors.New("invalid seal's public key") + return + } + + passed, err = signer.Verify(hash, e.Signature) + if !passed { + err = errors.New("invalid seal signature") + } + + return } From 3cba674cab8b18075bd8250860af327dacc2e109 Mon Sep 17 00:00:00 2001 From: bianning Date: Wed, 29 Jun 2022 17:15:58 +0800 Subject: [PATCH 05/20] feat: add txpool --- .../smartAssets/smartAssetsLedger/tx_list.go | 227 +++++++++++++++++ .../smartAssets/smartAssetsLedger/txpool.go | 229 ++++++++++++++++++ 2 files changed, 456 insertions(+) create mode 100644 service/application/smartAssets/smartAssetsLedger/tx_list.go create mode 100644 service/application/smartAssets/smartAssetsLedger/txpool.go diff --git a/service/application/smartAssets/smartAssetsLedger/tx_list.go b/service/application/smartAssets/smartAssetsLedger/tx_list.go new file mode 100644 index 0000000..de1b94d --- /dev/null +++ b/service/application/smartAssets/smartAssetsLedger/tx_list.go @@ -0,0 +1,227 @@ +package smartAssetsLedger + +import ( + //"container/heap" + "container/heap" + "sort" +) + +type nonceHeap []uint64 + +func (h nonceHeap) Len() int { return len(h) } +func (h nonceHeap) Less(i, j int) bool { return h[i] < h[j] } +func (h nonceHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } + +func (h *nonceHeap) Push(x interface{}) { + *h = append(*h, x.(uint64)) +} + +func (h *nonceHeap) Pop() interface{} { + old := *h + n := len(old) + x := old[n-1] + *h = old[0 : n-1] + return x +} + +type Transactions []*Transaction + +func (s Transactions) Len() int { return len(s) } + +func (s Transactions) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +type TxByNonce Transactions + +func (s TxByNonce) Len() int { return len(s) } +func (s TxByNonce) Less(i, j int) bool { return s[i].Nonce < s[j].Nonce } +func (s TxByNonce) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +type txSortedMap struct { + items map[uint64]*Transaction + index *nonceHeap + cache Transactions +} + +func newTxSortedMap() *txSortedMap { + return &txSortedMap{ + items: make(map[uint64]*Transaction), + index: new(nonceHeap), + } +} + +func (m *txSortedMap) Get(nonce uint64) *Transaction { + return m.items[nonce] +} + +func (m *txSortedMap) Put(tx *Transaction) { + nonce := tx.Nonce + if m.items[nonce] == nil { + heap.Push(m.index, nonce) + } + m.items[nonce], m.cache = tx, nil +} + +func (m *txSortedMap) Forward(threshold uint64) Transactions { + var removed Transactions + + for m.index.Len() > 0 && (*m.index)[0] < threshold { + nonce := heap.Pop(m.index).(uint64) + removed = append(removed, m.items[nonce]) + delete(m.items, nonce) + } + if m.cache != nil { + m.cache = m.cache[len(removed):] + } + return removed +} + +func (m *txSortedMap) Filter(filter func(*Transaction) bool) Transactions { + var removed Transactions + + for nonce, tx := range m.items { + if filter(tx) { + removed = append(removed, tx) + delete(m.items, nonce) + } + } + if len(removed) > 0 { + *m.index = make([]uint64, 0, len(m.items)) + for nonce := range m.items { + *m.index = append(*m.index, nonce) + } + heap.Init(m.index) + + m.cache = nil + } + return removed +} + +func (m *txSortedMap) Cap(threshold int) Transactions { + if len(m.items) <= threshold { + return nil + } + + var drops Transactions + + sort.Sort(*m.index) + for size := len(m.items); size > threshold; size-- { + drops = append(drops, m.items[(*m.index)[size-1]]) + delete(m.items, (*m.index)[size-1]) + } + *m.index = (*m.index)[:threshold] + heap.Init(m.index) + + if m.cache != nil { + m.cache = m.cache[:len(m.cache)-len(drops)] + } + return drops +} + +func (m *txSortedMap) Remove(nonce uint64) bool { + _, ok := m.items[nonce] + if !ok { + return false + } + for i := 0; i < m.index.Len(); i++ { + if (*m.index)[i] == nonce { + heap.Remove(m.index, i) + break + } + } + delete(m.items, nonce) + m.cache = nil + + return true +} + +func (m *txSortedMap) Ready(start uint64) Transactions { + if m.index.Len() == 0 || (*m.index)[0] > start { + return nil + } + + var ready Transactions + for next := (*m.index)[0]; m.index.Len() > 0 && (*m.index)[0] == next; next++ { + ready = append(ready, m.items[next]) + delete(m.items, next) + heap.Pop(m.index) + } + + m.cache = nil + + return ready +} + +func (m *txSortedMap) Len() int { + return len(m.items) +} + +func (m *txSortedMap) Flatten() Transactions { + if m.cache == nil { + m.cache = make(Transactions, 0, len(m.items)) + for _, tx := range m.items { + m.cache = append(m.cache, tx) + } + sort.Sort(TxByNonce(m.cache)) + } + + txs := make(Transactions, len(m.cache)) + copy(txs, m.cache) + return txs +} + +type txList struct { + strict bool + txs *txSortedMap +} + +func newTxList(strict bool) *txList { + return &txList{ + strict: strict, + txs: newTxSortedMap(), + } +} + +func (l *txList) Overlaps(tx *Transaction) bool { + return l.txs.Get(tx.Nonce) != nil +} + +func (l *txList) Add(tx *Transaction) *Transaction { + old := l.txs.Get(tx.Nonce) + l.txs.Put(tx) + return old +} + +func (l *txList) Forward(threshold uint64) Transactions { + return l.txs.Forward(threshold) +} + +func (l *txList) Cap(threshold int) Transactions { + return l.txs.Cap(threshold) +} + +func (l *txList) Remove(tx *Transaction) (bool, Transactions) { + nonce := tx.Nonce + if removed := l.txs.Remove(nonce); !removed { + return false, nil + } + if l.strict { + return true, l.txs.Filter(func(tx *Transaction) bool { return tx.Nonce > nonce }) + } + return true, nil +} + +func (l *txList) Ready(start uint64) Transactions { + return l.txs.Ready(start) +} + +func (l *txList) Len() int { + return l.txs.Len() +} + +func (l *txList) Empty() bool { + return l.Len() == 0 +} + +func (l *txList) Flatten() Transactions { + return l.txs.Flatten() +} diff --git a/service/application/smartAssets/smartAssetsLedger/txpool.go b/service/application/smartAssets/smartAssetsLedger/txpool.go new file mode 100644 index 0000000..0daa72f --- /dev/null +++ b/service/application/smartAssets/smartAssetsLedger/txpool.go @@ -0,0 +1,229 @@ +package smartAssetsLedger + +import ( + "errors" + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/dataStructure/state" + "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" + "math/big" + "sync" +) + +var ( + ErrNonceTooLow = errors.New("nonce too low") + ErrNegativeValue = errors.New("negative value") +) + +type TxPool struct { + chain chainStructure.IChainInterface + + pending map[common.Address]*txList + queue map[common.Address]*txList + all map[common.Hash]*Transaction + + currentState *state.StateDB + pendingState *state.ManagedState + + mu sync.RWMutex +} + +func NewTxPool() *TxPool { + pool := &TxPool{ + mu: sync.RWMutex{}, + + pending: make(map[common.Address]*txList), + queue: make(map[common.Address]*txList), + all: make(map[common.Hash]*Transaction), + } + + return pool +} + +func (pool *TxPool) setChain(chain chainStructure.IChainInterface, stateDB *state.StateDB) { + pool.chain = chain + pool.currentState = stateDB + pool.pendingState = state.ManageState(stateDB) +} + +func (pool *TxPool) len() int { + return len(pool.all) +} + +func (pool *TxPool) Get(hash common.Hash) *Transaction { + pool.mu.RLock() + defer pool.mu.RUnlock() + + return pool.all[hash] +} + +func (pool *TxPool) addTx(tx *Transaction) error { + pool.mu.Lock() + defer pool.mu.Unlock() + + replaced, err := pool.add(tx) + if err != nil { + return err + } + + if !replaced { + pool.promoteExecutables(common.BytesToAddress(tx.From)) + } + + return nil +} + +func (pool *TxPool) add(tx *Transaction) (bool, error) { + hash := tx.getCommonHash() + + err := pool.validateTx(tx) + if err != nil { + return false, err + } + + from := common.BytesToAddress(tx.From) + if list := pool.pending[from]; list != nil && list.Overlaps(tx) { + old := list.Add(tx) + + if old != nil { + delete(pool.all, old.getCommonHash()) + } + pool.all[tx.getCommonHash()] = tx + + return old != nil, nil + } + + replace, err := pool.enqueueTx(hash, tx) + if err != nil { + return false, err + } + return replace, nil +} + +func (pool *TxPool) validateTx(tx *Transaction) error { + amount, _ := big.NewInt(0).SetString(string(tx.Value), 10) + if amount.Sign() < 0 { + return ErrNegativeValue + } + + from := common.BytesToAddress(tx.From) + if pool.currentState.GetNonce(from) > tx.Nonce { + return ErrNonceTooLow + } + + return nil +} + +func (pool *TxPool) promoteExecutables(addr common.Address) { + + list := pool.queue[addr] + if list == nil { + return + } + + for _, tx := range list.Forward(pool.currentState.GetNonce(addr)) { + hash := tx.getCommonHash() + delete(pool.all, hash) + } + + for _, tx := range list.Ready(pool.pendingState.GetNonce(addr)) { + hash := tx.getCommonHash() + pool.promoteTx(addr, hash, tx) + } + + if list.Empty() { + delete(pool.queue, addr) + } +} + +func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *Transaction) { + if pool.pending[addr] == nil { + pool.pending[addr] = newTxList(true) + } + list := pool.pending[addr] + + old := list.Add(tx) + if old != nil { + delete(pool.all, old.getCommonHash()) + } + + if pool.all[hash] == nil { + pool.all[hash] = tx + } + + pool.pendingState.SetNonce(addr, tx.Nonce+1) +} + +func (pool *TxPool) removeTx(hash common.Hash) { + tx, ok := pool.all[hash] + if !ok { + return + } + addr := common.BytesToAddress(tx.From) + + delete(pool.all, hash) + + if pending := pool.pending[addr]; pending != nil { + if removed, _ := pending.Remove(tx); removed { + if pending.Empty() { + delete(pool.pending, addr) + } else { + //for _, tx := range invalids { + // + //} + } + + if nonce := tx.Nonce; pool.pendingState.GetNonce(addr) > nonce { + pool.pendingState.SetNonce(addr, nonce) + } + return + } + } + + //if future := pool.queue[addr]; future != nil { + // future.Remove(tx) + // if future.Empty() { + // delete(pool.queue, addr) + // } + //} +} + +func (pool *TxPool) enqueueTx(hash common.Hash, tx *Transaction) (bool, error) { + from := common.BytesToAddress(tx.From) + if pool.queue[from] == nil { + pool.queue[from] = newTxList(false) + } + + old := pool.queue[from].Add(tx) + if old != nil { + delete(pool.all, old.getCommonHash()) + } + + pool.all[hash] = tx + return old != nil, nil +} + +func (pool *TxPool) removeUnenforceable() { + for addr, list := range pool.pending { + nonce := pool.currentState.GetNonce(addr) + + for _, tx := range list.Forward(nonce) { + hash := tx.getCommonHash() + delete(pool.all, hash) + } + + if list.Empty() { + delete(pool.pending, addr) + } + } +} + +func (pool *TxPool) Pending() Transactions { + pool.mu.Lock() + defer pool.mu.Unlock() + + var pending Transactions + for _, list := range pool.pending { + pending = append(pending, list.Flatten()...) + } + return pending +} From 44baac16aab316fa66efd8146342c76f782084ee Mon Sep 17 00:00:00 2001 From: bianning Date: Wed, 29 Jun 2022 17:20:26 +0800 Subject: [PATCH 06/20] feat: add account state and transaction pool to smartAssetsLedger --- service/application/smartAssets/service.go | 14 +- .../smartAssetsInterface.go | 53 ++-- .../smartAssets/smartAssetsLedger/assets.go | 18 +- .../smartAssetsLedger/evmAdapter.go | 14 +- .../smartAssets/smartAssetsLedger/ledger.go | 234 +++++++++++++----- .../smartAssetsLedger/operationForQuery.go | 19 +- .../smartAssetsLedger/operationForTransfer.go | 17 +- .../smartAssets/smartAssetsLedger/query.go | 5 +- .../smartAssetsLedger/transaction.go | 30 ++- 9 files changed, 271 insertions(+), 133 deletions(-) diff --git a/service/application/smartAssets/service.go b/service/application/smartAssets/service.go index 4b286d3..9700abc 100644 --- a/service/application/smartAssets/service.go +++ b/service/application/smartAssets/service.go @@ -28,13 +28,6 @@ import ( "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" ) -func Load() { - smartAssetsInterface.Load() - smartAssetsLedger.Load() - smartAssetsSQLTables.Load() - smartAssetsSQLStorage.Load() -} - func NewSmartAssetsApplication(config *Config) (app chainStructure.IBlockchainExternalApplication, err error) { if config == nil { config = DefaultConfig() @@ -54,3 +47,10 @@ func NewSmartAssetsApplication(config *Config) (app chainStructure.IBlockchainEx app, err = smartAssetsInterface.NewApplicationInterface(kvDriver, sqlDriver, config.CryptoTools, config.BaseAssets) return } + +func Load() { + smartAssetsInterface.Load() + smartAssetsLedger.Load() + smartAssetsSQLTables.Load() + smartAssetsSQLStorage.Load() +} diff --git a/service/application/smartAssets/smartAssetsInterface/smartAssetsInterface.go b/service/application/smartAssets/smartAssetsInterface/smartAssetsInterface.go index bc7cc00..0cb3ce4 100644 --- a/service/application/smartAssets/smartAssetsInterface/smartAssetsInterface.go +++ b/service/application/smartAssets/smartAssetsInterface/smartAssetsInterface.go @@ -18,6 +18,8 @@ package smartAssetsInterface import ( + "encoding/hex" + "encoding/json" "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" "github.com/SealSC/SealABC/crypto" "github.com/SealSC/SealABC/log" @@ -31,13 +33,11 @@ import ( "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "encoding/hex" - "encoding/json" ) type SmartAssetsApplication struct { chainStructure.BlankApplication - ledger *smartAssetsLedger.Ledger + ledger *smartAssetsLedger.Ledger sqlStorage *smartAssetsSQLStorage.Storage } @@ -93,7 +93,10 @@ func (s *SmartAssetsApplication) Execute( } _, err = s.ledger.Execute(txList, blk) - if err == nil && s.sqlStorage != nil{ + + result.Data, _ = s.ledger.StateDB.CommitTo(s.ledger.Storage, true) + + if err == nil && s.sqlStorage != nil { for _, tx := range txList.Transactions { _ = s.sqlStorage.StoreTransaction(tx, blk) } @@ -104,6 +107,7 @@ func (s *SmartAssetsApplication) Execute( func (s *SmartAssetsApplication) RequestsForBlock(blk block.Entity) (reqList []blockchainRequest.Entity, cnt uint32) { txList, cnt, txRoot := s.ledger.GetTransactionsFromPool(blk) + if cnt == 0 { return } @@ -119,7 +123,7 @@ func (s *SmartAssetsApplication) RequestsForBlock(blk block.Entity) (reqList []b Packed: true, PackedCount: cnt, - Seal: seal.Entity{ + Seal: seal.Entity{ Hash: txRoot, //use merkle tree root as seal hash for packed actions Signature: nil, SignerPublicKey: nil, @@ -136,7 +140,7 @@ func (s *SmartAssetsApplication) Information() (info service.BasicInformation) { info.Api.Protocol = service.ApiProtocols.INTERNAL.String() info.Api.Address = "" - info.Api.ApiList = []service.ApiInterface {} + info.Api.ApiList = []service.ApiInterface{} return } @@ -144,9 +148,9 @@ func (s *SmartAssetsApplication) SetChainInterface(ci chainStructure.IChainInter s.ledger.SetChain(ci) } -func (s *SmartAssetsApplication) UnpackingActionsAsRequests(req blockchainRequest.Entity) (list []blockchainRequest.Entity, err error){ +func (s *SmartAssetsApplication) UnpackingActionsAsRequests(req blockchainRequest.Entity) (list []blockchainRequest.Entity, err error) { if !req.Packed { - list = []blockchainRequest.Entity {req} + list = []blockchainRequest.Entity{req} return } @@ -182,14 +186,14 @@ func (s *SmartAssetsApplication) GetActionAsRequest(req blockchainRequest.Entity return newReq } -func Load() {} +func Load() {} func NewApplicationInterface( kvDriver kvDatabase.IDriver, sqlDriver simpleSQLDatabase.IDriver, tools crypto.Tools, assets smartAssetsLedger.BaseAssetsData, - ) (app chainStructure.IBlockchainExternalApplication, err error) { +) (app chainStructure.IBlockchainExternalApplication, err error) { sa := SmartAssetsApplication{} sa.ledger = smartAssetsLedger.NewLedger(tools, kvDriver) @@ -203,22 +207,27 @@ func NewApplicationInterface( return } - err = sa.ledger.LoadGenesisAssets(ownerBytes, assets) + err = sa.ledger.NewStateAndLoadGenesisAssets(ownerBytes, assets) if err != nil { return } - ownerBalance, err := sa.ledger.BalanceOf(ownerBytes) - if err != nil { - return - } - - if sqlDriver != nil { - err = sa.sqlStorage.StoreSystemIssueBalance(ownerBalance, assets.Owner) - if err != nil { - return - } - } + //err = sa.ledger.LoadGenesisAssets(ownerBytes, assets) + //if err != nil { + // return + //} + + //ownerBalance, err := sa.ledger.BalanceOf(ownerBytes) + //if err != nil { + // return + //} + // + //if sqlDriver != nil { + // err = sa.sqlStorage.StoreSystemIssueBalance(ownerBalance, assets.Owner) + // if err != nil { + // return + // } + //} app = &sa return diff --git a/service/application/smartAssets/smartAssetsLedger/assets.go b/service/application/smartAssets/smartAssetsLedger/assets.go index 76a8f6b..d6e6aea 100644 --- a/service/application/smartAssets/smartAssetsLedger/assets.go +++ b/service/application/smartAssets/smartAssetsLedger/assets.go @@ -18,9 +18,10 @@ package smartAssetsLedger import ( + "encoding/json" + "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/metadata/seal" "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" - "encoding/json" "math/big" ) @@ -45,17 +46,12 @@ func (b *BaseAssets) getHash() []byte { } func (l *Ledger) BalanceOf(address []byte) (balance *big.Int, err error) { - balanceKey := BuildKey(StoragePrefixes.Balance, address) - bKV, err := l.Storage.Get(balanceKey) - if err != nil { - return - } - - if !bKV.Exists { - return big.NewInt(0), nil - } + balance = l.StateDB.GetBalance(common.BytesToAddress(address)) + return +} - balance = big.NewInt(0).SetBytes(bKV.Data) +func (l *Ledger) NonceOf(address []byte) (nonce uint64) { + nonce = l.StateDB.GetNonce(common.BytesToAddress(address)) return } diff --git a/service/application/smartAssets/smartAssetsLedger/evmAdapter.go b/service/application/smartAssets/smartAssetsLedger/evmAdapter.go index ea0b7a1..7eb930c 100644 --- a/service/application/smartAssets/smartAssetsLedger/evmAdapter.go +++ b/service/application/smartAssets/smartAssetsLedger/evmAdapter.go @@ -18,19 +18,20 @@ package smartAssetsLedger import ( + "bytes" + "fmt" "github.com/SealSC/SealABC/metadata/block" "github.com/SealSC/SealEVM" "github.com/SealSC/SealEVM/common" "github.com/SealSC/SealEVM/environment" "github.com/SealSC/SealEVM/evmInt256" "github.com/SealSC/SealEVM/storage" - "bytes" - "fmt" "math/big" "sort" ) const defaultStackDepth = 1000 + func constTransactionGasPrice() *evmInt256.Int { return evmInt256.New(1) } @@ -38,7 +39,7 @@ func constTransactionGasLimit() *evmInt256.Int { return evmInt256.New(100000000) } -func (l Ledger)newEVM(tx Transaction, callback SealEVM.EVMResultCallback, +func (l Ledger) newEVM(tx Transaction, callback SealEVM.EVMResultCallback, blk block.Entity, blockGasLimit *evmInt256.Int) (*SealEVM.EVM, *environment.Contract, error) { evmTransaction := environment.Transaction{ @@ -77,8 +78,8 @@ func (l Ledger)newEVM(tx Transaction, callback SealEVM.EVMResultCallback, MaxStackDepth: defaultStackDepth, ExternalStore: &l.storageForEVM, ResultCallback: callback, - Context: &environment.Context{ - Block: environment.Block{ + Context: &environment.Context{ + Block: environment.Block{ Coinbase: common.BytesDataToEVMIntHash(blk.BlankSeal.SignerPublicKey), Timestamp: evmInt256.New(int64(blk.Header.Timestamp)), Number: evmInt256.New(int64(blk.Header.Height)), @@ -88,7 +89,7 @@ func (l Ledger)newEVM(tx Transaction, callback SealEVM.EVMResultCallback, }, Contract: contract, Transaction: evmTransaction, - Message: environment.Message { + Message: environment.Message{ Caller: caller, Value: evmInt256.FromDecimalString(tx.Value), Data: tx.Data, @@ -120,7 +121,6 @@ func (l Ledger) processEVMBalanceCache(cache storage.BalanceCache, resultCache t continue } - resultCache[string(addr)] = &txResultCacheData{ val: localBalance, } diff --git a/service/application/smartAssets/smartAssetsLedger/ledger.go b/service/application/smartAssets/smartAssetsLedger/ledger.go index 20a14a2..5e4b56d 100644 --- a/service/application/smartAssets/smartAssetsLedger/ledger.go +++ b/service/application/smartAssets/smartAssetsLedger/ledger.go @@ -18,28 +18,30 @@ package smartAssetsLedger import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" "github.com/SealSC/SealABC/crypto" "github.com/SealSC/SealABC/dataStructure/enum" "github.com/SealSC/SealABC/dataStructure/merkleTree" + "github.com/SealSC/SealABC/dataStructure/state" + "github.com/SealSC/SealABC/log" "github.com/SealSC/SealABC/metadata/block" "github.com/SealSC/SealABC/metadata/blockchainRequest" "github.com/SealSC/SealABC/metadata/seal" "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" - "bytes" - "encoding/json" - "errors" - "fmt" "math/big" "sync" ) type Ledger struct { - txPool map[string] *Transaction - txPoolRecord []string + txPool *TxPool txPoolLimit int - clientTxCount map[string] int + clientTxCount map[string]int clientTxLimit int operateLock sync.RWMutex @@ -47,14 +49,16 @@ type Ledger struct { genesisAssets BaseAssets - preActuators map[string] txPreActuator - queryActuators map[string] queryActuator + preActuators map[string]txPreActuator + queryActuators map[string]queryActuator - chain chainStructure.IChainInterface - CryptoTools crypto.Tools - Storage kvDatabase.IDriver + chain chainStructure.IChainInterface + CryptoTools crypto.Tools + Storage kvDatabase.IDriver storageForEVM contractStorage + + StateDB *state.StateDB } func Load() { @@ -65,11 +69,23 @@ func Load() { enum.BuildErrorEnum(&Errors, 1000) } -func (l *Ledger) SetChain(chain chainStructure.IChainInterface) { +func (l *Ledger) SetChain(chain chainStructure.IChainInterface) { l.chain = chain + + if chain.GetLastBlock() != nil { + stateRoot := common.BytesToHash(chain.GetLastBlock().Header.StateRoot) + stateDB, err := state.New(stateRoot, state.NewDatabase(l.Storage)) + if err != nil { + log.Log.Error("Failed to reset txpool state", "err", err) + } + + l.StateDB = stateDB + } + + l.txPool.setChain(chain, l.StateDB) } -func (l *Ledger) LoadGenesisAssets(owner []byte, assets BaseAssetsData) error { +func (l *Ledger) NewStateAndLoadGenesisAssets(owner []byte, assets BaseAssetsData) (err error) { _, exists, err := l.getSystemAssets() if err != nil { return err @@ -79,7 +95,22 @@ func (l *Ledger) LoadGenesisAssets(owner []byte, assets BaseAssetsData) error { return nil } - //if not exists, create + if len(owner) == 0 { + return errors.New("no owner for system assets") + } + + stateDB, err := state.New(common.Hash{}, state.NewDatabase(l.Storage)) + if err != nil { + return err + } + l.StateDB = stateDB + + addr := common.BytesToAddress(owner) + exist := stateDB.Exist(addr) + if exist { + return + } + supply := assets.Supply assets.Supply = "0" @@ -128,15 +159,80 @@ func (l *Ledger) LoadGenesisAssets(owner []byte, assets BaseAssetsData) error { return errors.New("supply is zero or negative") } - err = l.Storage.Put(kvDatabase.KVItem{ - Key: BuildKey(StoragePrefixes.Balance, owner), - Data: balance.Bytes(), - Exists: false, - }) + stateDB.AddBalance(addr, balance) + stateDB.SetNonce(addr, 0) - return err + return } +//func (l *Ledger) LoadGenesisAssets(owner []byte, assets BaseAssetsData) error { +// _, exists, err := l.getSystemAssets() +// if err != nil { +// return err +// } +// +// if exists { +// return nil +// } +// +// //if not exists, create +// supply := assets.Supply +// assets.Supply = "0" +// +// if len(owner) == 0 { +// return errors.New("no owner for system assets") +// } +// +// signer, err := l.CryptoTools.SignerGenerator.NewSigner(nil) +// if err != nil { +// return err +// } +// +// pk := signer.PrivateKeyBytes() +// metaBytes, _ := structSerializer.ToMFBytes(assets) +// metaSeal := seal.Entity{} +// err = metaSeal.Sign(metaBytes, l.CryptoTools, pk) +// if err != nil { +// return err +// } +// +// assets.Supply = supply +// issuedBytes, _ := structSerializer.ToMFBytes(assets) +// issuedSeal := seal.Entity{} +// err = issuedSeal.Sign(issuedBytes, l.CryptoTools, pk) +// if err != nil { +// return err +// } +// +// sysAssets := BaseAssets{ +// BaseAssetsData: assets, +// IssuedSeal: issuedSeal, +// MetaSeal: metaSeal, +// } +// +// err = l.storeSystemAssets(sysAssets) +// if err != nil { +// return err +// } +// +// balance, valid := big.NewInt(0).SetString(assets.Supply, 10) +// if !valid { +// return errors.New("invalid assets supply") +// } +// +// if balance.Sign() <= 0 { +// return errors.New("supply is zero or negative") +// } +// +// err = l.Storage.Put(kvDatabase.KVItem{ +// Key: BuildKey(StoragePrefixes.Balance, owner), +// Data: balance.Bytes(), +// Exists: false, +// }) +// +// return err +//} + func (l *Ledger) AddTx(req blockchainRequest.Entity) error { tx := Transaction{} err := json.Unmarshal(req.Data, &tx) @@ -168,7 +264,7 @@ func (l *Ledger) AddTx(req blockchainRequest.Entity) error { return errors.New("reach transaction count limit") } - if len(l.txPool) >= l.txPoolLimit { + if l.txPool.len() >= l.txPoolLimit { return errors.New("reach transaction pool limit") } @@ -177,13 +273,16 @@ func (l *Ledger) AddTx(req blockchainRequest.Entity) error { return errors.New("duplicate history transaction") } - txHash := string(tx.DataSeal.Hash) - if l.txPool[txHash] != nil { + if l.txPool.Get(tx.getCommonHash()) != nil { return errors.New("duplicate pending transaction") } - l.txPool[txHash] = &tx - l.txPoolRecord = append(l.txPoolRecord, txHash) + err = l.txPool.addTx(&tx) + if err != nil { + return err + } + + //l.txPoolRecord = append(l.txPoolRecord, tx.getCommonHash()) l.clientTxCount[client] = clientTxCount + 1 return nil @@ -204,8 +303,8 @@ func (l Ledger) txResultCheck(orgResult TransactionResult, execResult Transactio for i, s := range orgResult.NewState { if !bytes.Equal(s.Key, execResult.NewState[i].Key) || - !bytes.Equal(s.OrgVal, execResult.NewState[i].OrgVal) || - !bytes.Equal(s.NewVal, execResult.NewState[i].NewVal) { + !bytes.Equal(s.OrgVal, execResult.NewState[i].OrgVal) || + !bytes.Equal(s.NewVal, execResult.NewState[i].NewVal) { return errors.New(fmt.Sprintf("transaction %x has different state to change", txHash)) } } @@ -217,8 +316,8 @@ func (l Ledger) PreExecute(txList TransactionList, blk block.Entity) (result []b l.poolLock.Lock() defer l.poolLock.Unlock() - txHash := map[string] bool{} - resultCache := txResultCache { + txHash := map[string]bool{} + resultCache := txResultCache{ CachedBlockGasKey: &txResultCacheData{ gasLeft: constTransactionGasLimit().Uint64(), }, @@ -263,30 +362,14 @@ func (l Ledger) PreExecute(txList TransactionList, blk block.Entity) (result []b } func (l *Ledger) removeTransactionsFromPool(txList []Transaction) { - removeTxHashes := map[string] bool {} + l.txPool.removeUnenforceable() for _, tx := range txList { - txHashStr := string(tx.getHash()) - poolEl := l.txPool[txHashStr] - if poolEl != nil { - removeTxHashes[txHashStr] = true - delete(l.txPool, txHashStr) - } - client := string(tx.DataSeal.SignerPublicKey) - if l.clientTxCount[client] > 0{ + if l.clientTxCount[client] > 0 { l.clientTxCount[client] -= 1 } } - - var newTxPoolRecord []string - for _, recHash := range l.txPoolRecord { - if !removeTxHashes[recHash] { - newTxPoolRecord = append(newTxPoolRecord, recHash) - } - } - - l.txPoolRecord = newTxPoolRecord } func (l *Ledger) Execute(txList TransactionList, blk block.Entity) (result []byte, err error) { @@ -302,18 +385,34 @@ func (l *Ledger) Execute(txList TransactionList, blk block.Entity) (result []byt Exists: true, }) - for _, s := range tx.TransactionResult.NewState { - kvList = append(kvList, kvDatabase.KVItem { - Key: s.Key, - Data: s.NewVal, - Exists: true, - }) + switch tx.Type { + case TxType.Transfer.String(): + for i, s := range tx.TransactionResult.NewState { + balance := big.NewInt(0) + balance.SetBytes(s.NewVal) + + address := common.BytesToAddress(s.Key) + + l.StateDB.SetBalance(address, balance) + if i == 0 { //From + l.StateDB.SetNonce(address, l.StateDB.GetNonce(address)+1) + } + } + default: + for _, s := range tx.TransactionResult.NewState { + kvList = append(kvList, kvDatabase.KVItem{ + Key: s.Key, + Data: s.NewVal, + Exists: true, + }) + } } + } err = l.Storage.BatchPut(kvList) if err != nil { - return + return } l.removeTransactionsFromPool(txList.Transactions) @@ -336,12 +435,14 @@ func (l Ledger) GetTransactionsFromPool(blk block.Entity) (txList TransactionLis l.poolLock.Lock() defer l.poolLock.Unlock() - count = uint32(len(l.txPool)) + txs := l.txPool.Pending() + + count = uint32(len(txs)) if count == 0 { return } - resultCache := txResultCache { + resultCache := txResultCache{ CachedBlockGasKey: &txResultCacheData{ gasLeft: constTransactionGasLimit().Uint64(), }, @@ -357,8 +458,7 @@ func (l Ledger) GetTransactionsFromPool(blk block.Entity) (txList TransactionLis mt := merkleTree.Tree{} - for idx, txHashStr := range l.txPoolRecord { - tx := l.txPool[txHashStr] + for idx, tx := range txs { mt.AddHash(tx.DataSeal.Hash) @@ -389,10 +489,9 @@ func (l *Ledger) DoQuery(req QueryRequest) (interface{}, error) { func NewLedger(tools crypto.Tools, driver kvDatabase.IDriver) *Ledger { l := &Ledger{ - txPool: map[string] *Transaction{}, - txPoolRecord: []string {}, + txPool: NewTxPool(), txPoolLimit: 1000, - clientTxCount: map[string] int{}, + clientTxCount: map[string]int{}, clientTxLimit: 4, operateLock: sync.RWMutex{}, poolLock: sync.Mutex{}, @@ -403,15 +502,16 @@ func NewLedger(tools crypto.Tools, driver kvDatabase.IDriver) *Ledger { l.storageForEVM.basedLedger = l l.preActuators = map[string]txPreActuator{ - TxType.Transfer.String(): l.preTransfer, + TxType.Transfer.String(): l.preTransfer, TxType.CreateContract.String(): l.preContractCreation, - TxType.ContractCall.String(): l.preContractCall, + TxType.ContractCall.String(): l.preContractCall, } l.queryActuators = map[string]queryActuator{ - QueryTypes.BaseAssets.String(): l.queryBaseAssets, - QueryTypes.Balance.String(): l.queryBalance, - QueryTypes.Transaction.String(): l.queryTransaction, + QueryTypes.BaseAssets.String(): l.queryBaseAssets, + QueryTypes.Balance.String(): l.queryBalance, + QueryTypes.Nonce.String(): l.queryNonce, + QueryTypes.Transaction.String(): l.queryTransaction, QueryTypes.OffChainCall.String(): l.contractOffChainCall, } diff --git a/service/application/smartAssets/smartAssetsLedger/operationForQuery.go b/service/application/smartAssets/smartAssetsLedger/operationForQuery.go index bd49483..97551f8 100644 --- a/service/application/smartAssets/smartAssetsLedger/operationForQuery.go +++ b/service/application/smartAssets/smartAssetsLedger/operationForQuery.go @@ -41,10 +41,25 @@ func (l *Ledger) queryBalance(req QueryRequest) (interface{}, error) { if err != nil { return nil, Errors.DBError.NewErrorWithNewMessage(err.Error()) } - + return balance.String(), nil } +func (l *Ledger) queryNonce(req QueryRequest) (interface{}, error) { + hexStr := req.Parameter[QueryParameterFields.Address.String()] + if hexStr == "" { + return nil, Errors.InvalidParameter + } + + addr, err := hex.DecodeString(hexStr) + if err != nil { + return nil, Errors.InvalidParameter.NewErrorWithNewMessage(err.Error()) + } + + nonce := l.NonceOf(addr) + return nonce, nil +} + func (l *Ledger) queryTransaction(req QueryRequest) (interface{}, error) { param := req.Parameter[QueryParameterFields.TxHash.String()] if param == "" { @@ -74,7 +89,7 @@ func (l *Ledger) contractOffChainCall(req QueryRequest) (interface{}, error) { return nil, Errors.InvalidParameter.NewErrorWithNewMessage(err.Error()) } - resultCache := txResultCache { + resultCache := txResultCache{ CachedBlockGasKey: &txResultCacheData{ gasLeft: constTransactionGasLimit().Uint64(), }, diff --git a/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go b/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go index 2c8fe50..7ac6aeb 100644 --- a/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go +++ b/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go @@ -33,7 +33,7 @@ func (l *Ledger) getBalance(addr []byte, cache txResultCache) (*big.Int, error) balance, err := l.BalanceOf(addr) if err == nil { cache[addrStr] = &txResultCacheData{ - val:balance, + val: balance, } } @@ -90,16 +90,27 @@ func (l *Ledger) preTransfer(tx Transaction, cache txResultCache, _ block.Entity statusToChange := []StateData{ { - Key: BuildKey(StoragePrefixes.Balance, tx.From), + Key: tx.From, NewVal: fromBalance.Bytes(), OrgVal: orgFromBalance, }, { - Key: BuildKey(StoragePrefixes.Balance, tx.To), + Key: tx.To, NewVal: toBalance.Bytes(), OrgVal: orgToBalance, }, + //{ + // Key: BuildKey(StoragePrefixes.Balance, tx.From), + // NewVal: fromBalance.Bytes(), + // OrgVal: orgFromBalance, + //}, + // + //{ + // Key: BuildKey(StoragePrefixes.Balance, tx.To), + // NewVal: toBalance.Bytes(), + // OrgVal: orgToBalance, + //}, } return statusToChange, cache, Errors.Success diff --git a/service/application/smartAssets/smartAssetsLedger/query.go b/service/application/smartAssets/smartAssetsLedger/query.go index 7e00f84..b09159d 100644 --- a/service/application/smartAssets/smartAssetsLedger/query.go +++ b/service/application/smartAssets/smartAssetsLedger/query.go @@ -22,11 +22,12 @@ import "github.com/SealSC/SealABC/dataStructure/enum" var QueryTypes struct { BaseAssets enum.Element Balance enum.Element + Nonce enum.Element Transaction enum.Element OffChainCall enum.Element } -var QueryParameterFields struct{ +var QueryParameterFields struct { Address enum.Element TxHash enum.Element Data enum.Element @@ -34,5 +35,5 @@ var QueryParameterFields struct{ type QueryRequest struct { QueryType string - Parameter map[string] string + Parameter map[string]string } diff --git a/service/application/smartAssets/smartAssetsLedger/transaction.go b/service/application/smartAssets/smartAssetsLedger/transaction.go index f0c0b83..5a5fb8a 100644 --- a/service/application/smartAssets/smartAssetsLedger/transaction.go +++ b/service/application/smartAssets/smartAssetsLedger/transaction.go @@ -18,18 +18,19 @@ package smartAssetsLedger import ( + "bytes" + "errors" + "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" "github.com/SealSC/SealABC/crypto/hashes" "github.com/SealSC/SealABC/dataStructure/enum" "github.com/SealSC/SealABC/metadata/block" "github.com/SealSC/SealABC/metadata/seal" - "bytes" - "errors" "math/big" ) const ( - maxMemoSize = 200 //200 Byte + maxMemoSize = 200 //200 Byte maxDataSize = 24 * 1024 //24 KB ) @@ -55,13 +56,14 @@ func GetTxTypeCodeForName(name string) int { } type TransactionData struct { - Type string - From []byte - To []byte - Value string - Data []byte - Memo string - SerialNumber string + Nonce uint64 + Type string + From []byte + To []byte + Value string + Data []byte + Memo string + SerialNumber string } type StateData struct { @@ -83,7 +85,7 @@ type Transaction struct { TransactionData TransactionResult - DataSeal seal.Entity + DataSeal seal.Entity } type TransactionList struct { @@ -104,6 +106,10 @@ func (t *Transaction) getHash() []byte { return t.DataSeal.Hash } +func (t *Transaction) getCommonHash() common.Hash { + return common.BytesToHash(t.DataSeal.Hash) +} + func (t *Transaction) verify(hashCalc hashes.IHashCalculator) (passed bool, err error) { if !bytes.Equal(t.From, t.DataSeal.SignerPublicKey) { return false, errors.New("invalid sender") @@ -138,6 +144,6 @@ const ( CachedContractCreationAddress = "contractCreationAddress" ) -type txResultCache map[string] *txResultCacheData +type txResultCache map[string]*txResultCacheData type txPreActuator func(tx Transaction, cache txResultCache, blk block.Entity) (ret []StateData, resultCache txResultCache, err error) type queryActuator func(req QueryRequest) (ret interface{}, err error) From bd8f3633ef0b009c9a6f38e6ede0b4a80f58ed93 Mon Sep 17 00:00:00 2001 From: bianning Date: Wed, 29 Jun 2022 17:47:43 +0800 Subject: [PATCH 07/20] feat: modify the blockchain to support smart ledger --- .../chainStructure/applicationExecutor.go | 223 +++++----- .../blockchain/chainStructure/blockBuilder.go | 4 +- .../system/blockchain/chainStructure/chain.go | 47 ++- .../blockchain/chainStructure/operator.go | 387 +++++++++--------- service/system/blockchain/service.go | 80 ++-- 5 files changed, 381 insertions(+), 360 deletions(-) diff --git a/service/system/blockchain/chainStructure/applicationExecutor.go b/service/system/blockchain/chainStructure/applicationExecutor.go index f860655..eb79dad 100644 --- a/service/system/blockchain/chainStructure/applicationExecutor.go +++ b/service/system/blockchain/chainStructure/applicationExecutor.go @@ -18,156 +18,169 @@ package chainStructure import ( - "github.com/SealSC/SealABC/metadata/applicationResult" - "github.com/SealSC/SealABC/metadata/block" - "github.com/SealSC/SealABC/metadata/blockchainRequest" - "github.com/SealSC/SealABC/service" - "errors" - "sync" + "errors" + "github.com/SealSC/SealABC/metadata/applicationResult" + "github.com/SealSC/SealABC/metadata/block" + "github.com/SealSC/SealABC/metadata/blockchainRequest" + "github.com/SealSC/SealABC/service" + "sync" ) type applicationExecutor struct { - ExternalExecutors map[string]IBlockchainExternalApplication + ExternalExecutors map[string]IBlockchainExternalApplication - externalExeLock sync.RWMutex + externalExeLock sync.RWMutex } type IBlockchainExternalApplication interface { + Name() (name string) - Name() (name string) + //receive a request from user + PushClientRequest(req blockchainRequest.Entity) (result interface{}, err error) - //receive a request from user - PushClientRequest(req blockchainRequest.Entity) (result interface{}, err error) + //query + Query(req []byte) (result interface{}, err error) - //query - Query(req []byte) (result interface{}, err error) + //receive and verify request from a block + PreExecute(req blockchainRequest.Entity, header block.Entity) (result []byte, err error) - //receive and verify request from a block - PreExecute(req blockchainRequest.Entity, header block.Entity) (result []byte, err error) + //receive and execute confirmed block + Execute(req blockchainRequest.Entity, header block.Entity, actIndex uint32) (result applicationResult.Entity, err error) - //receive and execute confirmed block - Execute(req blockchainRequest.Entity, header block.Entity, actIndex uint32) (result applicationResult.Entity, err error) + //handle consensus failed + Cancel(req blockchainRequest.Entity) (err error) - //handle consensus failed - Cancel(req blockchainRequest.Entity) (err error) + //build request list for new block + RequestsForBlock(block block.Entity) (entity []blockchainRequest.Entity, cnt uint32) - //build request list for new block - RequestsForBlock(block block.Entity) (entity []blockchainRequest.Entity, cnt uint32) + //support one application call another inside blockchain execute + ApplicationInternalCall(src string, callData []byte) (ret interface{}, err error) - //support one application call another inside blockchain execute - ApplicationInternalCall(src string, callData []byte) (ret interface{}, err error) + //external service information + Information() (info service.BasicInformation) - //external service information - Information() (info service.BasicInformation) + SetChainInterface(ci IChainInterface) - SetChainInterface(ci IChainInterface) - - UnpackingActionsAsRequests(req blockchainRequest.Entity) (reqList []blockchainRequest.Entity, err error) - GetActionAsRequest(req blockchainRequest.Entity) (ret blockchainRequest.Entity) + UnpackingActionsAsRequests(req blockchainRequest.Entity) (reqList []blockchainRequest.Entity, err error) + GetActionAsRequest(req blockchainRequest.Entity) (ret blockchainRequest.Entity) } -type BlankApplication struct {} -func (BlankApplication) Name() (name string) {return } -func (BlankApplication) PushClientRequest(req blockchainRequest.Entity) (result interface{}, err error) {return } -func (BlankApplication) Query(req []byte) (result interface{}, err error) {return } -func (BlankApplication) PreExecute(req blockchainRequest.Entity, header block.Entity) (result []byte, err error) {return } -func (BlankApplication) Execute(req blockchainRequest.Entity, header block.Entity, actIndex uint32) (result applicationResult.Entity, err error) {return } -func (BlankApplication) Cancel(req blockchainRequest.Entity) (err error) {return } -func (BlankApplication) RequestsForBlock(block block.Entity) (entity []blockchainRequest.Entity, cnt uint32) {return } -func (BlankApplication) ApplicationInternalCall(src string, callData []byte) (ret interface{}, err error) {return } -func (BlankApplication) Information() (info service.BasicInformation) {return } -func (BlankApplication) SetChainInterface(ci IChainInterface) {return } -func (BlankApplication) UnpackingActionsAsRequests(req blockchainRequest.Entity) (reqList []blockchainRequest.Entity, err error) {return } -func (BlankApplication) GetActionAsRequest(req blockchainRequest.Entity) (ret blockchainRequest.Entity) {return } +type BlankApplication struct{} + +func (BlankApplication) Name() (name string) { return } +func (BlankApplication) PushClientRequest(req blockchainRequest.Entity) (result interface{}, err error) { + return +} +func (BlankApplication) Query(req []byte) (result interface{}, err error) { return } +func (BlankApplication) PreExecute(req blockchainRequest.Entity, header block.Entity) (result []byte, err error) { + return +} +func (BlankApplication) Execute(req blockchainRequest.Entity, header block.Entity, actIndex uint32) (result applicationResult.Entity, err error) { + return +} +func (BlankApplication) Cancel(req blockchainRequest.Entity) (err error) { return } +func (BlankApplication) RequestsForBlock(block block.Entity) (entity []blockchainRequest.Entity, cnt uint32) { + return +} +func (BlankApplication) ApplicationInternalCall(src string, callData []byte) (ret interface{}, err error) { + return +} +func (BlankApplication) Information() (info service.BasicInformation) { return } +func (BlankApplication) SetChainInterface(ci IChainInterface) { return } +func (BlankApplication) UnpackingActionsAsRequests(req blockchainRequest.Entity) (reqList []blockchainRequest.Entity, err error) { + return +} +func (BlankApplication) GetActionAsRequest(req blockchainRequest.Entity) (ret blockchainRequest.Entity) { + return +} -func (a *applicationExecutor)getExternalExecutor(name string) (exe IBlockchainExternalApplication, err error) { - exe, exists := a.ExternalExecutors[name] - if !exists { - err = errors.New("no applicationExecutor named " + name) - return - } +func (a *applicationExecutor) getExternalExecutor(name string) (exe IBlockchainExternalApplication, err error) { + exe, exists := a.ExternalExecutors[name] + if !exists { + err = errors.New("no applicationExecutor named " + name) + return + } - return + return } -func (a *applicationExecutor) RegisterApplicationExecutor(s IBlockchainExternalApplication, ci IChainInterface) (err error) { - a.externalExeLock.Lock() - defer a.externalExeLock.Unlock() +func (a *applicationExecutor) RegisterApplicationExecutor(s IBlockchainExternalApplication, ci IChainInterface) (err error) { + a.externalExeLock.Lock() + defer a.externalExeLock.Unlock() - if s == nil { - return - } + if s == nil { + return + } - if exe, _ := a.getExternalExecutor(s.Name()); exe != nil { - return - } + if exe, _ := a.getExternalExecutor(s.Name()); exe != nil { + return + } - s.SetChainInterface(ci) - a.ExternalExecutors[s.Name()] = s - return + s.SetChainInterface(ci) + a.ExternalExecutors[s.Name()] = s + return } -func (a *applicationExecutor)PreExecute(act blockchainRequest.Entity, blk block.Entity) (result []byte, err error) { - a.externalExeLock.RLock() - defer a.externalExeLock.RUnlock() +func (a *applicationExecutor) PreExecute(act blockchainRequest.Entity, blk block.Entity) (result []byte, err error) { + a.externalExeLock.RLock() + defer a.externalExeLock.RUnlock() - exe, err := a.getExternalExecutor(act.RequestApplication) - if err != nil { - return - } + exe, err := a.getExternalExecutor(act.RequestApplication) + if err != nil { + return + } - return exe.PreExecute(act, blk) + return exe.PreExecute(act, blk) } -func (a *applicationExecutor)ExecuteRequest(req blockchainRequest.Entity, blk block.Entity, actIndex uint32) (result applicationResult.Entity, err error) { - a.externalExeLock.RLock() - defer a.externalExeLock.RUnlock() +func (a *applicationExecutor) ExecuteRequest(req blockchainRequest.Entity, blk block.Entity, actIndex uint32) (result applicationResult.Entity, err error) { + a.externalExeLock.RLock() + defer a.externalExeLock.RUnlock() - exe, err := a.getExternalExecutor(req.RequestApplication) - if err != nil { - return - } + exe, err := a.getExternalExecutor(req.RequestApplication) + if err != nil { + return + } - return exe.Execute(req, blk, actIndex) + return exe.Execute(req, blk, actIndex) } -func (a *applicationExecutor)GetRequestListToBuildBlock(block block.Entity) (reqList []blockchainRequest.Entity) { - a.externalExeLock.RLock() - defer a.externalExeLock.RUnlock() +func (a *applicationExecutor) GetRequestListToBuildBlock(block block.Entity) (reqList []blockchainRequest.Entity) { + a.externalExeLock.RLock() + defer a.externalExeLock.RUnlock() - for _, exe := range a.ExternalExecutors { - req, cnt := exe.RequestsForBlock(block) - if cnt == 0 { - continue - } + for _, exe := range a.ExternalExecutors { + req, cnt := exe.RequestsForBlock(block) + if cnt == 0 { + continue + } - reqList = append(reqList, req...) - } + reqList = append(reqList, req...) + } - return + return } -func (a *applicationExecutor)PushRequest(req blockchainRequest.Entity) (result interface{}, err error) { - a.externalExeLock.RLock() - defer a.externalExeLock.RUnlock() - - exe, err := a.getExternalExecutor(req.RequestApplication) - if err != nil { - return - } +func (a *applicationExecutor) PushRequest(req blockchainRequest.Entity) (result interface{}, err error) { + a.externalExeLock.RLock() + defer a.externalExeLock.RUnlock() + exe, err := a.getExternalExecutor(req.RequestApplication) + if err != nil { + return + } - return exe.PushClientRequest(req) + return exe.PushClientRequest(req) } -func (a *applicationExecutor)ExternalApplicationInformation() (list []service.BasicInformation) { - a.externalExeLock.RLock() - defer a.externalExeLock.RUnlock() +func (a *applicationExecutor) ExternalApplicationInformation() (list []service.BasicInformation) { + a.externalExeLock.RLock() + defer a.externalExeLock.RUnlock() - for _, exe := range a.ExternalExecutors { - info := exe.Information() - list = append(list, info) - } + for _, exe := range a.ExternalExecutors { + info := exe.Information() + list = append(list, info) + } - return + return } diff --git a/service/system/blockchain/chainStructure/blockBuilder.go b/service/system/blockchain/chainStructure/blockBuilder.go index a30f3f5..98c3fe4 100644 --- a/service/system/blockchain/chainStructure/blockBuilder.go +++ b/service/system/blockchain/chainStructure/blockBuilder.go @@ -62,6 +62,7 @@ func (b *Blockchain) NewBlankBlock() (newBlock block.Entity) { //set block prev hash newBlock.Header.PrevBlock = append([]byte{}, b.lastBlock.Seal.Hash...) + newBlock.Header.StateRoot = b.lastBlock.Header.StateRoot } //set block hash @@ -79,7 +80,8 @@ func (b *Blockchain) NewBlock(requests []blockchainRequest.Entity, blankBlock bl newBlock = b.buildBasicBlock(requests) newBlock.Header.Timestamp = blankBlock.Header.Timestamp newBlock.BlankSeal = blankBlock.BlankSeal - + newBlock.Header.StateRoot = blankBlock.Header.StateRoot + //set block height if lastBlock != nil { newBlock.Header.Height = lastBlock.Header.Height + 1 diff --git a/service/system/blockchain/chainStructure/chain.go b/service/system/blockchain/chainStructure/chain.go index dbc2897..39630c2 100644 --- a/service/system/blockchain/chainStructure/chain.go +++ b/service/system/blockchain/chainStructure/chain.go @@ -18,40 +18,39 @@ package chainStructure import ( - "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/metadata/block" - "github.com/SealSC/SealABC/service/system/blockchain/chainSQLStorage" - "sync" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/metadata/block" + "github.com/SealSC/SealABC/service/system/blockchain/chainSQLStorage" + "sync" ) type Blockchain struct { - Config Config - Executor applicationExecutor + Config Config + Executor applicationExecutor - lastBlock *block.Entity - SQLStorage *chainSQLStorage.Storage - currentHeight uint64 - operateLock sync.RWMutex + lastBlock *block.Entity + SQLStorage *chainSQLStorage.Storage + currentHeight uint64 + operateLock sync.RWMutex } -func (b *Blockchain) SetSQLStorage(sqlStorage *chainSQLStorage.Storage) { - b.SQLStorage = sqlStorage +func (b *Blockchain) SetSQLStorage(sqlStorage *chainSQLStorage.Storage) { + b.SQLStorage = sqlStorage } func (b *Blockchain) LoadBlockchain(cfg Config) (err error) { - b.Config = cfg - b.Executor.ExternalExecutors = map[string]IBlockchainExternalApplication{} + b.Config = cfg + b.Executor.ExternalExecutors = map[string]IBlockchainExternalApplication{} - lastBlock := b.GetLastBlock() - if lastBlock == nil { - b.currentHeight = 0 - return - } + lastBlock := b.GetLastBlock() + if lastBlock == nil { + b.currentHeight = 0 + return + } - log.Log.Println("get latest block: ", lastBlock.Header.Height) + log.Log.Println("get latest block: ", lastBlock.Header.Height) - b.lastBlock = lastBlock - b.currentHeight = lastBlock.Header.Height - return + b.lastBlock = lastBlock + b.currentHeight = lastBlock.Header.Height + return } - diff --git a/service/system/blockchain/chainStructure/operator.go b/service/system/blockchain/chainStructure/operator.go index b2135d9..07e01cf 100644 --- a/service/system/blockchain/chainStructure/operator.go +++ b/service/system/blockchain/chainStructure/operator.go @@ -18,231 +18,238 @@ package chainStructure import ( - "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/metadata/block" - "github.com/SealSC/SealABC/metadata/blockchainRequest" - "github.com/SealSC/SealABC/service/system/blockchain/chainTables" - "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" - "encoding/binary" - "encoding/hex" - "encoding/json" - "errors" + "encoding/binary" + "encoding/hex" + "encoding/json" + "errors" + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/metadata/block" + "github.com/SealSC/SealABC/metadata/blockchainRequest" + "github.com/SealSC/SealABC/service/system/blockchain/chainTables" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" ) const lastBlockKey = "lastBlockKey" -func (b *Blockchain) executeRequest(blk block.Entity) (err error) { - for idx, req := range blk.Body.Requests { - appRet, exeErr := b.Executor.ExecuteRequest(req, blk, uint32(idx)) - - if exeErr != nil { - err = exeErr - break - } - - app, _ := b.Executor.getExternalExecutor(req.RequestApplication) - - if b.SQLStorage != nil { - var reqList []blockchainRequest.Entity - var err error = nil - if req.Packed { - reqList, err = app.UnpackingActionsAsRequests(req) - if err != nil { - log.Log.Errorf("unpack packed transaction for application %s failed: %s\r\n", - req.RequestApplication, err.Error()) - continue - } - - for _, r := range reqList { - sqlErr := b.SQLStorage.StoreTransaction(blk, r, appRet) - if sqlErr != nil { - log.Log.Error("store block in sql database failed: ", sqlErr.Error()) - } - - go b.SQLStorage.StoreAddress(blk, r) - } - } else { - newReq := app.GetActionAsRequest(req) - sqlErr := b.SQLStorage.StoreTransaction(blk, newReq, appRet) - if sqlErr != nil { - log.Log.Error("store block in sql database failed: ", sqlErr.Error()) - } - - go b.SQLStorage.StoreAddress(blk, newReq) - } - } - //todo: record result - } - - return +func (b *Blockchain) executeRequest(blk *block.Entity) (err error) { + for idx, req := range blk.Body.Requests { + appRet, exeErr := b.Executor.ExecuteRequest(req, *blk, uint32(idx)) + + switch appRet.Data.(type) { + case common.Hash: + blk.Header.StateRoot = (appRet.Data).(common.Hash).Bytes() + } + + if exeErr != nil { + err = exeErr + break + } + + app, _ := b.Executor.getExternalExecutor(req.RequestApplication) + + if b.SQLStorage != nil { + var reqList []blockchainRequest.Entity + var err error = nil + if req.Packed { + reqList, err = app.UnpackingActionsAsRequests(req) + if err != nil { + log.Log.Errorf("unpack packed transaction for application %s failed: %s\r\n", + req.RequestApplication, err.Error()) + continue + } + + for _, r := range reqList { + sqlErr := b.SQLStorage.StoreTransaction(*blk, r, appRet) + if sqlErr != nil { + log.Log.Error("store block in sql database failed: ", sqlErr.Error()) + } + + go b.SQLStorage.StoreAddress(*blk, r) + } + } else { + newReq := app.GetActionAsRequest(req) + sqlErr := b.SQLStorage.StoreTransaction(*blk, newReq, appRet) + if sqlErr != nil { + log.Log.Error("store block in sql database failed: ", sqlErr.Error()) + } + + go b.SQLStorage.StoreAddress(*blk, newReq) + } + } + //todo: record result + } + + //blk.Header.StateRoot = + return } func (b *Blockchain) InternalCall(src string, dst string, data []byte) (ret interface{}, err error) { - app, err := b.Executor.getExternalExecutor(dst) - if err != nil { - return - } + app, err := b.Executor.getExternalExecutor(dst) + if err != nil { + return + } - return app.ApplicationInternalCall(src, data) + return app.ApplicationInternalCall(src, data) } func (b *Blockchain) AddBlock(blk block.Entity) (err error) { - err = b.executeRequest(blk) - if err != nil { - log.Log.Error("execute requests in the block failed!") - return - } - - b.operateLock.Lock() - defer b.operateLock.Unlock() - - blockBytes, err := json.Marshal(blk) - if err != nil { - return - } - - heightKey := make([]byte, 8, 8) - binary.BigEndian.PutUint64(heightKey, blk.Header.Height) - - err = b.Config.StorageDriver.BatchPut([]kvDatabase.KVItem { - //first: key is height and data is block - { - Key: heightKey, - Data: blockBytes, - }, - - //second: key is hash and data is height - { - Key: blk.Seal.Hash, - Data: heightKey, - }, - - //last: save block as last block - { - Key: []byte(lastBlockKey), - Data: blockBytes, - }, - }) - - if err != nil { - return - } - - b.currentHeight = blk.Header.Height - b.lastBlock = &blk - - if b.SQLStorage != nil { - go func() { - _ = b.SQLStorage.StoreBlock(blk) - }() - } - - return + err = b.executeRequest(&blk) + if err != nil { + log.Log.Error("execute requests in the block failed!") + return + } + + b.operateLock.Lock() + defer b.operateLock.Unlock() + + blockBytes, err := json.Marshal(blk) + if err != nil { + return + } + + heightKey := make([]byte, 8, 8) + binary.BigEndian.PutUint64(heightKey, blk.Header.Height) + + err = b.Config.StorageDriver.BatchPut([]kvDatabase.KVItem{ + //first: key is height and data is block + { + Key: heightKey, + Data: blockBytes, + }, + + //second: key is hash and data is height + { + Key: blk.Seal.Hash, + Data: heightKey, + }, + + //last: save block as last block + { + Key: []byte(lastBlockKey), + Data: blockBytes, + }, + }) + + if err != nil { + return + } + + b.currentHeight = blk.Header.Height + b.lastBlock = &blk + + if b.SQLStorage != nil { + go func() { + _ = b.SQLStorage.StoreBlock(blk) + }() + } + + return } func (b *Blockchain) GetBlockByHeight(height uint64) (blk block.Entity, err error) { - b.operateLock.RLock() - defer b.operateLock.RUnlock() + b.operateLock.RLock() + defer b.operateLock.RUnlock() - heightKey := make([]byte, 8, 8) - binary.BigEndian.PutUint64(heightKey, height) - kv, err := b.Config.StorageDriver.Get(heightKey) - if err != nil { - return - } + heightKey := make([]byte, 8, 8) + binary.BigEndian.PutUint64(heightKey, height) + kv, err := b.Config.StorageDriver.Get(heightKey) + if err != nil { + return + } - if !kv.Exists { - err = errors.New("no such block") - return - } + if !kv.Exists { + err = errors.New("no such block") + return + } - err = json.Unmarshal(kv.Data, &blk) + err = json.Unmarshal(kv.Data, &blk) - return + return } -func (b *Blockchain) getBlockFromKVDBByHeight(height uint64) (blk chainTables.BlockListRow, err error) { - blkEntity, err := b.GetBlockByHeight(height) - if err != nil { - return - } - blk.FromBlockEntity(blkEntity) - return +func (b *Blockchain) getBlockFromKVDBByHeight(height uint64) (blk chainTables.BlockListRow, err error) { + blkEntity, err := b.GetBlockByHeight(height) + if err != nil { + return + } + blk.FromBlockEntity(blkEntity) + return } func (b *Blockchain) GetBlockRowByHeight(height uint64) (blk chainTables.BlockListRow, err error) { - if b.SQLStorage != nil { - return b.SQLStorage.GetBlock(height) - } else { - return b.getBlockFromKVDBByHeight(height) - } + if b.SQLStorage != nil { + return b.SQLStorage.GetBlock(height) + } else { + return b.getBlockFromKVDBByHeight(height) + } } func (b *Blockchain) getBlockFromKVDBByHash(hash []byte) (blk chainTables.BlockListRow, err error) { - b.operateLock.RLock() - defer b.operateLock.RUnlock() - - //get height by hash first - kvHeight, err := b.Config.StorageDriver.Get(hash) - if err != nil { - return - } - - if !kvHeight.Exists { - err = errors.New("no such block") - return - } - - //get block by height finally - kvBlock, err := b.Config.StorageDriver.Get(kvHeight.Data) - if err != nil { - return - } - - if !kvBlock.Exists { - err = errors.New("no such block") - return - } - - blkEntity := block.Entity{} - err = json.Unmarshal(kvBlock.Data, &blkEntity) - if err != nil { - return - } - - blk.FromBlockEntity(blkEntity) - return + b.operateLock.RLock() + defer b.operateLock.RUnlock() + + //get height by hash first + kvHeight, err := b.Config.StorageDriver.Get(hash) + if err != nil { + return + } + + if !kvHeight.Exists { + err = errors.New("no such block") + return + } + + //get block by height finally + kvBlock, err := b.Config.StorageDriver.Get(kvHeight.Data) + if err != nil { + return + } + + if !kvBlock.Exists { + err = errors.New("no such block") + return + } + + blkEntity := block.Entity{} + err = json.Unmarshal(kvBlock.Data, &blkEntity) + if err != nil { + return + } + + blk.FromBlockEntity(blkEntity) + return } -func (b *Blockchain) GetBlockRowByHash (hash string) (blk chainTables.BlockListRow, err error) { - hashBytes, err := hex.DecodeString(hash) - if err != nil { - return - } - if b.SQLStorage != nil { - return b.SQLStorage.GetBlockByHash(hash) - } else { - return b.getBlockFromKVDBByHash(hashBytes) - } +func (b *Blockchain) GetBlockRowByHash(hash string) (blk chainTables.BlockListRow, err error) { + hashBytes, err := hex.DecodeString(hash) + if err != nil { + return + } + if b.SQLStorage != nil { + return b.SQLStorage.GetBlockByHash(hash) + } else { + return b.getBlockFromKVDBByHash(hashBytes) + } } func (b *Blockchain) GetLastBlock() (last *block.Entity) { - kv, _ := b.Config.StorageDriver.Get([]byte(lastBlockKey)) + kv, _ := b.Config.StorageDriver.Get([]byte(lastBlockKey)) - if !kv.Exists { - return - } + if !kv.Exists { + return + } - lastBlk := block.Entity{} - err := json.Unmarshal(kv.Data, &lastBlk) - if err != nil { - return - } + lastBlk := block.Entity{} + err := json.Unmarshal(kv.Data, &lastBlk) + if err != nil { + return + } - last = &lastBlk - return + last = &lastBlk + return } func (b *Blockchain) CurrentHeight() uint64 { - return b.currentHeight + return b.currentHeight } diff --git a/service/system/blockchain/service.go b/service/system/blockchain/service.go index 3f16720..592058b 100644 --- a/service/system/blockchain/service.go +++ b/service/system/blockchain/service.go @@ -18,57 +18,57 @@ package blockchain import ( - "github.com/SealSC/SealABC/engine/engineService" - "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/service" - "github.com/SealSC/SealABC/service/system/blockchain/chainApi" - "github.com/SealSC/SealABC/service/system/blockchain/chainNetwork" - "github.com/SealSC/SealABC/service/system/blockchain/chainSQLStorage" - "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" - "github.com/SealSC/SealABC/service/system/blockchain/serviceInterface" + "github.com/SealSC/SealABC/engine/engineService" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/service" + "github.com/SealSC/SealABC/service/system/blockchain/chainApi" + "github.com/SealSC/SealABC/service/system/blockchain/chainNetwork" + "github.com/SealSC/SealABC/service/system/blockchain/chainSQLStorage" + "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" + "github.com/SealSC/SealABC/service/system/blockchain/serviceInterface" ) -func Load() { - chainNetwork.Load() - chainApi.Load() - chainSQLStorage.Load() +func Load() { + chainNetwork.Load() + chainApi.Load() + chainSQLStorage.Load() } func NewService(cfg Config) service.IService { - //new blockchain - chain := chainStructure.Blockchain{} + //new blockchain + chain := chainStructure.Blockchain{} - //sql database - var sqlStorage *chainSQLStorage.Storage = nil - if cfg.SQLStorage != nil && cfg.EnableSQLDB{ - sqlStorage = &chainSQLStorage.Storage { - Driver: cfg.SQLStorage, - } - chain.SetSQLStorage(sqlStorage) - } + //sql database + var sqlStorage *chainSQLStorage.Storage = nil + if cfg.SQLStorage != nil && cfg.EnableSQLDB { + sqlStorage = &chainSQLStorage.Storage{ + Driver: cfg.SQLStorage, + } + chain.SetSQLStorage(sqlStorage) + } - err := chain.LoadBlockchain(cfg.Blockchain) - if err != nil { - log.Log.Error("create block chain failed") - return nil - } + err := chain.LoadBlockchain(cfg.Blockchain) + if err != nil { + log.Log.Error("create block chain failed") + return nil + } - //new networks & service - p2p := chainNetwork.NewNetwork(cfg.Network, &chain) + //new networks & service + p2p := chainNetwork.NewNetwork(cfg.Network, &chain) - //start api server - apiServers := chainApi.NewServer(cfg.Api, &chain, p2p, sqlStorage) + //start api server + apiServers := chainApi.NewServer(cfg.Api, &chain, p2p, sqlStorage) - //register application executors - for _, exe := range cfg.ExternalExecutors { - _ = chain.Executor.RegisterApplicationExecutor(exe, &chain) - apiServers.HttpJSON.Actions.RegisterApplicationQueryHandler(exe.Name(), exe.Query) - } + //register application executors + for _, exe := range cfg.ExternalExecutors { + _ = chain.Executor.RegisterApplicationExecutor(exe, &chain) + apiServers.HttpJSON.Actions.RegisterApplicationQueryHandler(exe.Name(), exe.Query) + } - chainService := serviceInterface.NewServiceInterface(cfg.ServiceName, &chain, p2p, apiServers) + chainService := serviceInterface.NewServiceInterface(cfg.ServiceName, &chain, p2p, apiServers) - //mount to engine - _ = engineService.Mount(chainService) + //mount to engine + _ = engineService.Mount(chainService) - return chainService + return chainService } From bc6705f52eed21bae3fa766bc3773ecbe8207902 Mon Sep 17 00:00:00 2001 From: bianning Date: Mon, 18 Jul 2022 15:36:03 +0800 Subject: [PATCH 08/20] style: fmt all --- account/account.go | 66 +- account/store.go | 10 +- cli/action.go | 4 +- cli/app.go | 70 +- cli/cliFlags/config.go | 6 +- cli/cliFlags/const.go | 2 +- cli/parameters.go | 4 +- common/constant.go | 6 +- .../structSerializer/deserialization.go | 464 +++++++------- .../structSerializer/serialization.go | 299 +++++---- .../serializer/structSerializer/serializer.go | 27 +- common/utility/utility.go | 6 +- consensus/driver.go | 28 +- consensus/hotStuff/config.go | 38 +- crypto/ciphers/aes/aes.go | 224 ++++--- crypto/ciphers/cipher.go | 17 +- crypto/ciphers/cipherCommon/cipherCommon.go | 5 +- crypto/crypto.go | 24 +- crypto/hashes/commonHash/commonHash.go | 13 +- crypto/hashes/hash.go | 30 +- crypto/hashes/sha3/sha3.go | 20 +- crypto/kdf/kdf.go | 8 +- crypto/kdf/pbkdf2/pbkdf2.go | 114 ++-- crypto/signers/ecdsa/secp256k1/secp256k1.go | 31 +- crypto/signers/ed25519/ed25519.go | 237 ++++--- crypto/signers/signer.go | 28 +- crypto/signers/signerCommon/signerCommon.go | 8 +- dataStructure/enum/builder.go | 66 +- dataStructure/enum/enum.go | 56 +- dataStructure/enum/errorEnum.go | 92 +-- dataStructure/merkleTree/merkleTree.go | 90 +-- dataStructure/mfb/markedFlatBytes.go | 72 +-- engine/engine.go | 2 +- engine/engineApi/api.go | 4 +- engine/engineApi/config.go | 2 +- engine/engineApi/httpJSON/actions/actions.go | 34 +- .../httpJSON/actions/listServices.go | 59 +- engine/engineApi/httpJSON/server.go | 16 +- engine/engineService/informations.go | 23 +- engine/engineStartup/consensus.go | 14 +- engine/engineStartup/network.go | 33 +- engine/engineStartup/storage.go | 4 +- engine/engineStartup/systemService.go | 8 +- log/log.go | 77 ++- metadata/applicationCommonConfig/entity.go | 16 +- metadata/applicationResult/entity.go | 4 +- metadata/block/operation.go | 24 +- metadata/blockchainRequest/entity.go | 18 +- .../httpJSONResult/rowsWithCount/entity.go | 4 +- metadata/message/message.go | 13 +- metadata/serviceRequest/entity.go | 12 +- network/config.go | 16 +- network/directConnect.go | 77 ++- network/http/config.go | 10 +- network/http/handler.go | 18 +- network/http/http.go | 72 +-- network/http/response.go | 22 +- network/http/utils.go | 16 +- network/link.go | 228 +++---- network/message.go | 135 ++-- network/network.go | 157 +++-- network/node.go | 12 +- network/processor.go | 4 +- network/router.go | 370 +++++------ .../topology/p2p/fullyConnect/fullyConnect.go | 6 +- .../p2p/fullyConnect/message/message.go | 38 +- .../p2p/fullyConnect/message/payload/join.go | 4 +- .../fullyConnect/message/payload/joinReply.go | 5 +- .../fullyConnect/message/payload/neighbors.go | 2 +- .../fullyConnect/message/payload/payload.go | 6 +- .../fullyConnect/message/payload/pingpong.go | 8 +- .../p2p/fullyConnect/topology/join.go | 116 ++-- .../p2p/fullyConnect/topology/neighbors.go | 97 +-- .../p2p/fullyConnect/topology/pingpong.go | 65 +- .../p2p/fullyConnect/topology/processor.go | 4 +- .../p2p/fullyConnect/topology/topology.go | 234 ++++--- .../basicAssetsInterface.go | 270 ++++---- .../storeToSQLDatabase.go | 5 +- .../basicAssets/basicAssetsLedger/assets.go | 190 +++--- .../basicAssetsLedger/copyrightStore.go | 6 +- .../basicAssets/basicAssetsLedger/ledger.go | 150 ++--- .../basicAssetsLedger/operationForAssets.go | 176 ++--- .../basicAssetsLedger/operationForQuery.go | 216 +++---- .../basicAssetsLedger/operationForSelling.go | 22 +- .../operationForTransaction.go | 274 ++++---- .../basicAssetsLedger/operationForTransfer.go | 99 ++- .../basicAssets/basicAssetsLedger/query.go | 30 +- .../basicAssetsLedger/transaction.go | 80 +-- .../basicAssets/basicAssetsLedger/utxo.go | 527 +++++++-------- .../basicAssetsSQLStorage/query.go | 603 +++++++++--------- .../basicAssetsSQLStorage/storage.go | 82 +-- .../basicAssetsSQLStorage/store.go | 314 ++++----- .../basicAssetsSQLStorage/utils.go | 66 +- .../basicAssetsSQLTables/addressList.go | 58 +- .../basicAssetsSQLTables/addressRecord.go | 100 +-- .../basicAssetsSQLTables/assetsList.go | 133 ++-- .../basicAssetsSQLTables/assetsTransfers.go | 259 ++++---- .../basicAssetsSQLTables/balance.go | 88 +-- .../basicAssetsSQLTables/sellingList.go | 21 +- .../basicAssetsSQLTables/tables.go | 14 +- service/application/basicAssets/config.go | 2 +- service/application/basicAssets/service.go | 34 +- service/application/copyright/config.go | 10 +- .../copyright/copyrightData/copyrightData.go | 25 +- .../copyrightInterface/copyrightInterface.go | 16 +- service/application/memo/config.go | 2 +- .../memo/memoInterface/memoInterface.go | 280 ++++---- .../memo/memoInterface/memoOperation.go | 78 +-- .../application/memo/memoSQLStorage/query.go | 324 +++++----- .../memo/memoSQLStorage/statistics.go | 80 +-- .../memo/memoSQLStorage/storage.go | 66 +- .../application/memo/memoSQLStorage/store.go | 36 +- .../application/memo/memoSQLStorage/utils.go | 86 +-- .../application/memo/memoSpace/memoSpace.go | 13 +- .../memo/memoTables/addressList.go | 54 +- .../application/memo/memoTables/memoList.go | 98 +-- service/application/memo/memoTables/tables.go | 6 +- service/application/memo/service.go | 44 +- service/application/smartAssets/config.go | 10 +- .../smartAssets/smartAssetsLedger/errors.go | 2 +- .../operationForContractCall.go | 2 +- .../operationForContractCreation.go | 6 +- .../smartAssets/smartAssetsLedger/storage.go | 5 +- .../smartAssetsSQLStorage/query.go | 8 +- .../smartAssetsSQLStorage/queryAccount.go | 11 +- .../smartAssetsSQLStorage/queryContract.go | 12 +- .../queryContractCall.go | 11 +- .../smartAssetsSQLStorage/queryTransaction.go | 10 +- .../smartAssetsSQLStorage/queryTransfer.go | 6 +- .../smartAssetsSQLStorage/storage.go | 8 +- .../smartAssetsSQLStorage/store.go | 5 +- .../smartAssetsSQLTables/addressList.go | 6 +- .../smartAssetsSQLTables/contract.go | 4 +- .../smartAssetsSQLTables/contractCall.go | 6 +- .../smartAssetsSQLTables/tables.go | 2 +- .../smartAssetsSQLTables/transaction.go | 7 +- .../smartAssetsSQLTables/transfer.go | 6 +- .../application/traceableStorage/config.go | 10 +- .../application/traceableStorage/service.go | 1 - .../traceableStorage/tsData/tsData.go | 12 +- .../tsInterface/tsInterface.go | 16 +- .../traceableStorage/tsLedger/tsLedger.go | 27 +- .../traceableStorage/tsLedger/tsModify.go | 4 +- .../traceableStorage/tsLedger/tsStore.go | 4 +- .../traceableStorage/tsLedger/tsVerify.go | 1 - .../universalIdentification/service.go | 1 - .../uidData/actions.go | 6 +- .../uidInterface/uidInterface.go | 10 +- .../uidLedger/operationForAppendUIDKeys.go | 8 +- .../uidLedger/operationForCreateUID.go | 4 +- .../uidLedger/operationForQueryUID.go | 2 +- .../uidLedger/operationForUpdateUID.go | 7 +- .../uidLedger/uidLedger.go | 14 +- service/system/blockchain/chainApi/api.go | 24 +- service/system/blockchain/chainApi/config.go | 4 +- .../chainApi/httpJSON/actions/actions.go | 198 +++--- .../httpJSON/actions/callApplication.go | 70 +- .../httpJSON/actions/getAddressList.go | 11 +- .../httpJSON/actions/getBlockByHash.go | 54 +- .../httpJSON/actions/getBlockByHeight.go | 61 +- .../chainApi/httpJSON/actions/getBlockList.go | 120 ++-- .../getRequestByApplicationAndAction.go | 12 +- .../httpJSON/actions/getRequestByHash.go | 55 +- .../httpJSON/actions/getRequestByHeight.go | 13 +- .../httpJSON/actions/getRequestList.go | 64 +- .../httpJSON/actions/queryApplication.go | 75 ++- .../blockchain/chainApi/httpJSON/server.go | 46 +- .../blockchain/chainNetwork/blockSync.go | 83 ++- .../blockchain/chainNetwork/chainNetwork.go | 93 ++- .../system/blockchain/chainNetwork/message.go | 136 ++-- .../blockchain/chainNetwork/messageHandler.go | 130 ++-- .../blockchain/chainSQLStorage/query.go | 286 +++++---- .../blockchain/chainSQLStorage/storage.go | 8 +- .../blockchain/chainSQLStorage/store.go | 89 ++- .../blockchain/chainStructure/config.go | 18 +- .../blockchain/chainTables/addressList.go | 6 +- .../blockchain/chainTables/blockList.go | 105 ++- .../system/blockchain/chainTables/tables.go | 6 +- .../blockchain/chainTables/transactions.go | 130 ++-- service/system/blockchain/config.go | 22 +- service/system/config.go | 2 +- service/system/system.go | 8 +- storage/db/db.go | 49 +- storage/db/dbDrivers/levelDB/batch.go | 115 ++-- storage/db/dbDrivers/levelDB/driver.go | 63 +- storage/db/dbDrivers/levelDB/simple.go | 52 +- storage/db/dbDrivers/simpleMysql/driver.go | 358 +++++------ storage/db/dbInterface/constant.go | 5 +- storage/db/dbInterface/kvDatabase/driver.go | 22 +- storage/db/dbInterface/kvDatabase/item.go | 6 +- .../dbInterface/simpleSQLDatabase/driver.go | 14 +- .../db/dbInterface/simpleSQLDatabase/item.go | 200 +++--- .../db/dbInterface/simpleSQLDatabase/utils.go | 251 ++++---- 193 files changed, 6263 insertions(+), 6346 deletions(-) diff --git a/account/account.go b/account/account.go index 585cc1e..aee6781 100644 --- a/account/account.go +++ b/account/account.go @@ -18,63 +18,63 @@ package account import ( - "github.com/SealSC/SealABC/crypto/ciphers/cipherCommon" - "github.com/SealSC/SealABC/crypto/signers" - "github.com/SealSC/SealABC/crypto/signers/signerCommon" + "github.com/SealSC/SealABC/crypto/ciphers/cipherCommon" + "github.com/SealSC/SealABC/crypto/signers" + "github.com/SealSC/SealABC/crypto/signers/signerCommon" ) const encryptedKeyLen = 32 type StoreConfig struct { - CipherType string - CipherParam []byte + CipherType string + CipherParam []byte - KDFType string - KDFSalt []byte - KDFParam []byte + KDFType string + KDFSalt []byte + KDFParam []byte - KeyLength int + KeyLength int } type Encrypted struct { - Address string - Data cipherCommon.EncryptedData - Config StoreConfig + Address string + Data cipherCommon.EncryptedData + Config StoreConfig } type accountDataForEncrypt struct { - SignerType string - KeyData []byte + SignerType string + KeyData []byte } type SealAccount struct { - Address string - SingerType string - Signer signerCommon.ISigner + Address string + SingerType string + Signer signerCommon.ISigner } func NewAccount(privateKey []byte, sg signers.ISignerGenerator) (sa SealAccount, err error) { - signer, err := sg.NewSigner(privateKey) + signer, err := sg.NewSigner(privateKey) - if err != nil { - return - } + if err != nil { + return + } - sa.Address = signer.PublicKeyString() - sa.SingerType = signer.Type() - sa.Signer = signer - return + sa.Address = signer.PublicKeyString() + sa.SingerType = signer.Type() + sa.Signer = signer + return } func NewAccountForVerify(publicKey []byte, sg signers.ISignerGenerator) (sa SealAccount, err error) { - signer, err := sg.FromRawPublicKey(publicKey) - if err != nil { - return - } + signer, err := sg.FromRawPublicKey(publicKey) + if err != nil { + return + } - sa.Address = signer.PublicKeyString() - sa.SingerType = signer.Type() - sa.Signer = signer + sa.Address = signer.PublicKeyString() + sa.SingerType = signer.Type() + sa.Signer = signer - return + return } diff --git a/account/store.go b/account/store.go index 76a13e9..71639a7 100644 --- a/account/store.go +++ b/account/store.go @@ -18,12 +18,12 @@ package account import ( + "encoding/json" + "errors" "github.com/SealSC/SealABC/crypto/ciphers" "github.com/SealSC/SealABC/crypto/ciphers/cipherCommon" "github.com/SealSC/SealABC/crypto/kdf/pbkdf2" "github.com/SealSC/SealABC/crypto/signers" - "encoding/json" - "errors" "io/ioutil" ) @@ -47,7 +47,7 @@ func (s SealAccount) Store(filename string, password string, cipher ciphers.ICip encrypted.Address = s.Address encrypted.Data = encData - encrypted.Config = StoreConfig { + encrypted.Config = StoreConfig{ CipherType: cipher.Type(), CipherParam: []byte(encMode), KDFType: pbkdf2.Generator.Name(), @@ -61,7 +61,6 @@ func (s SealAccount) Store(filename string, password string, cipher ciphers.ICip return } - err = ioutil.WriteFile(filename, fileData, 0666) return } @@ -72,7 +71,7 @@ func (s *SealAccount) FromStore(filename string, password string) (sa SealAccoun return } - encAccount := Encrypted {} + encAccount := Encrypted{} err = json.Unmarshal(data, &encAccount) if err != nil { return @@ -119,4 +118,3 @@ func (s *SealAccount) FromStore(filename string, password string) (sa SealAccoun sa.Signer = signer return } - diff --git a/cli/action.go b/cli/action.go index 25fd557..a59ec8e 100644 --- a/cli/action.go +++ b/cli/action.go @@ -18,13 +18,13 @@ package cli import ( - "github.com/SealSC/SealABC/cli/cliFlags" "errors" + "github.com/SealSC/SealABC/cli/cliFlags" cliV2 "github.com/urfave/cli/v2" ) func SetAction(app *cliV2.App) { - app.Action = func(c *cliV2.Context) error { + app.Action = func(c *cliV2.Context) error { cfgFile := c.String(cliFlags.Config) //config file diff --git a/cli/app.go b/cli/app.go index c3ddc97..4455035 100644 --- a/cli/app.go +++ b/cli/app.go @@ -18,43 +18,43 @@ package cli import ( - "github.com/SealSC/SealABC/cli/cliFlags" - cliV2 "github.com/urfave/cli/v2" - "io" - "os" + "github.com/SealSC/SealABC/cli/cliFlags" + cliV2 "github.com/urfave/cli/v2" + "io" + "os" ) func Run() (app *cliV2.App) { - oldHelpPrinter := cliV2.HelpPrinter - cliV2.HelpPrinter = func(w io.Writer, templ string, data interface{}) { - oldHelpPrinter(w, templ, data) - os.Exit(0) - } - - oldVersionPrinter := cliV2.VersionPrinter - cliV2.VersionPrinter = func(c *cliV2.Context) { - oldVersionPrinter(c) - os.Exit(0) - } - - app = cliV2.NewApp() - app.Name = "SealABC" - app.Version = "0.1" - app.HelpName = "SealABC" - app.Usage = "SealABC" - app.UsageText = "SealABC [options] [args]" - app.HideHelp = false - app.HideVersion = false - - cliFlags.SetFlags(app) - SetAction(app) - - //run - err := app.Run(os.Args) - if nil != err { - os.Exit(-1) - } - - return + oldHelpPrinter := cliV2.HelpPrinter + cliV2.HelpPrinter = func(w io.Writer, templ string, data interface{}) { + oldHelpPrinter(w, templ, data) + os.Exit(0) + } + + oldVersionPrinter := cliV2.VersionPrinter + cliV2.VersionPrinter = func(c *cliV2.Context) { + oldVersionPrinter(c) + os.Exit(0) + } + + app = cliV2.NewApp() + app.Name = "SealABC" + app.Version = "0.1" + app.HelpName = "SealABC" + app.Usage = "SealABC" + app.UsageText = "SealABC [options] [args]" + app.HideHelp = false + app.HideVersion = false + + cliFlags.SetFlags(app) + SetAction(app) + + //run + err := app.Run(os.Args) + if nil != err { + os.Exit(-1) + } + + return } diff --git a/cli/cliFlags/config.go b/cli/cliFlags/config.go index 0272a21..0f6d0ea 100644 --- a/cli/cliFlags/config.go +++ b/cli/cliFlags/config.go @@ -23,9 +23,9 @@ import ( func newConfigFlag() cliV2.Flag { return &(cliV2.StringFlag{ - Name: Config, - Usage: "set config file name", - Hidden: false, + Name: Config, + Usage: "set config file name", + Hidden: false, Required: true, }) } diff --git a/cli/cliFlags/const.go b/cli/cliFlags/const.go index 54ac432..9920288 100644 --- a/cli/cliFlags/const.go +++ b/cli/cliFlags/const.go @@ -18,5 +18,5 @@ package cliFlags const ( - Config = "config" + Config = "config" ) diff --git a/cli/parameters.go b/cli/parameters.go index e988814..270a2aa 100644 --- a/cli/parameters.go +++ b/cli/parameters.go @@ -18,9 +18,9 @@ package cli type parameters struct { - ConfigFile string + ConfigFile string } var Parameters = parameters{ - "", + "", } diff --git a/common/constant.go b/common/constant.go index 23313f7..37c9ea2 100644 --- a/common/constant.go +++ b/common/constant.go @@ -18,9 +18,9 @@ package common const ( - JSON_MARSHAL_INDENT = " " + JSON_MARSHAL_INDENT = " " - INT256_BYTE_COUNT = 8 + INT256_BYTE_COUNT = 8 - BASIC_TIME_FORMAT = "2006-01-02 15:04:05" + BASIC_TIME_FORMAT = "2006-01-02 15:04:05" ) diff --git a/common/utility/serializer/structSerializer/deserialization.go b/common/utility/serializer/structSerializer/deserialization.go index 97ddf33..72aa0ec 100644 --- a/common/utility/serializer/structSerializer/deserialization.go +++ b/common/utility/serializer/structSerializer/deserialization.go @@ -18,282 +18,282 @@ package structSerializer import ( - "github.com/SealSC/SealABC/dataStructure/mfb" - "encoding/binary" - "errors" - "reflect" + "encoding/binary" + "errors" + "github.com/SealSC/SealABC/dataStructure/mfb" + "reflect" ) -type standardDeserializer func (value reflect.Value, data []byte) (error) +type standardDeserializer func(value reflect.Value, data []byte) error -var standardDeserializerMap map [reflect.Kind]standardDeserializer +var standardDeserializerMap map[reflect.Kind]standardDeserializer func loadDeserializer() { - standardDeserializerMap = map [reflect.Kind]standardDeserializer{ - reflect.Bool: bytesToBool, - - reflect.Int: bytesToInt, - reflect.Int8: bytesToInt, - reflect.Int16: bytesToInt, - reflect.Int32: bytesToInt, - reflect.Int64: bytesToInt, - - reflect.Uint: bytesToUint, - reflect.Uint8: bytesToUint, - reflect.Uint16: bytesToUint, - reflect.Uint32: bytesToUint, - reflect.Uint64: bytesToUint, - - reflect.String: bytesToString, - - reflect.Array: bytesToArray, - reflect.Slice: bytesToArray, - - reflect.Interface: bytesToInterface, - reflect.Ptr: bytesToInterface, - reflect.Struct: bytesToStruct, - } + standardDeserializerMap = map[reflect.Kind]standardDeserializer{ + reflect.Bool: bytesToBool, + + reflect.Int: bytesToInt, + reflect.Int8: bytesToInt, + reflect.Int16: bytesToInt, + reflect.Int32: bytesToInt, + reflect.Int64: bytesToInt, + + reflect.Uint: bytesToUint, + reflect.Uint8: bytesToUint, + reflect.Uint16: bytesToUint, + reflect.Uint32: bytesToUint, + reflect.Uint64: bytesToUint, + + reflect.String: bytesToString, + + reflect.Array: bytesToArray, + reflect.Slice: bytesToArray, + + reflect.Interface: bytesToInterface, + reflect.Ptr: bytesToInterface, + reflect.Struct: bytesToStruct, + } } -func getMarklessElementLen (kind reflect.Kind) (len int) { - switch kind { - case reflect.Bool: - len = 1 - case reflect.Int8, reflect.Uint8: - len = 1 - case reflect.Int16, reflect.Uint16: - len = 2 - case reflect.Int32, reflect.Uint32: - len = 4 - case reflect.Int, reflect.Int64, reflect.Uint, reflect.Uint64: - len = 8 - } - - return +func getMarklessElementLen(kind reflect.Kind) (len int) { + switch kind { + case reflect.Bool: + len = 1 + case reflect.Int8, reflect.Uint8: + len = 1 + case reflect.Int16, reflect.Uint16: + len = 2 + case reflect.Int32, reflect.Uint32: + len = 4 + case reflect.Int, reflect.Int64, reflect.Uint, reflect.Uint64: + len = 8 + } + + return } func bytesToBool(value reflect.Value, data []byte) (err error) { - if 1 == data[0] { - value.SetBool(true) - } else { - value.SetBool(false) - } - return + if 1 == data[0] { + value.SetBool(true) + } else { + value.SetBool(false) + } + return } func bytesToInt(value reflect.Value, data []byte) (err error) { - var dataVal int64 - switch value.Kind() { - case reflect.Int8: - dataVal = int64(data[0]) - case reflect.Int16: - dataVal = int64(binary.BigEndian.Uint16(data)) - case reflect.Int32: - dataVal = int64(binary.BigEndian.Uint32(data)) - case reflect.Int, reflect.Int64: - dataVal = int64(binary.BigEndian.Uint64(data)) - } - value.SetInt(dataVal) - return + var dataVal int64 + switch value.Kind() { + case reflect.Int8: + dataVal = int64(data[0]) + case reflect.Int16: + dataVal = int64(binary.BigEndian.Uint16(data)) + case reflect.Int32: + dataVal = int64(binary.BigEndian.Uint32(data)) + case reflect.Int, reflect.Int64: + dataVal = int64(binary.BigEndian.Uint64(data)) + } + value.SetInt(dataVal) + return } func bytesToUint(value reflect.Value, data []byte) (err error) { - var dataVal uint64 - switch value.Kind() { - case reflect.Uint8: - dataVal = uint64(data[0]) - case reflect.Uint16: - dataVal = uint64(binary.BigEndian.Uint16(data)) - case reflect.Uint32: - dataVal = uint64(binary.BigEndian.Uint32(data)) - case reflect.Uint, reflect.Uint64: - dataVal = uint64(binary.BigEndian.Uint64(data)) - } - value.SetUint(dataVal) - return + var dataVal uint64 + switch value.Kind() { + case reflect.Uint8: + dataVal = uint64(data[0]) + case reflect.Uint16: + dataVal = uint64(binary.BigEndian.Uint16(data)) + case reflect.Uint32: + dataVal = uint64(binary.BigEndian.Uint32(data)) + case reflect.Uint, reflect.Uint64: + dataVal = uint64(binary.BigEndian.Uint64(data)) + } + value.SetUint(dataVal) + return } func bytesToString(value reflect.Value, data []byte) (err error) { - value.SetString(string(data)) - return + value.SetString(string(data)) + return } -type bytesToArrayMethod func (el reflect.Value, data []byte, kind reflect.Kind) (err error) -func bytesToComplexArray(el reflect.Value, data []byte, kind reflect.Kind,) (err error) { - return callStandardDeserializer(kind, el, data) +type bytesToArrayMethod func(el reflect.Value, data []byte, kind reflect.Kind) (err error) + +func bytesToComplexArray(el reflect.Value, data []byte, kind reflect.Kind) (err error) { + return callStandardDeserializer(kind, el, data) } -func bytesToStructArray(el reflect.Value, data []byte, kind reflect.Kind,) (err error) { - return fromMFBytes(data, el, true) +func bytesToStructArray(el reflect.Value, data []byte, kind reflect.Kind) (err error) { + return fromMFBytes(data, el, true) } func bytesToArray(value reflect.Value, data []byte) (err error) { - elKind := value.Type().Elem().Kind() - sType := value.Type() - - var arrayFromReflect reflect.Value - var sMakeType reflect.Type - if sType.Kind() == reflect.Slice { - sMakeType = sType - } else { - sMakeType = reflect.SliceOf(value.Type().Elem()) - } - - sElLen := getMarklessElementLen(elKind) - if !isMarklessSlice(elKind) { - mfBytes := mfb.MarkedFlatBytes(data) - var bytesList [][]byte - bytesList, err = mfBytes.ToByteSlice() - if err != nil { - return - } - - sLen := len(bytesList) - - if len(bytesList) == 0 { - return - } - - arrayFromReflect = reflect.MakeSlice(sMakeType, sLen, sLen) - - var deserializeMethod bytesToArrayMethod - if elKind == reflect.Struct { - deserializeMethod = bytesToStructArray - } else { - deserializeMethod = bytesToComplexArray - } - - for i:=0; i buffer.Len() { - break - } + if elLength > buffer.Len() { + break + } - bufferList = append(bufferList, buffer.Next(elLength)) - } + bufferList = append(bufferList, buffer.Next(elLength)) + } - return + return } diff --git a/engine/engine.go b/engine/engine.go index 1d1e647..589a67c 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -20,5 +20,5 @@ package engine import "github.com/SealSC/SealABC/engine/engineStartup" func Startup(cfg engineStartup.Config) { - _ = engineStartup.Start(cfg) + _ = engineStartup.Start(cfg) } diff --git a/engine/engineApi/api.go b/engine/engineApi/api.go index 5b2a238..c661e8b 100644 --- a/engine/engineApi/api.go +++ b/engine/engineApi/api.go @@ -18,9 +18,9 @@ package engineApi import ( - "github.com/SealSC/SealABC/engine/engineApi/httpJSON" + "github.com/SealSC/SealABC/engine/engineApi/httpJSON" ) func Start(cfg Config) { - httpJSON.Start(cfg.HttpJSON) + httpJSON.Start(cfg.HttpJSON) } diff --git a/engine/engineApi/config.go b/engine/engineApi/config.go index 77c5793..3d0970a 100644 --- a/engine/engineApi/config.go +++ b/engine/engineApi/config.go @@ -20,5 +20,5 @@ package engineApi import "github.com/SealSC/SealABC/network/http" type Config struct { - HttpJSON http.Config + HttpJSON http.Config } diff --git a/engine/engineApi/httpJSON/actions/actions.go b/engine/engineApi/httpJSON/actions/actions.go index e99c378..9442f60 100644 --- a/engine/engineApi/httpJSON/actions/actions.go +++ b/engine/engineApi/httpJSON/actions/actions.go @@ -18,36 +18,36 @@ package actions import ( - "github.com/SealSC/SealABC/network/http" - "github.com/SealSC/SealABC/service" + "github.com/SealSC/SealABC/network/http" + "github.com/SealSC/SealABC/service" ) var actionList []http.IRequestHandler var serverConfig http.Config func Load(cfg http.Config) []http.IRequestHandler { - serverConfig = cfg + serverConfig = cfg - actionList = []http.IRequestHandler{ - ListServices, - } + actionList = []http.IRequestHandler{ + ListServices, + } - return actionList + return actionList } func ApiInformation() (list []service.ApiInterface) { - for _, act := range actionList { - actInfo := act.BasicInformation() - ai := service.ApiInterface{} + for _, act := range actionList { + actInfo := act.BasicInformation() + ai := service.ApiInterface{} - ai.Description = actInfo.Description - ai.Path = actInfo.Path - ai.Method = actInfo.Method - ai.Parameters = (service.Parameters)(actInfo.Parameters) + ai.Description = actInfo.Description + ai.Path = actInfo.Path + ai.Method = actInfo.Method + ai.Parameters = (service.Parameters)(actInfo.Parameters) - list = append(list, ai) - } + list = append(list, ai) + } - return + return } diff --git a/engine/engineApi/httpJSON/actions/listServices.go b/engine/engineApi/httpJSON/actions/listServices.go index 6194fab..f247102 100644 --- a/engine/engineApi/httpJSON/actions/listServices.go +++ b/engine/engineApi/httpJSON/actions/listServices.go @@ -18,54 +18,53 @@ package actions import ( - "github.com/gin-gonic/gin" - "github.com/SealSC/SealABC/engine/engineService" - "github.com/SealSC/SealABC/network/http" - "github.com/SealSC/SealABC/service" + "github.com/SealSC/SealABC/engine/engineService" + "github.com/SealSC/SealABC/network/http" + "github.com/SealSC/SealABC/service" + "github.com/gin-gonic/gin" ) -type listServices struct{ - path string +type listServices struct { + path string } var ListServices = &listServices{ - path: "/list/services", + path: "/list/services", } type engineSetting struct { - Consensus interface{} + Consensus interface{} } -func (c *listServices)Handle(ctx *gin.Context) { - res := http.NewResponse(ctx) +func (c *listServices) Handle(ctx *gin.Context) { + res := http.NewResponse(ctx) - basicInfo := service.BasicInformation{} + basicInfo := service.BasicInformation{} - es := engineSetting{} + es := engineSetting{} - basicInfo.Name = "Seal ABC" - basicInfo.Description = "the engine of Seal ABC blockchain framework" - settingsInfo, subService := engineService.GetServicesBasicInformation() - es.Consensus = settingsInfo - basicInfo.Settings = es - basicInfo.SubServices = subService - basicInfo.Api.Protocol = service.ApiProtocols.HTTP.String() - basicInfo.Api.Address = serverConfig.Address - basicInfo.Api.ApiList = ApiInformation() + basicInfo.Name = "Seal ABC" + basicInfo.Description = "the engine of Seal ABC blockchain framework" + settingsInfo, subService := engineService.GetServicesBasicInformation() + es.Consensus = settingsInfo + basicInfo.Settings = es + basicInfo.SubServices = subService + basicInfo.Api.Protocol = service.ApiProtocols.HTTP.String() + basicInfo.Api.Address = serverConfig.Address + basicInfo.Api.ApiList = ApiInformation() - res.OK(basicInfo) + res.OK(basicInfo) } -func (c *listServices)RouteRegister(router gin.IRouter) { - router.GET(serverConfig.BasePath + c.path, c.Handle) +func (c *listServices) RouteRegister(router gin.IRouter) { + router.GET(serverConfig.BasePath+c.path, c.Handle) } -func (c *listServices)BasicInformation() (info http.HandlerBasicInformation) { +func (c *listServices) BasicInformation() (info http.HandlerBasicInformation) { - info.Description = "this method will list all the services mounted on this engine." - info.Path = serverConfig.BasePath + c.path - info.Method = service.ApiProtocolMethod.HttpGet.String() + info.Description = "this method will list all the services mounted on this engine." + info.Path = serverConfig.BasePath + c.path + info.Method = service.ApiProtocolMethod.HttpGet.String() - return + return } - diff --git a/engine/engineApi/httpJSON/server.go b/engine/engineApi/httpJSON/server.go index 0894bee..788a903 100644 --- a/engine/engineApi/httpJSON/server.go +++ b/engine/engineApi/httpJSON/server.go @@ -18,17 +18,17 @@ package httpJSON import ( - "github.com/SealSC/SealABC/network/http" - "github.com/SealSC/SealABC/engine/engineApi/httpJSON/actions" + "github.com/SealSC/SealABC/engine/engineApi/httpJSON/actions" + "github.com/SealSC/SealABC/network/http" ) func Start(cfg http.Config) { - httpServer := http.Server { - Config: &cfg, - } + httpServer := http.Server{ + Config: &cfg, + } - httpServer.Config.AllowCORS = true - httpServer.Config.RequestHandler = actions.Load(cfg) + httpServer.Config.AllowCORS = true + httpServer.Config.RequestHandler = actions.Load(cfg) - httpServer.Start() + httpServer.Start() } diff --git a/engine/engineService/informations.go b/engine/engineService/informations.go index c279c8a..5813969 100644 --- a/engine/engineService/informations.go +++ b/engine/engineService/informations.go @@ -18,25 +18,24 @@ package engineService import ( - "github.com/SealSC/SealABC/consensus" - "github.com/SealSC/SealABC/service" + "github.com/SealSC/SealABC/consensus" + "github.com/SealSC/SealABC/service" ) var consensusService consensus.IConsensusService -func SetConsensusInformation(cs consensus.IConsensusService) { - consensusService = cs +func SetConsensusInformation(cs consensus.IConsensusService) { + consensusService = cs } func GetServicesBasicInformation() (consensusInfo interface{}, subService []service.BasicInformation) { - serviceLock.RLock() - defer serviceLock.RUnlock() + serviceLock.RLock() + defer serviceLock.RUnlock() - consensusInfo = consensusService.StaticInformation() - for _, s := range serviceMap { - subService = append(subService, s.Information()) - } + consensusInfo = consensusService.StaticInformation() + for _, s := range serviceMap { + subService = append(subService, s.Information()) + } - return + return } - diff --git a/engine/engineStartup/consensus.go b/engine/engineStartup/consensus.go index 9f4a7f0..831b99f 100644 --- a/engine/engineStartup/consensus.go +++ b/engine/engineStartup/consensus.go @@ -18,15 +18,15 @@ package engineStartup import ( - "github.com/SealSC/SealABC/consensus" - "github.com/SealSC/SealABC/network" + "github.com/SealSC/SealABC/consensus" + "github.com/SealSC/SealABC/network" ) func startConsensus(service consensus.IConsensusService, ns network.IService, processor consensus.ExternalProcessor) (err error) { - //load service to consensus driver - service = consensus.Load(service, ns, processor) + //load service to consensus driver + service = consensus.Load(service, ns, processor) - //start consensus - err = consensus.Driver.Start(config.Consensus) - return + //start consensus + err = consensus.Driver.Start(config.Consensus) + return } diff --git a/engine/engineStartup/network.go b/engine/engineStartup/network.go index 9e63dae..9efa40e 100644 --- a/engine/engineStartup/network.go +++ b/engine/engineStartup/network.go @@ -18,29 +18,28 @@ package engineStartup import ( - "github.com/SealSC/SealABC/network" + "github.com/SealSC/SealABC/network" ) func startConsensusNetwork() (networkService network.IService, err error) { - netCfg := config.ConsensusNetwork - networkService = &network.Service{} - networkService.Create(netCfg) + netCfg := config.ConsensusNetwork + networkService = &network.Service{} + networkService.Create(netCfg) + if len(config.ConsensusNetwork.P2PSeeds) == 0 { + return + } - if len(config.ConsensusNetwork.P2PSeeds) == 0 { - return - } + var seedNodes []network.Node + for _, seed := range netCfg.P2PSeeds { + newP2PNode := network.Node{} - var seedNodes []network.Node - for _, seed := range netCfg.P2PSeeds { - newP2PNode := network.Node{} + newP2PNode.ServeAddress = seed + newP2PNode.Protocol = netCfg.ServiceProtocol - newP2PNode.ServeAddress = seed - newP2PNode.Protocol = netCfg.ServiceProtocol + seedNodes = append(seedNodes, newP2PNode) + } - seedNodes = append(seedNodes, newP2PNode) - } - - err = networkService.Join(seedNodes, nil) - return + err = networkService.Join(seedNodes, nil) + return } diff --git a/engine/engineStartup/storage.go b/engine/engineStartup/storage.go index a267731..48e385f 100644 --- a/engine/engineStartup/storage.go +++ b/engine/engineStartup/storage.go @@ -18,9 +18,9 @@ package engineStartup import ( - "github.com/SealSC/SealABC/storage/db" + "github.com/SealSC/SealABC/storage/db" ) func loadStorage() { - db.Load() + db.Load() } diff --git a/engine/engineStartup/systemService.go b/engine/engineStartup/systemService.go index d345092..ba68157 100644 --- a/engine/engineStartup/systemService.go +++ b/engine/engineStartup/systemService.go @@ -18,11 +18,11 @@ package engineStartup import ( - "github.com/SealSC/SealABC/service/system" - "github.com/SealSC/SealABC/service" + "github.com/SealSC/SealABC/service" + "github.com/SealSC/SealABC/service/system" ) func startSystemService() { - service.Load() - system.Load() + service.Load() + system.Load() } diff --git a/log/log.go b/log/log.go index d9e8362..17b6547 100644 --- a/log/log.go +++ b/log/log.go @@ -18,6 +18,7 @@ package log import ( + "fmt" "github.com/sirupsen/logrus" "io" "os" @@ -25,7 +26,6 @@ import ( "runtime" "strconv" "time" - "fmt" ) type scLog struct { @@ -33,8 +33,8 @@ type scLog struct { } type Config struct { - Level logrus.Level - LogFile string + Level logrus.Level + LogFile string } var Log *scLog @@ -51,10 +51,10 @@ func SetUpLogger(cfg Config) { } Log.Formatter = &logrus.TextFormatter{ - ForceColors: true, + ForceColors: true, DisableTimestamp: false, - FullTimestamp:true, - TimestampFormat: time.StampMilli, + FullTimestamp: true, + TimestampFormat: time.StampMilli, } // Only log the warning severity or above. @@ -72,50 +72,49 @@ func (l *scLog) Tracef(format string, args ...interface{}) { } func (l *scLog) Error(args ...interface{}) { - args = getTraceInfo(args) - l.Logger.Error(args) + args = getTraceInfo(args) + l.Logger.Error(args) } func (l *scLog) Errorf(format string, args ...interface{}) { - args = getTraceInfo(args) - l.Logger.Errorf("%s "+format, args...) + args = getTraceInfo(args) + l.Logger.Errorf("%s "+format, args...) } - func getTraceInfo(args ...interface{}) []interface{} { pc := make([]uintptr, 10) runtime.Callers(3, pc) - var stackRows = []interface{} {"\r\n"} - for i := 0; i<10; i++ { - f := runtime.FuncForPC(pc[i]) - if nil == f { - break - } - file, line := f.FileLine(pc[i]) - fileName := filepath.Base(file) - nameFull := f.Name() - - stackRows = append(stackRows, "func " + nameFull + "@" + fileName + ":" + strconv.Itoa(line - 1) + "\r\n") - } - - ret := append([]interface{}{}, args...) - return append(ret, stackRows...) + var stackRows = []interface{}{"\r\n"} + for i := 0; i < 10; i++ { + f := runtime.FuncForPC(pc[i]) + if nil == f { + break + } + file, line := f.FileLine(pc[i]) + fileName := filepath.Base(file) + nameFull := f.Name() + + stackRows = append(stackRows, "func "+nameFull+"@"+fileName+":"+strconv.Itoa(line-1)+"\r\n") + } + + ret := append([]interface{}{}, args...) + return append(ret, stackRows...) } func TracePanic() { - r := recover() - if nil != r { - printPanic(r) - } + r := recover() + if nil != r { + printPanic(r) + } } -func printPanic(r interface{}) { - if nil == Log { - trace := getTraceInfo() - fmt.Println(trace...) - fmt.Println("got a panic: ", r) - } else { - Log.Errorf("got a panic: %#v", r) - } -} \ No newline at end of file +func printPanic(r interface{}) { + if nil == Log { + trace := getTraceInfo() + fmt.Println(trace...) + fmt.Println("got a panic: ", r) + } else { + Log.Errorf("got a panic: %#v", r) + } +} diff --git a/metadata/applicationCommonConfig/entity.go b/metadata/applicationCommonConfig/entity.go index f8b0674..7be378a 100644 --- a/metadata/applicationCommonConfig/entity.go +++ b/metadata/applicationCommonConfig/entity.go @@ -18,17 +18,17 @@ package applicationCommonConfig import ( - "github.com/SealSC/SealABC/crypto" - "github.com/SealSC/SealABC/storage/db/dbDrivers/levelDB" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" + "github.com/SealSC/SealABC/crypto" + "github.com/SealSC/SealABC/storage/db/dbDrivers/levelDB" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" ) type Config struct { - KVDBName string - KVDBConfig levelDB.Config + KVDBName string + KVDBConfig levelDB.Config - EnableSQLDB bool - SQLStorage simpleSQLDatabase.IDriver + EnableSQLDB bool + SQLStorage simpleSQLDatabase.IDriver - CryptoTools crypto.Tools + CryptoTools crypto.Tools } diff --git a/metadata/applicationResult/entity.go b/metadata/applicationResult/entity.go index 3bfe3a6..98f4b26 100644 --- a/metadata/applicationResult/entity.go +++ b/metadata/applicationResult/entity.go @@ -20,7 +20,7 @@ package applicationResult import "github.com/SealSC/SealABC/metadata/seal" type Entity struct { - Data interface{} + Data interface{} - Seal *seal.Entity + Seal *seal.Entity } diff --git a/metadata/block/operation.go b/metadata/block/operation.go index 0109a9e..c268aa2 100644 --- a/metadata/block/operation.go +++ b/metadata/block/operation.go @@ -18,24 +18,24 @@ package block import ( - "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" - "github.com/SealSC/SealABC/crypto" + "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" + "github.com/SealSC/SealABC/crypto" ) func (e *Entity) Sign(tools crypto.Tools, privateKey []byte) (err error) { - blockHeaderBytes, _ := structSerializer.ToMFBytes(e.EntityData.Header) - err = e.Seal.Sign(blockHeaderBytes, tools, privateKey) - return + blockHeaderBytes, _ := structSerializer.ToMFBytes(e.EntityData.Header) + err = e.Seal.Sign(blockHeaderBytes, tools, privateKey) + return } func (e *Entity) Verify(tools crypto.Tools) (passed bool, err error) { - passed = false - blockHeaderBytes, _ := structSerializer.ToMFBytes(e.EntityData.Header) + passed = false + blockHeaderBytes, _ := structSerializer.ToMFBytes(e.EntityData.Header) - passed, err = e.Seal.Verify(blockHeaderBytes, tools.HashCalculator) - if err != nil { - return - } + passed, err = e.Seal.Verify(blockHeaderBytes, tools.HashCalculator) + if err != nil { + return + } - return + return } diff --git a/metadata/blockchainRequest/entity.go b/metadata/blockchainRequest/entity.go index c6fa1f3..c156bb5 100644 --- a/metadata/blockchainRequest/entity.go +++ b/metadata/blockchainRequest/entity.go @@ -18,20 +18,20 @@ package blockchainRequest import ( - "github.com/SealSC/SealABC/metadata/seal" + "github.com/SealSC/SealABC/metadata/seal" ) type EntityData struct { - RequestApplication string - RequestAction string - Data []byte - QueryString string + RequestApplication string + RequestAction string + Data []byte + QueryString string } type Entity struct { - EntityData + EntityData - Packed bool - PackedCount uint32 - Seal seal.Entity + Packed bool + PackedCount uint32 + Seal seal.Entity } diff --git a/metadata/httpJSONResult/rowsWithCount/entity.go b/metadata/httpJSONResult/rowsWithCount/entity.go index eb3697b..2331528 100644 --- a/metadata/httpJSONResult/rowsWithCount/entity.go +++ b/metadata/httpJSONResult/rowsWithCount/entity.go @@ -18,6 +18,6 @@ package rowsWithCount type Entity struct { - Rows []interface{} - Total uint64 + Rows []interface{} + Total uint64 } diff --git a/metadata/message/message.go b/metadata/message/message.go index 25510c1..f38e88c 100644 --- a/metadata/message/message.go +++ b/metadata/message/message.go @@ -18,11 +18,10 @@ package message type Message struct { - Family string - Version string - Type string - Payload []byte - Hash []byte - Signature []byte + Family string + Version string + Type string + Payload []byte + Hash []byte + Signature []byte } - diff --git a/metadata/serviceRequest/entity.go b/metadata/serviceRequest/entity.go index faf1384..b304dee 100644 --- a/metadata/serviceRequest/entity.go +++ b/metadata/serviceRequest/entity.go @@ -20,15 +20,15 @@ package serviceRequest import "github.com/SealSC/SealABC/metadata/seal" type EntityData struct { - Sender string - RequestService string - RequestAction string + Sender string + RequestService string + RequestAction string - Payload string + Payload string } type Entity struct { - EntityData + EntityData - CustomerSeal seal.Entity + CustomerSeal seal.Entity } diff --git a/network/config.go b/network/config.go index e467e7f..c567033 100644 --- a/network/config.go +++ b/network/config.go @@ -18,15 +18,15 @@ package network type Config struct { - ID string + ID string - ClientOnly bool + ClientOnly bool - ServiceProtocol string - ServiceAddress string + ServiceProtocol string + ServiceAddress string - P2PSeeds []string + P2PSeeds []string - Topology ITopology - Router IRouter -} \ No newline at end of file + Topology ITopology + Router IRouter +} diff --git a/network/directConnect.go b/network/directConnect.go index 48f597c..0f9f192 100644 --- a/network/directConnect.go +++ b/network/directConnect.go @@ -20,78 +20,77 @@ package network //type TopologyRegister func(IProcessor) (error) type ITopology interface { - Name() string + Name() string - MountTo(router IRouter) - BuildNodeID(node Node) string + MountTo(router IRouter) + BuildNodeID(node Node) string - InterestedMessage(msg Message) (interested bool) - MessageProcessor(msg Message, link ILink) + InterestedMessage(msg Message) (interested bool) + MessageProcessor(msg Message, link ILink) - Join(seed LinkNode) (err error) - Leave() + Join(seed LinkNode) (err error) + Leave() - SetLocalNode(node LinkNode) - GetLink(node Node) (link ILink, err error) - GetAllNodes() []LinkNode + SetLocalNode(node LinkNode) + GetLink(node Node) (link ILink, err error) + GetAllNodes() []LinkNode - AddLink(link ILink) - RemoveLink(link ILink) + AddLink(link ILink) + RemoveLink(link ILink) } -type directConnect struct{ - LocalNode LinkNode +type directConnect struct { + LocalNode LinkNode } func (t *directConnect) Name() string { - return "direct connect" + return "direct connect" } -func (t *directConnect)MountTo(router IRouter) { - return +func (t *directConnect) MountTo(router IRouter) { + return } -func (t *directConnect)BuildNodeID(node Node) string { - return node.ServeAddress +func (t *directConnect) BuildNodeID(node Node) string { + return node.ServeAddress } -func (t *directConnect)InterestedMessage(msg Message) (interested bool) { - return false +func (t *directConnect) InterestedMessage(msg Message) (interested bool) { + return false } -func (t *directConnect)MessageProcessor(msg Message, link ILink) { - return +func (t *directConnect) MessageProcessor(msg Message, link ILink) { + return } -func (t *directConnect)Join(node LinkNode) (err error) { - return +func (t *directConnect) Join(node LinkNode) (err error) { + return } -func (t *directConnect)Leave() { - return +func (t *directConnect) Leave() { + return } - -func (t *directConnect)SetLocalNode(node LinkNode) { - t.LocalNode = node +func (t *directConnect) SetLocalNode(node LinkNode) { + t.LocalNode = node } -func (t *directConnect)GetLocalNode() (node LinkNode) { - return t.LocalNode +func (t *directConnect) GetLocalNode() (node LinkNode) { + return t.LocalNode } -func (t *directConnect)GetLink(node Node) (link ILink, err error) { - return +func (t *directConnect) GetLink(node Node) (link ILink, err error) { + return } -func (t *directConnect)GetAllNodes() (all []LinkNode) { - return +func (t *directConnect) GetAllNodes() (all []LinkNode) { + return } -func (t *directConnect)AddLink(link ILink) { +func (t *directConnect) AddLink(link ILink) { } -func (t *directConnect)RemoveLink(link ILink) { +func (t *directConnect) RemoveLink(link ILink) { -} \ No newline at end of file +} diff --git a/network/http/config.go b/network/http/config.go index 9acce9e..e54f628 100644 --- a/network/http/config.go +++ b/network/http/config.go @@ -18,9 +18,9 @@ package http type Config struct { - Address string `json:"address"` - BasePath string `json:"base_path"` - EnableTLS bool `json:"enable_tls"` - AllowCORS bool `json:"allow_cors"` - RequestHandler []IRequestHandler `json:"-"` + Address string `json:"address"` + BasePath string `json:"base_path"` + EnableTLS bool `json:"enable_tls"` + AllowCORS bool `json:"allow_cors"` + RequestHandler []IRequestHandler `json:"-"` } diff --git a/network/http/handler.go b/network/http/handler.go index 5f32ad3..c7eb1da 100644 --- a/network/http/handler.go +++ b/network/http/handler.go @@ -20,19 +20,19 @@ package http import "github.com/gin-gonic/gin" type Parameters struct { - Type string - Template interface{} + Type string + Template interface{} } type HandlerBasicInformation struct { - Path string - Method string - Description string - Parameters Parameters + Path string + Method string + Description string + Parameters Parameters } type IRequestHandler interface { - Handle(ctx *gin.Context) - RouteRegister(router gin.IRouter) - BasicInformation() (info HandlerBasicInformation) + Handle(ctx *gin.Context) + RouteRegister(router gin.IRouter) + BasicInformation() (info HandlerBasicInformation) } diff --git a/network/http/http.go b/network/http/http.go index 2a200f5..e23747a 100644 --- a/network/http/http.go +++ b/network/http/http.go @@ -18,52 +18,52 @@ package http import ( - "github.com/SealSC/SealABC/log" - "errors" - "github.com/gin-gonic/gin" - "net/http" + "errors" + "github.com/SealSC/SealABC/log" + "github.com/gin-gonic/gin" + "net/http" ) type Server struct { - Config *Config + Config *Config } -func (s *Server)Start() (err error) { - if s.Config == nil { - err = errors.New("no configure") - return - } +func (s *Server) Start() (err error) { + if s.Config == nil { + err = errors.New("no configure") + return + } - router := gin.Default() + router := gin.Default() - router.Use(func(c *gin.Context) { - if s.Config.AllowCORS { - c.Header("Access-Control-Allow-Origin", "*") - } + router.Use(func(c *gin.Context) { + if s.Config.AllowCORS { + c.Header("Access-Control-Allow-Origin", "*") + } - if c.Request.Method == "OPTIONS" { - if len(c.Request.Header["Access-Control-Request-Headers"]) > 0 { - c.Header("Access-Control-Allow-Headers", c.Request.Header["Access-Control-Request-Headers"][0]) - } - c.AbortWithStatus(http.StatusNoContent) - } else { - c.Next() - } - }) - s.setRouters(router, *s.Config) + if c.Request.Method == "OPTIONS" { + if len(c.Request.Header["Access-Control-Request-Headers"]) > 0 { + c.Header("Access-Control-Allow-Headers", c.Request.Header["Access-Control-Request-Headers"][0]) + } + c.AbortWithStatus(http.StatusNoContent) + } else { + c.Next() + } + }) + s.setRouters(router, *s.Config) - go func() { - runSrvErr := router.Run(s.Config.Address) - if runSrvErr != nil { - log.Log.Warn("start http server failed: ", runSrvErr.Error()) - } - }() + go func() { + runSrvErr := router.Run(s.Config.Address) + if runSrvErr != nil { + log.Log.Warn("start http server failed: ", runSrvErr.Error()) + } + }() - return + return } -func (s *Server)setRouters(router *gin.Engine, cfg Config) { - for _, v := range cfg.RequestHandler { - v.RouteRegister(router) - } +func (s *Server) setRouters(router *gin.Engine, cfg Config) { + for _, v := range cfg.RequestHandler { + v.RouteRegister(router) + } } diff --git a/network/http/response.go b/network/http/response.go index 883aac0..493ff8e 100644 --- a/network/http/response.go +++ b/network/http/response.go @@ -23,18 +23,18 @@ import ( ) type ServiceResult struct { - Code int64 `json:"code"` - Success bool `json:"success"` - Data interface{} `json:"data"` + Code int64 `json:"code"` + Success bool `json:"success"` + Data interface{} `json:"data"` } type Response struct { - ctx *gin.Context + ctx *gin.Context } func NewResponse(ctx *gin.Context) *Response { return &Response{ - ctx: ctx, + ctx: ctx, } } @@ -60,13 +60,13 @@ func (c *Response) OK(data interface{}) { //service response will always set http status to 200. func (c *Response) ServiceError(code int64, data interface{}) { - c.ctx.JSON(http.StatusOK, &ServiceResult{ - code, false,data, - }) + c.ctx.JSON(http.StatusOK, &ServiceResult{ + code, false, data, + }) } func (c *Response) ServiceSuccess(data interface{}) { - c.ctx.JSON(http.StatusOK, &ServiceResult{ - 0, true,data, - }) + c.ctx.JSON(http.StatusOK, &ServiceResult{ + 0, true, data, + }) } diff --git a/network/http/utils.go b/network/http/utils.go index 5dc78fa..10c99c8 100644 --- a/network/http/utils.go +++ b/network/http/utils.go @@ -18,16 +18,16 @@ package http import ( - "github.com/gin-gonic/gin" - "encoding/json" + "encoding/json" + "github.com/gin-gonic/gin" ) func GetPostedJson(ctx *gin.Context, output interface{}) (rawData []byte, err error) { - rawData, err = ctx.GetRawData() - if nil != err { - return - } + rawData, err = ctx.GetRawData() + if nil != err { + return + } - err = json.Unmarshal(rawData, output) - return + err = json.Unmarshal(rawData, output) + return } diff --git a/network/link.go b/network/link.go index 07e8cfa..e73ee5a 100644 --- a/network/link.go +++ b/network/link.go @@ -18,143 +18,143 @@ package network import ( - "net" - "io" - "bufio" - "github.com/SealSC/SealABC/log" - "sync" + "bufio" + "github.com/SealSC/SealABC/log" + "io" + "net" + "sync" ) const ( - max_buffer_size = 10 * 1024 * 1024 + max_buffer_size = 10 * 1024 * 1024 ) type ILink interface { - Start() - StartReceiving() - SendData(data [] byte) (n int, err error) - SendMessage(msg Message) (n int, err error) - RemoteAddr() net.Addr - Close() + Start() + StartReceiving() + SendData(data []byte) (n int, err error) + SendMessage(msg Message) (n int, err error) + RemoteAddr() net.Addr + Close() } type Link struct { - Connection net.Conn - Reader *bufio.Reader - Writer *bufio.Writer - RawMessageProcessor RawMessageProcessor - LinkClosed LinkClosed - ConnectOut bool - - senderLock sync.Mutex + Connection net.Conn + Reader *bufio.Reader + Writer *bufio.Writer + RawMessageProcessor RawMessageProcessor + LinkClosed LinkClosed + ConnectOut bool + + senderLock sync.Mutex } func (l *Link) RemoteAddr() net.Addr { - return l.Connection.RemoteAddr() + return l.Connection.RemoteAddr() } -func (l *Link)Start() { +func (l *Link) Start() { - l.Reader = bufio.NewReader(l.Connection) - l.Writer = bufio.NewWriter(l.Connection) + l.Reader = bufio.NewReader(l.Connection) + l.Writer = bufio.NewWriter(l.Connection) - go l.StartReceiving() + go l.StartReceiving() } -func (l *Link)StartReceiving() { - defer func() { - l.Close() - l.LinkClosed(l) - }() - - for { - msgPrefix := make([]byte, MESSAGE_PREFIX_LEN, MESSAGE_PREFIX_LEN) - data := make([]byte, max_buffer_size, max_buffer_size) - - n, err := io.ReadFull(l.Reader, msgPrefix) //l.Reader.Read(msgPrefix[:]) - if n != MESSAGE_PREFIX_LEN { - log.Log.Println("get msg prefix failed: need ", MESSAGE_PREFIX_LEN, " bytes, got ", n, " bytes. ", err) - } - - if err != nil { - if err == io.EOF { - log.Log.Println("disconnect remote: ", err) - break - } - log.Log.Println("got an network error: ", err) - continue - } - - prefix := MessagePrefix{} - err = prefix.FromBytes(msgPrefix) - if err != nil { - log.Log.Warn("unknown message: ", err.Error()) - unreadSize := l.Reader.Size() - _, _ =l.Reader.Discard(unreadSize) - continue - } - - if prefix.Size > MAX_MESSAGE_LEN { - _, _ = l.Reader.Discard(int(prefix.Size)) - continue - } - - n, err = io.ReadFull(l.Reader, data[:prefix.Size]) - //n, err := l.Reader.Read(data[:prefix.Size]) - - if int32(n) != prefix.Size { - log.Log.Println("error message: need ", prefix.Size, "bytes bug got ", n, " bytes") - //log.Log.Println("error ", err.Error()) - return - } - - if err != nil { - if err == io.EOF { - log.Log.Println("disconnect remote: ", err) - break - } - log.Log.Println("got an network error: ", err) - continue - } - - go l.RawMessageProcessor(data[:prefix.Size], l) - } +func (l *Link) StartReceiving() { + defer func() { + l.Close() + l.LinkClosed(l) + }() + + for { + msgPrefix := make([]byte, MESSAGE_PREFIX_LEN, MESSAGE_PREFIX_LEN) + data := make([]byte, max_buffer_size, max_buffer_size) + + n, err := io.ReadFull(l.Reader, msgPrefix) //l.Reader.Read(msgPrefix[:]) + if n != MESSAGE_PREFIX_LEN { + log.Log.Println("get msg prefix failed: need ", MESSAGE_PREFIX_LEN, " bytes, got ", n, " bytes. ", err) + } + + if err != nil { + if err == io.EOF { + log.Log.Println("disconnect remote: ", err) + break + } + log.Log.Println("got an network error: ", err) + continue + } + + prefix := MessagePrefix{} + err = prefix.FromBytes(msgPrefix) + if err != nil { + log.Log.Warn("unknown message: ", err.Error()) + unreadSize := l.Reader.Size() + _, _ = l.Reader.Discard(unreadSize) + continue + } + + if prefix.Size > MAX_MESSAGE_LEN { + _, _ = l.Reader.Discard(int(prefix.Size)) + continue + } + + n, err = io.ReadFull(l.Reader, data[:prefix.Size]) + //n, err := l.Reader.Read(data[:prefix.Size]) + + if int32(n) != prefix.Size { + log.Log.Println("error message: need ", prefix.Size, "bytes bug got ", n, " bytes") + //log.Log.Println("error ", err.Error()) + return + } + + if err != nil { + if err == io.EOF { + log.Log.Println("disconnect remote: ", err) + break + } + log.Log.Println("got an network error: ", err) + continue + } + + go l.RawMessageProcessor(data[:prefix.Size], l) + } } -func (l *Link)SendMessage(msg Message) (n int, err error) { - data, err := msg.ToRawMessage() - if err != nil { - return - } +func (l *Link) SendMessage(msg Message) (n int, err error) { + data, err := msg.ToRawMessage() + if err != nil { + return + } - return l.SendData(data) + return l.SendData(data) } -func (l *Link)SendData(data []byte) (n int, err error) { - l.senderLock.Lock() - defer l.senderLock.Unlock() - - n, err = l.Writer.Write(data) - if err != nil { - log.Log.Warn("got an error when write to buffer: ", err.Error()) - return - } - - if n != len(data) { - log.Log.Warn("not write the complete data to buffer: ", n, " bytes written but need: ", len(data), " bytes") - } - - err = l.Writer.Flush() - - if n == 0 { - log.Log.Println("sent 0 bytes to ", l.RemoteAddr()) - if err != nil { - log.Log.Warn(" and got an error: ", err.Error()) - } - } - return +func (l *Link) SendData(data []byte) (n int, err error) { + l.senderLock.Lock() + defer l.senderLock.Unlock() + + n, err = l.Writer.Write(data) + if err != nil { + log.Log.Warn("got an error when write to buffer: ", err.Error()) + return + } + + if n != len(data) { + log.Log.Warn("not write the complete data to buffer: ", n, " bytes written but need: ", len(data), " bytes") + } + + err = l.Writer.Flush() + + if n == 0 { + log.Log.Println("sent 0 bytes to ", l.RemoteAddr()) + if err != nil { + log.Log.Warn(" and got an error: ", err.Error()) + } + } + return } -func (l *Link)Close() { - l.Connection.Close() +func (l *Link) Close() { + l.Connection.Close() } diff --git a/network/message.go b/network/message.go index 43ea70a..fa8eafa 100644 --- a/network/message.go +++ b/network/message.go @@ -18,100 +18,97 @@ package network import ( - "encoding/binary" - "encoding/json" - "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/metadata/message" - "errors" + "encoding/binary" + "encoding/json" + "errors" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/metadata/message" ) - - const ( - MSG_JOIN = 0 - MSG_LEAVE = 1 - MSG_BROADCAST = 2 - MSG_MULTICAST = 3 - MSG_UNICAST = 4 + MSG_JOIN = 0 + MSG_LEAVE = 1 + MSG_BROADCAST = 2 + MSG_MULTICAST = 3 + MSG_UNICAST = 4 - MAGIC_WORD = "[what a day ^_T]" + MAGIC_WORD = "[what a day ^_T]" - MAGIC_WORD_LEN = len(MAGIC_WORD) - SIZE_LEN = 4 - SIZE_DATA_TYPE = 1 + MAGIC_WORD_LEN = len(MAGIC_WORD) + SIZE_LEN = 4 + SIZE_DATA_TYPE = 1 - MESSAGE_PREFIX_LEN = SIZE_LEN + SIZE_DATA_TYPE + MAGIC_WORD_LEN + MESSAGE_PREFIX_LEN = SIZE_LEN + SIZE_DATA_TYPE + MAGIC_WORD_LEN - MAX_MESSAGE_LEN = 8 * 1024 * 1024 //raw message max size will be (8 MB + MESSAGE_PREFIX_LEN) bytes. + MAX_MESSAGE_LEN = 8 * 1024 * 1024 //raw message max size will be (8 MB + MESSAGE_PREFIX_LEN) bytes. - JSON_TYPE = 0x00 + JSON_TYPE = 0x00 ) type Message struct { - message.Message - From Node + message.Message + From Node } -func (m Message) ToRawMessage() (rawMsg []byte, err error) { - msgJson, err := json.Marshal(m) - if err != nil { - log.Log.Println("marshal message faild: ", err) - return - } - - msgSize := len(msgJson) +func (m Message) ToRawMessage() (rawMsg []byte, err error) { + msgJson, err := json.Marshal(m) + if err != nil { + log.Log.Println("marshal message faild: ", err) + return + } + msgSize := len(msgJson) - rawMsg = append([]byte(MAGIC_WORD)) - rawMsg = append(rawMsg, JSON_TYPE) + rawMsg = append([]byte(MAGIC_WORD)) + rawMsg = append(rawMsg, JSON_TYPE) - msgSizeBytes := make([]byte, SIZE_LEN, SIZE_LEN) - binary.BigEndian.PutUint32(msgSizeBytes, uint32(msgSize)) - rawMsg = append(rawMsg, msgSizeBytes...) - rawMsg = append(rawMsg, msgJson...) + msgSizeBytes := make([]byte, SIZE_LEN, SIZE_LEN) + binary.BigEndian.PutUint32(msgSizeBytes, uint32(msgSize)) + rawMsg = append(rawMsg, msgSizeBytes...) + rawMsg = append(rawMsg, msgJson...) - return + return } func (m *Message) FromRawMessage(msgData []byte) (err error) { - err = json.Unmarshal(msgData, m) - if err != nil { - log.Log.Println("not json message: ", string(msgData)) - return - } + err = json.Unmarshal(msgData, m) + if err != nil { + log.Log.Println("not json message: ", string(msgData)) + return + } - return + return } type MessagePrefix struct { - Size int32 - DataType byte + Size int32 + DataType byte } func (m *MessagePrefix) FromBytes(prefix []byte) (err error) { - off := 0 - magic := prefix[ : MAGIC_WORD_LEN] - if string(magic) != MAGIC_WORD { - err = errors.New("unknown raw message") - return - } - off += MAGIC_WORD_LEN - - dataType := prefix[off] - off += SIZE_DATA_TYPE - - if dataType != JSON_TYPE { - err = errors.New("only support json for now") - return - } - - size := binary.BigEndian.Uint32(prefix[off : off + SIZE_LEN]) - if size > MAX_MESSAGE_LEN { - //err = errors.New("message too large") - log.Log.Warn("only support ", MAX_MESSAGE_LEN, " bytes message, but got ", size) - } - - m.Size = int32(size) - m.DataType = dataType - return + off := 0 + magic := prefix[:MAGIC_WORD_LEN] + if string(magic) != MAGIC_WORD { + err = errors.New("unknown raw message") + return + } + off += MAGIC_WORD_LEN + + dataType := prefix[off] + off += SIZE_DATA_TYPE + + if dataType != JSON_TYPE { + err = errors.New("only support json for now") + return + } + + size := binary.BigEndian.Uint32(prefix[off : off+SIZE_LEN]) + if size > MAX_MESSAGE_LEN { + //err = errors.New("message too large") + log.Log.Warn("only support ", MAX_MESSAGE_LEN, " bytes message, but got ", size) + } + + m.Size = int32(size) + m.DataType = dataType + return } diff --git a/network/network.go b/network/network.go index 431d684..c500612 100644 --- a/network/network.go +++ b/network/network.go @@ -18,134 +18,131 @@ package network import ( - "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/metadata/message" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/metadata/message" ) type StaticInformation struct { - Topology string - ConnectedNode []string + Topology string + ConnectedNode []string } type IService interface { - Self() (node Node) + Self() (node Node) - Create(cfg Config) (err error) - ConnectTo(Node) (err error) + Create(cfg Config) (err error) + ConnectTo(Node) (err error) - Join(seeds []Node, cfg *Config) (err error) - Leave() + Join(seeds []Node, cfg *Config) (err error) + Leave() - GetAllLinkedNode() (nodes []Node) + GetAllLinkedNode() (nodes []Node) - SendTo(node Node, msg message.Message) (n int, err error) - Broadcast(msg message.Message) (err error) + SendTo(node Node, msg message.Message) (n int, err error) + Broadcast(msg message.Message) (err error) - RegisterMessageProcessor(msgFamily string, processor MessageProcessor) + RegisterMessageProcessor(msgFamily string, processor MessageProcessor) - StaticInformation() StaticInformation + StaticInformation() StaticInformation } type Service struct { - started bool - router IRouter + started bool + router IRouter } func NewNetworkNodeFromLink(link ILink) (node LinkNode) { - node.Protocol = link.RemoteAddr().Network() - node.Link = link - return node + node.Protocol = link.RemoteAddr().Network() + node.Link = link + return node } func (s *Service) StaticInformation() (info StaticInformation) { - info.Topology = s.router.TopologyName() - linkedNode := s.router.GetAllLinkedNode() + info.Topology = s.router.TopologyName() + linkedNode := s.router.GetAllLinkedNode() - nodes := []string {s.Self().ServeAddress} - for _, n := range linkedNode { - nodes = append(nodes, n.ServeAddress) - } + nodes := []string{s.Self().ServeAddress} + for _, n := range linkedNode { + nodes = append(nodes, n.ServeAddress) + } - info.ConnectedNode = nodes + info.ConnectedNode = nodes - return + return } -func (s *Service)Self() (node Node) { - return s.router.Self() +func (s *Service) Self() (node Node) { + return s.router.Self() } func (s *Service) ConnectTo(node Node) (err error) { - _, err = s.router.ConnectTo(node) - return + _, err = s.router.ConnectTo(node) + return } func (s *Service) Create(cfg Config) (err error) { - //create router - if cfg.Router != nil { - s.router = cfg.Router - } else { - s.router = &Router{} - } - - //start router - err = s.router.Start(cfg) - if err != nil { - log.Log.Println("create p2p network failed. ", err) - return - } - s.started = true - return + //create router + if cfg.Router != nil { + s.router = cfg.Router + } else { + s.router = &Router{} + } + + //start router + err = s.router.Start(cfg) + if err != nil { + log.Log.Println("create p2p network failed. ", err) + return + } + s.started = true + return } func (s *Service) Join(seeds []Node, serviceCfg *Config) (err error) { - if !s.started && serviceCfg != nil{ - err = s.Create(*serviceCfg) - if err != nil { - return - } - } - - for _, node := range seeds { - err = s.router.JoinTopology(node) - if err == nil { - break - } - - log.Log.Println("connect to seeds ", node, " failed.") - } - - if err != nil { - log.Log.Println("connect to p2p network failed -> seeds : ", seeds) - return - } - - s.started = true - - return + if !s.started && serviceCfg != nil { + err = s.Create(*serviceCfg) + if err != nil { + return + } + } + + for _, node := range seeds { + err = s.router.JoinTopology(node) + if err == nil { + break + } + + log.Log.Println("connect to seeds ", node, " failed.") + } + + if err != nil { + log.Log.Println("connect to p2p network failed -> seeds : ", seeds) + return + } + + s.started = true + + return } func (s *Service) Leave() { - s.router.LeaveTopology() + s.router.LeaveTopology() } func (s *Service) GetAllLinkedNode() (nodes []Node) { - return s.router.GetAllLinkedNode() + return s.router.GetAllLinkedNode() } func (s *Service) SendTo(node Node, msg message.Message) (sent int, err error) { - networkMsg := Message{} - networkMsg.Message = msg - return s.router.SendTo(node, networkMsg) + networkMsg := Message{} + networkMsg.Message = msg + return s.router.SendTo(node, networkMsg) } func (s *Service) Broadcast(msg message.Message) (err error) { - return s.router.Broadcast(msg) + return s.router.Broadcast(msg) } func (s *Service) RegisterMessageProcessor(msgFamily string, processor MessageProcessor) { - s.router.RegisterMessageProcessor(msgFamily, processor) + s.router.RegisterMessageProcessor(msgFamily, processor) } - - - diff --git a/network/node.go b/network/node.go index 8bbc885..d1950f5 100644 --- a/network/node.go +++ b/network/node.go @@ -18,13 +18,13 @@ package network type Node struct { - ID string - Protocol string - ServeAddress string - CustomerData []byte + ID string + Protocol string + ServeAddress string + CustomerData []byte } type LinkNode struct { - Node - Link ILink + Node + Link ILink } diff --git a/network/processor.go b/network/processor.go index c976480..30f397d 100644 --- a/network/processor.go +++ b/network/processor.go @@ -18,6 +18,6 @@ package network type IProcessor interface { - Handle(message Message, network *Service) (result interface{}, err error) - ForMessage() string + Handle(message Message, network *Service) (result interface{}, err error) + ForMessage() string } diff --git a/network/router.go b/network/router.go index a22240f..dd73838 100644 --- a/network/router.go +++ b/network/router.go @@ -18,10 +18,10 @@ package network import ( - "net" - "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/metadata/message" - "sync" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/metadata/message" + "net" + "sync" ) type RawMessageProcessor func(data []byte, link ILink) @@ -29,234 +29,234 @@ type MessageProcessor func(msg Message) (reply *Message) type LinkClosed func(link ILink) type IRouter interface { - Self() Node + Self() Node - TopologyName() string + TopologyName() string - Start(cfg Config) (err error) - Listen(listener net.Listener) - ConnectTo(node Node) (linkedNode LinkNode, err error) + Start(cfg Config) (err error) + Listen(listener net.Listener) + ConnectTo(node Node) (linkedNode LinkNode, err error) - LinkClosed(link ILink) + LinkClosed(link ILink) - JoinTopology(seed Node) (err error) - LeaveTopology() - GetAllLinkedNode() (nodes []Node) + JoinTopology(seed Node) (err error) + LeaveTopology() + GetAllLinkedNode() (nodes []Node) - RawMessageProcessor(data []byte, link ILink) - RegisterMessageProcessor(msgFamily string, processor MessageProcessor) + RawMessageProcessor(data []byte, link ILink) + RegisterMessageProcessor(msgFamily string, processor MessageProcessor) - SendTo(node Node, msg Message) (n int, err error) - Broadcast(msg message.Message) (err error) + SendTo(node Node, msg Message) (n int, err error) + Broadcast(msg message.Message) (err error) } type Router struct { - Topology ITopology - MessageProcessorMap map[string]MessageProcessor - LocalNode LinkNode + Topology ITopology + MessageProcessorMap map[string]MessageProcessor + LocalNode LinkNode - rawProcessorLock sync.Mutex + rawProcessorLock sync.Mutex } -func (r *Router) Self() Node{ - return r.LocalNode.Node +func (r *Router) Self() Node { + return r.LocalNode.Node } func (r *Router) TopologyName() string { - return r.Topology.Name() + return r.Topology.Name() } func (r *Router) Start(cfg Config) (err error) { - r.MessageProcessorMap = map[string]MessageProcessor{} - if cfg.Topology != nil { - r.Topology = cfg.Topology - } else { - r.Topology = &directConnect{} - } - - r.Topology.MountTo(r) - - localNode := LinkNode{} - localNode.Protocol = cfg.ServiceProtocol - localNode.ServeAddress = cfg.ServiceAddress - if cfg.ID == "" { - localNode.ID = r.Topology.BuildNodeID(localNode.Node) - } else { - localNode.ID = cfg.ID - } - - r.LocalNode = localNode - r.Topology.SetLocalNode(localNode) - - log.Log.Println("[ I am ]: ", localNode.ID) - - var listener net.Listener - if !cfg.ClientOnly { - listener, err = net.Listen(cfg.ServiceProtocol, cfg.ServiceAddress) - if err != nil { - return - } - - go r.Listen(listener) - } - - return + r.MessageProcessorMap = map[string]MessageProcessor{} + if cfg.Topology != nil { + r.Topology = cfg.Topology + } else { + r.Topology = &directConnect{} + } + + r.Topology.MountTo(r) + + localNode := LinkNode{} + localNode.Protocol = cfg.ServiceProtocol + localNode.ServeAddress = cfg.ServiceAddress + if cfg.ID == "" { + localNode.ID = r.Topology.BuildNodeID(localNode.Node) + } else { + localNode.ID = cfg.ID + } + + r.LocalNode = localNode + r.Topology.SetLocalNode(localNode) + + log.Log.Println("[ I am ]: ", localNode.ID) + + var listener net.Listener + if !cfg.ClientOnly { + listener, err = net.Listen(cfg.ServiceProtocol, cfg.ServiceAddress) + if err != nil { + return + } + + go r.Listen(listener) + } + + return } func (r *Router) Listen(listener net.Listener) { - for { - conn, err := listener.Accept() - if err != nil { - log.Log.Println("accept error:", err) - break - } - - newLink := Link{ - Connection: conn, - ConnectOut: false, - RawMessageProcessor: r.RawMessageProcessor, - LinkClosed: r.LinkClosed, - } - - r.Topology.AddLink(&newLink) - newLink.Start() - } + for { + conn, err := listener.Accept() + if err != nil { + log.Log.Println("accept error:", err) + break + } + + newLink := Link{ + Connection: conn, + ConnectOut: false, + RawMessageProcessor: r.RawMessageProcessor, + LinkClosed: r.LinkClosed, + } + + r.Topology.AddLink(&newLink) + newLink.Start() + } } -func (r *Router)ConnectTo(node Node) (linkedNode LinkNode, err error) { - conn, err := net.Dial(node.Protocol, node.ServeAddress) - if err != nil { - log.Log.Println("got an error: ", err) - return - } - - link := Link{ - Connection: conn, - ConnectOut: true, - RawMessageProcessor: r.RawMessageProcessor, - LinkClosed: r.LinkClosed, - } - link.Start() - - linkedNode = NewNetworkNodeFromLink(&link) - linkedNode.ServeAddress = node.ServeAddress - linkedNode.ID = r.Topology.BuildNodeID(linkedNode.Node) - - return +func (r *Router) ConnectTo(node Node) (linkedNode LinkNode, err error) { + conn, err := net.Dial(node.Protocol, node.ServeAddress) + if err != nil { + log.Log.Println("got an error: ", err) + return + } + + link := Link{ + Connection: conn, + ConnectOut: true, + RawMessageProcessor: r.RawMessageProcessor, + LinkClosed: r.LinkClosed, + } + link.Start() + + linkedNode = NewNetworkNodeFromLink(&link) + linkedNode.ServeAddress = node.ServeAddress + linkedNode.ID = r.Topology.BuildNodeID(linkedNode.Node) + + return } -func (r *Router)LinkClosed(link ILink) { - r.Topology.RemoveLink(link) - return +func (r *Router) LinkClosed(link ILink) { + r.Topology.RemoveLink(link) + return } -func (r *Router)JoinTopology(seed Node) (err error) { - if seed.ID == "" { - seed.ID = r.Topology.BuildNodeID(seed) - } +func (r *Router) JoinTopology(seed Node) (err error) { + if seed.ID == "" { + seed.ID = r.Topology.BuildNodeID(seed) + } - if _, err = r.Topology.GetLink(seed); err == nil { - return - } + if _, err = r.Topology.GetLink(seed); err == nil { + return + } - linkedNode, err := r.ConnectTo(seed) - if err != nil { - return - } + linkedNode, err := r.ConnectTo(seed) + if err != nil { + return + } - log.Log.Println("connect to seed: ", seed) - err = r.Topology.Join(linkedNode) + log.Log.Println("connect to seed: ", seed) + err = r.Topology.Join(linkedNode) - return + return } -func (r *Router)LeaveTopology() { - r.Topology.Leave() +func (r *Router) LeaveTopology() { + r.Topology.Leave() } -func (r *Router)GetAllLinkedNode() (nodes []Node) { - linkedNodes := r.Topology.GetAllNodes() - for _, n := range linkedNodes { - nodes = append(nodes, n.Node) - } +func (r *Router) GetAllLinkedNode() (nodes []Node) { + linkedNodes := r.Topology.GetAllNodes() + for _, n := range linkedNodes { + nodes = append(nodes, n.Node) + } - return + return } func (r *Router) RegisterMessageProcessor(msgFamily string, processor MessageProcessor) { - r.MessageProcessorMap[msgFamily] = processor + r.MessageProcessorMap[msgFamily] = processor } func (r *Router) RawMessageProcessor(data []byte, link ILink) { - r.rawProcessorLock.Lock() - defer r.rawProcessorLock.Unlock() - - newMsg := Message{} - err := newMsg.FromRawMessage(data) - if err != nil { - return - } - - if r.Topology.InterestedMessage(newMsg) { - r.Topology.MessageProcessor(newMsg, link) - } - - msgProcessor, exists := r.MessageProcessorMap[newMsg.Family] - if !exists { - return - } - - replyMsg := msgProcessor(newMsg) - if replyMsg == nil { - return - } - - replyMsg.From = r.LocalNode.Node - rawMsg, err := replyMsg.ToRawMessage() - if err != nil { - return - } - - n, err := link.SendData(rawMsg) - - if err != nil { - log.Log.Println("reply message failed. ", err) - log.Log.Printf("\r\nshould sent %d real sent %d \r\n", len(rawMsg), n) - } - - rawMsg = nil + r.rawProcessorLock.Lock() + defer r.rawProcessorLock.Unlock() + + newMsg := Message{} + err := newMsg.FromRawMessage(data) + if err != nil { + return + } + + if r.Topology.InterestedMessage(newMsg) { + r.Topology.MessageProcessor(newMsg, link) + } + + msgProcessor, exists := r.MessageProcessorMap[newMsg.Family] + if !exists { + return + } + + replyMsg := msgProcessor(newMsg) + if replyMsg == nil { + return + } + + replyMsg.From = r.LocalNode.Node + rawMsg, err := replyMsg.ToRawMessage() + if err != nil { + return + } + + n, err := link.SendData(rawMsg) + + if err != nil { + log.Log.Println("reply message failed. ", err) + log.Log.Printf("\r\nshould sent %d real sent %d \r\n", len(rawMsg), n) + } + + rawMsg = nil } -func (r *Router)SendTo(node Node, msg Message) (n int, err error) { - link, err := r.Topology.GetLink(node) - if err != nil { - return - } +func (r *Router) SendTo(node Node, msg Message) (n int, err error) { + link, err := r.Topology.GetLink(node) + if err != nil { + return + } - msg.From = r.LocalNode.Node - rawMsg, err := msg.ToRawMessage() - if err != nil { - return - } + msg.From = r.LocalNode.Node + rawMsg, err := msg.ToRawMessage() + if err != nil { + return + } - n, err = link.SendData(rawMsg) - if err != nil { - log.Log.Error("send data failed: data length ", len(rawMsg), " error: ", err.Error()) - } + n, err = link.SendData(rawMsg) + if err != nil { + log.Log.Error("send data failed: data length ", len(rawMsg), " error: ", err.Error()) + } - return + return } -func (r *Router)Broadcast(msg message.Message) (err error) { - networkMsg := Message{ - Message: msg, - From: r.LocalNode.Node, - } - - targets := r.Topology.GetAllNodes() - for _, t := range targets { - n := t.Node - go r.SendTo(n, networkMsg) - } - return +func (r *Router) Broadcast(msg message.Message) (err error) { + networkMsg := Message{ + Message: msg, + From: r.LocalNode.Node, + } + + targets := r.Topology.GetAllNodes() + for _, t := range targets { + n := t.Node + go r.SendTo(n, networkMsg) + } + return } diff --git a/network/topology/p2p/fullyConnect/fullyConnect.go b/network/topology/p2p/fullyConnect/fullyConnect.go index f043feb..bf3947a 100644 --- a/network/topology/p2p/fullyConnect/fullyConnect.go +++ b/network/topology/p2p/fullyConnect/fullyConnect.go @@ -18,10 +18,10 @@ package fullyConnect import ( - "github.com/SealSC/SealABC/network" - "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/topology" + "github.com/SealSC/SealABC/network" + "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/topology" ) func NewTopology() network.ITopology { - return &topology.Topology{} + return &topology.Topology{} } diff --git a/network/topology/p2p/fullyConnect/message/message.go b/network/topology/p2p/fullyConnect/message/message.go index 1ff659a..148e10a 100644 --- a/network/topology/p2p/fullyConnect/message/message.go +++ b/network/topology/p2p/fullyConnect/message/message.go @@ -18,21 +18,20 @@ package message import ( - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/network" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/network" ) type messageTypes struct { - Join enum.Element - JoinReply enum.Element - Leave enum.Element - Ping enum.Element - Pong enum.Element - GetNeighbors enum.Element - GetNeighborsReply enum.Element - Neighbors enum.Element - PushNeighbors enum.Element - + Join enum.Element + JoinReply enum.Element + Leave enum.Element + Ping enum.Element + Pong enum.Element + GetNeighbors enum.Element + GetNeighborsReply enum.Element + Neighbors enum.Element + PushNeighbors enum.Element } const Family = "full-connected-p2p" @@ -40,17 +39,16 @@ const Family = "full-connected-p2p" var Types messageTypes func LoadMessageTypes() { - enum.Build(&Types, 0, "p2p-protocol-msg-") + enum.Build(&Types, 0, "p2p-protocol-msg-") } func NewMessage(msgType enum.Element, payload []byte) (msg network.Message) { - //msg := network.Message{} + //msg := network.Message{} - msg.Version = "0.0.1" - msg.Family = Family - msg.Type = msgType.String() - msg.Payload = payload + msg.Version = "0.0.1" + msg.Family = Family + msg.Type = msgType.String() + msg.Payload = payload - return + return } - diff --git a/network/topology/p2p/fullyConnect/message/payload/join.go b/network/topology/p2p/fullyConnect/message/payload/join.go index 2cae606..e6381bc 100644 --- a/network/topology/p2p/fullyConnect/message/payload/join.go +++ b/network/topology/p2p/fullyConnect/message/payload/join.go @@ -18,6 +18,6 @@ package payload type Join struct { - TargetID string - SourceID string + TargetID string + SourceID string } diff --git a/network/topology/p2p/fullyConnect/message/payload/joinReply.go b/network/topology/p2p/fullyConnect/message/payload/joinReply.go index 1928521..8d6d129 100644 --- a/network/topology/p2p/fullyConnect/message/payload/joinReply.go +++ b/network/topology/p2p/fullyConnect/message/payload/joinReply.go @@ -18,7 +18,6 @@ package payload type JoinReply struct { - PrevID string - RealID string + PrevID string + RealID string } - diff --git a/network/topology/p2p/fullyConnect/message/payload/neighbors.go b/network/topology/p2p/fullyConnect/message/payload/neighbors.go index be9b703..aed0d5d 100644 --- a/network/topology/p2p/fullyConnect/message/payload/neighbors.go +++ b/network/topology/p2p/fullyConnect/message/payload/neighbors.go @@ -20,5 +20,5 @@ package payload import "github.com/SealSC/SealABC/network" type NeighborsPayload struct { - Neighbors []network.Node + Neighbors []network.Node } diff --git a/network/topology/p2p/fullyConnect/message/payload/payload.go b/network/topology/p2p/fullyConnect/message/payload/payload.go index b78d058..d42b0de 100644 --- a/network/topology/p2p/fullyConnect/message/payload/payload.go +++ b/network/topology/p2p/fullyConnect/message/payload/payload.go @@ -18,10 +18,10 @@ package payload import ( - "github.com/SealSC/SealABC/network" - "encoding/json" + "encoding/json" + "github.com/SealSC/SealABC/network" ) func FromMessage(msg network.Message, payload interface{}) (err error) { - return json.Unmarshal(msg.Payload, payload) + return json.Unmarshal(msg.Payload, payload) } diff --git a/network/topology/p2p/fullyConnect/message/payload/pingpong.go b/network/topology/p2p/fullyConnect/message/payload/pingpong.go index 1b32ee4..1d4a752 100644 --- a/network/topology/p2p/fullyConnect/message/payload/pingpong.go +++ b/network/topology/p2p/fullyConnect/message/payload/pingpong.go @@ -20,11 +20,11 @@ package payload import "math/rand" type PingPongPayload struct { - Number int + Number int } func NewPing() (next PingPongPayload) { - return PingPongPayload { - Number: rand.Int(), - } + return PingPongPayload{ + Number: rand.Int(), + } } diff --git a/network/topology/p2p/fullyConnect/topology/join.go b/network/topology/p2p/fullyConnect/topology/join.go index cc4b025..20f774a 100644 --- a/network/topology/p2p/fullyConnect/topology/join.go +++ b/network/topology/p2p/fullyConnect/topology/join.go @@ -18,73 +18,75 @@ package topology import ( - "github.com/SealSC/SealABC/network" - "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/message" - "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/message/payload" - "encoding/json" - "github.com/SealSC/SealABC/log" + "encoding/json" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/network" + "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/message" + "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/message/payload" ) -type joinMessageProcessor struct {} -func (j *joinMessageProcessor)Process(msg network.Message, t *Topology, link network.ILink) (err error) { - join := payload.Join{} - err = payload.FromMessage(msg, &join) - if err != nil { - log.Log.Println("not join protocol ") - return - } - - joinReply := payload.JoinReply{ - PrevID: join.TargetID, - RealID: t.LocalNode.ID, - } - replyPayload, _ := json.Marshal(joinReply) - - target, exist := t.getPreJoinNode(link) - - if !exist { - return - } - - log.Log.Println("got join message from: ", msg.From) - target.Node = msg.From - t.setJoinedNode(target) - - reply := message.NewMessage(message.Types.JoinReply, replyPayload) - reply.From = t.LocalNode.Node - rawReply, _ := reply.ToRawMessage() - _, err = target.Link.SendData(rawReply) - if err != nil { - log.Log.Warn("send join reply failed: ", err.Error()) - } - return +type joinMessageProcessor struct{} + +func (j *joinMessageProcessor) Process(msg network.Message, t *Topology, link network.ILink) (err error) { + join := payload.Join{} + err = payload.FromMessage(msg, &join) + if err != nil { + log.Log.Println("not join protocol ") + return + } + + joinReply := payload.JoinReply{ + PrevID: join.TargetID, + RealID: t.LocalNode.ID, + } + replyPayload, _ := json.Marshal(joinReply) + + target, exist := t.getPreJoinNode(link) + + if !exist { + return + } + + log.Log.Println("got join message from: ", msg.From) + target.Node = msg.From + t.setJoinedNode(target) + + reply := message.NewMessage(message.Types.JoinReply, replyPayload) + reply.From = t.LocalNode.Node + rawReply, _ := reply.ToRawMessage() + _, err = target.Link.SendData(rawReply) + if err != nil { + log.Log.Warn("send join reply failed: ", err.Error()) + } + return } -type joinReplyMessageProcessor struct {} -func (j *joinReplyMessageProcessor)Process(msg network.Message, t *Topology, link network.ILink) (err error) { - joinReply := payload.JoinReply{} - err = payload.FromMessage(msg, &joinReply) +type joinReplyMessageProcessor struct{} - if err != nil { - log.Log.Println("not join-reply protocol ") - return - } +func (j *joinReplyMessageProcessor) Process(msg network.Message, t *Topology, link network.ILink) (err error) { + joinReply := payload.JoinReply{} + err = payload.FromMessage(msg, &joinReply) - target, exist := t.getPreJoinNode(link) + if err != nil { + log.Log.Println("not join-reply protocol ") + return + } - if !exist { - return - } + target, exist := t.getPreJoinNode(link) - log.Log.Println("got joinReply message from: ", msg.From) - target.Node = msg.From - t.setJoinedNode(target) + if !exist { + return + } - //doPing(link) + log.Log.Println("got joinReply message from: ", msg.From) + target.Node = msg.From + t.setJoinedNode(target) - //get neighbors - getNeighbors(target) - return + //doPing(link) + + //get neighbors + getNeighbors(target) + return } var JoinMessageProcessor = &joinMessageProcessor{} diff --git a/network/topology/p2p/fullyConnect/topology/neighbors.go b/network/topology/p2p/fullyConnect/topology/neighbors.go index ba4c7d3..b58d6e7 100644 --- a/network/topology/p2p/fullyConnect/topology/neighbors.go +++ b/network/topology/p2p/fullyConnect/topology/neighbors.go @@ -18,70 +18,71 @@ package topology import ( - "github.com/SealSC/SealABC/network" - "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/message" - "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/message/payload" - "encoding/json" - "github.com/SealSC/SealABC/log" - "sync" + "encoding/json" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/network" + "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/message" + "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/message/payload" + "sync" ) func getNeighbors(seed network.LinkNode) { - log.Log.Println("get neighbors from: ", seed.ID) - msg := message.NewMessage(message.Types.GetNeighbors, []byte{}) - _, err := seed.Link.SendMessage(msg) - if err != nil { - log.Log.Error("send get neighbors message failed: ", err.Error()) - } + log.Log.Println("get neighbors from: ", seed.ID) + msg := message.NewMessage(message.Types.GetNeighbors, []byte{}) + _, err := seed.Link.SendMessage(msg) + if err != nil { + log.Log.Error("send get neighbors message failed: ", err.Error()) + } } +type getNeighborsMessageProcessor struct{} -type getNeighborsMessageProcessor struct {} -func (j *getNeighborsMessageProcessor)Process(msg network.Message, t *Topology, link network.ILink) (err error) { - allNodes := t.GetAllNodes() - neighbors := payload.NeighborsPayload {} +func (j *getNeighborsMessageProcessor) Process(msg network.Message, t *Topology, link network.ILink) (err error) { + allNodes := t.GetAllNodes() + neighbors := payload.NeighborsPayload{} - for _, n := range allNodes { - neighbors.Neighbors = append(neighbors.Neighbors, n.Node) - } + for _, n := range allNodes { + neighbors.Neighbors = append(neighbors.Neighbors, n.Node) + } - replyPayload, _ := json.Marshal(neighbors) - replyMsg := message.NewMessage(message.Types.GetNeighborsReply, replyPayload) + replyPayload, _ := json.Marshal(neighbors) + replyMsg := message.NewMessage(message.Types.GetNeighborsReply, replyPayload) - _, err = link.SendMessage(replyMsg) + _, err = link.SendMessage(replyMsg) - return + return } var GetNeighborsMessageProcessor = &getNeighborsMessageProcessor{} type getNeighborsReplyMessageProcessor struct { - joinLock sync.Mutex + joinLock sync.Mutex } -func (j *getNeighborsReplyMessageProcessor)Process(msg network.Message, topology *Topology, link network.ILink) (err error) { - neighbors := payload.NeighborsPayload{} - err = payload.FromMessage(msg, & neighbors) - if err != nil { - log.Log.Warn("invalid get neighbor reply message: ", err.Error()) - return err - } - - for _, n := range neighbors.Neighbors { - if topology.isJoined(n.ID) { - continue - } - - j.joinLock.Lock() - err := topology.router.JoinTopology(n) - j.joinLock.Unlock() - - if err != nil { - log.Log.Warn("join neighbor: ", n, " failed.") - continue - } - } - - return + +func (j *getNeighborsReplyMessageProcessor) Process(msg network.Message, topology *Topology, link network.ILink) (err error) { + neighbors := payload.NeighborsPayload{} + err = payload.FromMessage(msg, &neighbors) + if err != nil { + log.Log.Warn("invalid get neighbor reply message: ", err.Error()) + return err + } + + for _, n := range neighbors.Neighbors { + if topology.isJoined(n.ID) { + continue + } + + j.joinLock.Lock() + err := topology.router.JoinTopology(n) + j.joinLock.Unlock() + + if err != nil { + log.Log.Warn("join neighbor: ", n, " failed.") + continue + } + } + + return } var GetNeighborsReplyMessageProcessor = &getNeighborsReplyMessageProcessor{} diff --git a/network/topology/p2p/fullyConnect/topology/pingpong.go b/network/topology/p2p/fullyConnect/topology/pingpong.go index a9f0806..427c996 100644 --- a/network/topology/p2p/fullyConnect/topology/pingpong.go +++ b/network/topology/p2p/fullyConnect/topology/pingpong.go @@ -18,54 +18,53 @@ package topology import ( - "encoding/json" - "github.com/SealSC/SealABC/network" - "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/message" - "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/message/payload" - "time" + "encoding/json" + "github.com/SealSC/SealABC/network" + "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/message" + "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/message/payload" + "time" ) func doPing(link network.ILink) { - ping := payload.NewPing() - pingPayloadBytes, _ := json.Marshal(ping) - msg := message.NewMessage(message.Types.Ping, pingPayloadBytes) - link.SendMessage(msg) + ping := payload.NewPing() + pingPayloadBytes, _ := json.Marshal(ping) + msg := message.NewMessage(message.Types.Ping, pingPayloadBytes) + link.SendMessage(msg) } -type pingMessageProcessor struct {} +type pingMessageProcessor struct{} -func (p *pingMessageProcessor)Process(msg network.Message, t *Topology, link network.ILink) (err error) { - pingPayload := payload.PingPongPayload{} - err = payload.FromMessage(msg, &pingPayload) - if err != nil { - return - } +func (p *pingMessageProcessor) Process(msg network.Message, t *Topology, link network.ILink) (err error) { + pingPayload := payload.PingPongPayload{} + err = payload.FromMessage(msg, &pingPayload) + if err != nil { + return + } - pong := payload.PingPongPayload{ - Number: pingPayload.Number, - } + pong := payload.PingPongPayload{ + Number: pingPayload.Number, + } - replayPayloadBytes, _ := json.Marshal(pong) - reply := message.NewMessage(message.Types.Pong, replayPayloadBytes) - link.SendMessage(reply) + replayPayloadBytes, _ := json.Marshal(pong) + reply := message.NewMessage(message.Types.Pong, replayPayloadBytes) + link.SendMessage(reply) - go func() { - time.Sleep(time.Second * 10) + go func() { + time.Sleep(time.Second * 10) - doPing(link) - }() + doPing(link) + }() - - return + return } -type pongMessageProcessor struct {} -func (p *pongMessageProcessor)Process(msg network.Message, topology *Topology, _ network.ILink) (err error) { - //todo: refresh neighbor's state +type pongMessageProcessor struct{} - return -} +func (p *pongMessageProcessor) Process(msg network.Message, topology *Topology, _ network.ILink) (err error) { + //todo: refresh neighbor's state + return +} var PingMessageProcessor = &pingMessageProcessor{} var PongMessageProcessor = &pongMessageProcessor{} diff --git a/network/topology/p2p/fullyConnect/topology/processor.go b/network/topology/p2p/fullyConnect/topology/processor.go index 79ac438..abf64df 100644 --- a/network/topology/p2p/fullyConnect/topology/processor.go +++ b/network/topology/p2p/fullyConnect/topology/processor.go @@ -18,9 +18,9 @@ package topology import ( - "github.com/SealSC/SealABC/network" + "github.com/SealSC/SealABC/network" ) type iMessageProcessor interface { - Process(msg network.Message, topology *Topology, link network.ILink) (err error) + Process(msg network.Message, topology *Topology, link network.ILink) (err error) } diff --git a/network/topology/p2p/fullyConnect/topology/topology.go b/network/topology/p2p/fullyConnect/topology/topology.go index 66b6a2e..7a29017 100644 --- a/network/topology/p2p/fullyConnect/topology/topology.go +++ b/network/topology/p2p/fullyConnect/topology/topology.go @@ -18,184 +18,182 @@ package topology import ( - "github.com/SealSC/SealABC/crypto/signers/ed25519" - "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/network" - "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/message" - "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/message/payload" - "encoding/json" - "errors" + "encoding/json" + "errors" + "github.com/SealSC/SealABC/crypto/signers/ed25519" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/network" + "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/message" + "github.com/SealSC/SealABC/network/topology/p2p/fullyConnect/message/payload" ) -type Topology struct{ - LocalNode network.LinkNode - preJoinNode map[network.ILink] network.LinkNode - joinedNode map[network.ILink] network.LinkNode - nodeID2Link map[string] network.ILink - messageProcessorMap map[string] iMessageProcessor - router network.IRouter +type Topology struct { + LocalNode network.LinkNode + preJoinNode map[network.ILink]network.LinkNode + joinedNode map[network.ILink]network.LinkNode + nodeID2Link map[string]network.ILink + messageProcessorMap map[string]iMessageProcessor + router network.IRouter } -func (t Topology) Name() string { - return "fully connected P2P" +func (t Topology) Name() string { + return "fully connected P2P" } -func (t *Topology)MountTo(router network.IRouter) { - message.LoadMessageTypes() +func (t *Topology) MountTo(router network.IRouter) { + message.LoadMessageTypes() - t.router = router + t.router = router - t.preJoinNode = map[network.ILink] network.LinkNode{} - t.joinedNode = map[network.ILink] network.LinkNode{} - t.nodeID2Link = map[string] network.ILink{} + t.preJoinNode = map[network.ILink]network.LinkNode{} + t.joinedNode = map[network.ILink]network.LinkNode{} + t.nodeID2Link = map[string]network.ILink{} - t.messageProcessorMap = map[string] iMessageProcessor{ - message.Types.Join.String(): JoinMessageProcessor, - message.Types.JoinReply.String(): JoinReplyMessageProcessor, - message.Types.GetNeighbors.String(): GetNeighborsMessageProcessor, - message.Types.GetNeighborsReply.String(): GetNeighborsReplyMessageProcessor, - message.Types.Ping.String(): PingMessageProcessor, - message.Types.Pong.String(): PongMessageProcessor, - } + t.messageProcessorMap = map[string]iMessageProcessor{ + message.Types.Join.String(): JoinMessageProcessor, + message.Types.JoinReply.String(): JoinReplyMessageProcessor, + message.Types.GetNeighbors.String(): GetNeighborsMessageProcessor, + message.Types.GetNeighborsReply.String(): GetNeighborsReplyMessageProcessor, + message.Types.Ping.String(): PingMessageProcessor, + message.Types.Pong.String(): PongMessageProcessor, + } } -func (t *Topology)BuildNodeID(_ network.Node) string { - //todo: create random id, not key - s, _ := ed25519.SignerGenerator.NewSigner(nil) - return s.PublicKeyString() +func (t *Topology) BuildNodeID(_ network.Node) string { + //todo: create random id, not key + s, _ := ed25519.SignerGenerator.NewSigner(nil) + return s.PublicKeyString() } -func (t *Topology)InterestedMessage(msg network.Message) (interested bool) { - return msg.Family == message.Family +func (t *Topology) InterestedMessage(msg network.Message) (interested bool) { + return msg.Family == message.Family } +func (t *Topology) MessageProcessor(msg network.Message, link network.ILink) { + processor, exists := t.messageProcessorMap[msg.Type] + if !exists { + return + } -func (t *Topology)MessageProcessor(msg network.Message, link network.ILink) { - processor, exists := t.messageProcessorMap[msg.Type] - if !exists { - return - } + err := processor.Process(msg, t, link) - err := processor.Process(msg, t, link) + if err != nil { + log.Log.Println("got p2p error: ", err) + } - if err != nil { - log.Log.Println("got p2p error: ", err) - } - - return + return } -func (t *Topology)SetLocalNode(node network.LinkNode) { - t.LocalNode = node +func (t *Topology) SetLocalNode(node network.LinkNode) { + t.LocalNode = node } -func (t *Topology)GetLocalNode() (node network.LinkNode) { - return t.LocalNode +func (t *Topology) GetLocalNode() (node network.LinkNode) { + return t.LocalNode } func (t *Topology) Join(node network.LinkNode) (err error) { - t.preJoinNode[node.Link] = node - join := payload.Join{ - TargetID: node.ID, - SourceID: t.LocalNode.ID, - } + t.preJoinNode[node.Link] = node + join := payload.Join{ + TargetID: node.ID, + SourceID: t.LocalNode.ID, + } - joinPayload, _ := json.Marshal(join) - joinMsg := message.NewMessage(message.Types.Join, joinPayload) + joinPayload, _ := json.Marshal(join) + joinMsg := message.NewMessage(message.Types.Join, joinPayload) - joinMsg.From = t.LocalNode.Node - _, err = node.Link.SendMessage(joinMsg) - if err != nil { - log.Log.Warn("join to seed failed: ", node.ServeAddress) - } else { - log.Log.Println("send join message to seed success: ", node.ServeAddress) - } - return + joinMsg.From = t.LocalNode.Node + _, err = node.Link.SendMessage(joinMsg) + if err != nil { + log.Log.Warn("join to seed failed: ", node.ServeAddress) + } else { + log.Log.Println("send join message to seed success: ", node.ServeAddress) + } + return } func (t *Topology) Leave() { - return + return } -func (t *Topology)getLinkFromPreJoinList(node network.Node) (link network.ILink) { - for l, n := range t.preJoinNode { - if n.ServeAddress == node.ServeAddress && n.Protocol == node.Protocol { - link = l - break - } - } +func (t *Topology) getLinkFromPreJoinList(node network.Node) (link network.ILink) { + for l, n := range t.preJoinNode { + if n.ServeAddress == node.ServeAddress && n.Protocol == node.Protocol { + link = l + break + } + } - return + return } func (t *Topology) GetLink(node network.Node) (link network.ILink, err error) { - link, exists := t.nodeID2Link[node.ID] - if exists { - return - } + link, exists := t.nodeID2Link[node.ID] + if exists { + return + } - link = t.getLinkFromPreJoinList(node) - if link != nil { - return - } - err = errors.New("no such link") - return + link = t.getLinkFromPreJoinList(node) + if link != nil { + return + } + err = errors.New("no such link") + return } func (t *Topology) GetAllNodes() (all []network.LinkNode) { - for _, n := range t.joinedNode { - if n.ID == t.LocalNode.ID { - continue - } + for _, n := range t.joinedNode { + if n.ID == t.LocalNode.ID { + continue + } - all = append(all, n) - } + all = append(all, n) + } - return + return } func (t *Topology) AddLink(link network.ILink) { - node := network.NewNetworkNodeFromLink(link) - t.preJoinNode[link] = node + node := network.NewNetworkNodeFromLink(link) + t.preJoinNode[link] = node } - -func (t *Topology)RemoveLink(link network.ILink) { - node, exist := t.getNode(link) - if exist { - delete(t.joinedNode, link) - delete(t.nodeID2Link, node.ID) - } - delete(t.preJoinNode, link) +func (t *Topology) RemoveLink(link network.ILink) { + node, exist := t.getNode(link) + if exist { + delete(t.joinedNode, link) + delete(t.nodeID2Link, node.ID) + } + delete(t.preJoinNode, link) } func (t *Topology) getPreJoinNode(link network.ILink) (node network.LinkNode, exist bool) { - node, exist = t.preJoinNode[link] - return + node, exist = t.preJoinNode[link] + return } -func (t *Topology) getNode(link network.ILink) (linkedNode network.LinkNode, exist bool){ - linkedNode, exist = t.joinedNode[link] - return +func (t *Topology) getNode(link network.ILink) (linkedNode network.LinkNode, exist bool) { + linkedNode, exist = t.joinedNode[link] + return } func (t *Topology) setJoinedNode(node network.LinkNode) { - if node.ID == t.LocalNode.ID { - return - } + if node.ID == t.LocalNode.ID { + return + } - t.joinedNode[node.Link] = node - t.nodeID2Link[node.ID] = node.Link - delete(t.preJoinNode, node.Link) + t.joinedNode[node.Link] = node + t.nodeID2Link[node.ID] = node.Link + delete(t.preJoinNode, node.Link) } func (t *Topology) removeNode(node network.LinkNode) { } func (t *Topology) isJoined(id string) (joined bool) { - if id == t.LocalNode.ID { - return true - } - _, joined = t.nodeID2Link[id] - return + if id == t.LocalNode.ID { + return true + } + _, joined = t.nodeID2Link[id] + return } diff --git a/service/application/basicAssets/basicAssetsInterface/basicAssetsInterface.go b/service/application/basicAssets/basicAssetsInterface/basicAssetsInterface.go index b95d804..ad41d57 100644 --- a/service/application/basicAssets/basicAssetsInterface/basicAssetsInterface.go +++ b/service/application/basicAssets/basicAssetsInterface/basicAssetsInterface.go @@ -18,178 +18,178 @@ package basicAssetsInterface import ( - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/metadata/applicationResult" - "github.com/SealSC/SealABC/metadata/block" - "github.com/SealSC/SealABC/metadata/blockchainRequest" - "github.com/SealSC/SealABC/service" - "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" - "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsSQLStorage" - "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" - "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "encoding/json" - "errors" + "encoding/json" + "errors" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/metadata/applicationResult" + "github.com/SealSC/SealABC/metadata/block" + "github.com/SealSC/SealABC/metadata/blockchainRequest" + "github.com/SealSC/SealABC/service" + "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" + "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsSQLStorage" + "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" ) -var QueryDBType struct{ - KV enum.Element - SQL enum.Element +var QueryDBType struct { + KV enum.Element + SQL enum.Element } type BasicAssetsApplication struct { - chainStructure.BlankApplication + chainStructure.BlankApplication - Ledger *basicAssetsLedger.Ledger - SQLStorage *basicAssetsSQLStorage.Storage + Ledger *basicAssetsLedger.Ledger + SQLStorage *basicAssetsSQLStorage.Storage } func (b *BasicAssetsApplication) Name() (name string) { - return "Basic Assets" + return "Basic Assets" } func (b *BasicAssetsApplication) PushClientRequest(req blockchainRequest.Entity) (result interface{}, err error) { - err = b.Ledger.PushTransaction(req) - return + err = b.Ledger.PushTransaction(req) + return } func (b *BasicAssetsApplication) Query(req []byte) (result interface{}, err error) { - queryReq := basicAssetsLedger.QueryRequest{} - err = json.Unmarshal(req, &queryReq) - if err != nil { - return - } - - switch queryReq.DBType { - case QueryDBType.KV.String(): - return b.Ledger.DoQuery(queryReq) - - case QueryDBType.SQL.String(): - return b.SQLStorage.DoQuery(queryReq) - - default: - err = errors.New("no such database type: " + queryReq.DBType) - return - } + queryReq := basicAssetsLedger.QueryRequest{} + err = json.Unmarshal(req, &queryReq) + if err != nil { + return + } + + switch queryReq.DBType { + case QueryDBType.KV.String(): + return b.Ledger.DoQuery(queryReq) + + case QueryDBType.SQL.String(): + return b.SQLStorage.DoQuery(queryReq) + + default: + err = errors.New("no such database type: " + queryReq.DBType) + return + } } func (b *BasicAssetsApplication) PreExecute(req blockchainRequest.Entity, _ block.Entity) (result []byte, err error) { - tx := basicAssetsLedger.Transaction{} - err = json.Unmarshal(req.Data, &tx) - if err != nil { - return - } - - if tx.TxType != req.RequestAction { - err = errors.New("action not same as tx type") - return - } - err = b.Ledger.VerifyTransaction(tx) - - return + tx := basicAssetsLedger.Transaction{} + err = json.Unmarshal(req.Data, &tx) + if err != nil { + return + } + + if tx.TxType != req.RequestAction { + err = errors.New("action not same as tx type") + return + } + err = b.Ledger.VerifyTransaction(tx) + + return } func (b *BasicAssetsApplication) Execute( - req blockchainRequest.Entity, - blk block.Entity, - actIndex uint32, - ) (result applicationResult.Entity, err error) { - - tx := basicAssetsLedger.Transaction{} - err = json.Unmarshal(req.Data, &tx) - if err != nil { - return - } - - execResult, err := b.Ledger.ExecuteTransaction(tx) - if err != nil { - return - } - - reqHash := req.Seal.Hash - err = b.Ledger.SaveTransactionWithBlockInfo(tx, reqHash, blk.Header.Height, actIndex) - if err != nil { - return - } - - b.Ledger.RemoveTransactionFromPool(tx.HashString()) - - if b.SQLStorage != nil { - txWithBlk := basicAssetsLedger.TransactionWithBlockInfo { - Transaction: tx, - } - - txWithBlk.BlockInfo.RequestHash = reqHash - txWithBlk.BlockInfo.BlockHeight = blk.Header.Height - txWithBlk.BlockInfo.ActionIndex = actIndex - - txTypes := basicAssetsLedger.TransactionTypes - - switch tx.TxType { - case txTypes.IssueAssets.String(): - b.storeAssets(txWithBlk, execResult) - - case txTypes.Transfer.String(): - b.storeTransfer(txWithBlk, execResult) - - case txTypes.StartSelling.String(): - fallthrough - case txTypes.StopSelling.String(): - fallthrough - case txTypes.BuyAssets.String(): - b.storeSelling(txWithBlk, execResult) - - case txTypes.IncreaseSupply.String(): - //todo: b.saveAssetsUpdate(txWithBlk) - - default: - break - } - } - return + req blockchainRequest.Entity, + blk block.Entity, + actIndex uint32, +) (result applicationResult.Entity, err error) { + + tx := basicAssetsLedger.Transaction{} + err = json.Unmarshal(req.Data, &tx) + if err != nil { + return + } + + execResult, err := b.Ledger.ExecuteTransaction(tx) + if err != nil { + return + } + + reqHash := req.Seal.Hash + err = b.Ledger.SaveTransactionWithBlockInfo(tx, reqHash, blk.Header.Height, actIndex) + if err != nil { + return + } + + b.Ledger.RemoveTransactionFromPool(tx.HashString()) + + if b.SQLStorage != nil { + txWithBlk := basicAssetsLedger.TransactionWithBlockInfo{ + Transaction: tx, + } + + txWithBlk.BlockInfo.RequestHash = reqHash + txWithBlk.BlockInfo.BlockHeight = blk.Header.Height + txWithBlk.BlockInfo.ActionIndex = actIndex + + txTypes := basicAssetsLedger.TransactionTypes + + switch tx.TxType { + case txTypes.IssueAssets.String(): + b.storeAssets(txWithBlk, execResult) + + case txTypes.Transfer.String(): + b.storeTransfer(txWithBlk, execResult) + + case txTypes.StartSelling.String(): + fallthrough + case txTypes.StopSelling.String(): + fallthrough + case txTypes.BuyAssets.String(): + b.storeSelling(txWithBlk, execResult) + + case txTypes.IncreaseSupply.String(): + //todo: b.saveAssetsUpdate(txWithBlk) + + default: + break + } + } + return } func (b *BasicAssetsApplication) RequestsForBlock(_ block.Entity) (reqList []blockchainRequest.Entity, cnt uint32) { - return b.Ledger.GetTransactionsFromPool() + return b.Ledger.GetTransactionsFromPool() } func (b *BasicAssetsApplication) Information() (info service.BasicInformation) { - info.Name = b.Name() - info.Description = "this is a basic assets application based on a UTXO mode ledger" + info.Name = b.Name() + info.Description = "this is a basic assets application based on a UTXO mode ledger" - info.Api.Protocol = service.ApiProtocols.INTERNAL.String() - info.Api.Address = "" - info.Api.ApiList = []service.ApiInterface {} - return + info.Api.Protocol = service.ApiProtocols.INTERNAL.String() + info.Api.Address = "" + info.Api.ApiList = []service.ApiInterface{} + return } func (b *BasicAssetsApplication) GetActionAsRequest(req blockchainRequest.Entity) blockchainRequest.Entity { - tx := basicAssetsLedger.Transaction{} - _ = json.Unmarshal(req.Data, &tx) + tx := basicAssetsLedger.Transaction{} + _ = json.Unmarshal(req.Data, &tx) - newReq := blockchainRequest.Entity{} - newReq.Seal = tx.Seal - newReq.RequestApplication = b.Name() - newReq.RequestAction = tx.TxType + newReq := blockchainRequest.Entity{} + newReq.Seal = tx.Seal + newReq.RequestApplication = b.Name() + newReq.RequestAction = tx.TxType - newReq.Data, _ = json.Marshal(tx.TransactionData) + newReq.Data, _ = json.Marshal(tx.TransactionData) - return newReq + return newReq } -func Load() { - enum.SimpleBuild(&QueryDBType) - basicAssetsLedger.Load() - basicAssetsSQLStorage.Load() +func Load() { + enum.SimpleBuild(&QueryDBType) + basicAssetsLedger.Load() + basicAssetsSQLStorage.Load() } func NewApplicationInterface(kvDriver kvDatabase.IDriver, sqlDriver simpleSQLDatabase.IDriver) (app chainStructure.IBlockchainExternalApplication) { - bs := BasicAssetsApplication{} - bs.Ledger = basicAssetsLedger.NewLedger(kvDriver) - if sqlDriver != nil { - bs.SQLStorage = basicAssetsSQLStorage.NewStorage(sqlDriver) - } - - app = &bs - return + bs := BasicAssetsApplication{} + bs.Ledger = basicAssetsLedger.NewLedger(kvDriver) + if sqlDriver != nil { + bs.SQLStorage = basicAssetsSQLStorage.NewStorage(sqlDriver) + } + + app = &bs + return } diff --git a/service/application/basicAssets/basicAssetsInterface/storeToSQLDatabase.go b/service/application/basicAssets/basicAssetsInterface/storeToSQLDatabase.go index d1b3f4c..e9b47d5 100644 --- a/service/application/basicAssets/basicAssetsInterface/storeToSQLDatabase.go +++ b/service/application/basicAssets/basicAssetsInterface/storeToSQLDatabase.go @@ -22,7 +22,7 @@ import ( "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" ) -func (b *BasicAssetsApplication) storeAssets(tx basicAssetsLedger.TransactionWithBlockInfo, blc interface{}) { +func (b *BasicAssetsApplication) storeAssets(tx basicAssetsLedger.TransactionWithBlockInfo, blc interface{}) { balance, ok := blc.(basicAssetsLedger.Balance) if !ok { log.Log.Warn("no balance") @@ -39,7 +39,7 @@ func (b *BasicAssetsApplication) storeAssets(tx basicAssetsLedger.TransactionWit } } -func (b *BasicAssetsApplication) storeTransfer(tx basicAssetsLedger.TransactionWithBlockInfo, list interface{}) { +func (b *BasicAssetsApplication) storeTransfer(tx basicAssetsLedger.TransactionWithBlockInfo, list interface{}) { usList, ok := list.(basicAssetsLedger.UnspentListWithBalance) if !ok { log.Log.Warn("transaction has no unspent") @@ -72,4 +72,3 @@ func (b *BasicAssetsApplication) storeSelling(tx basicAssetsLedger.TransactionWi return } - diff --git a/service/application/basicAssets/basicAssetsLedger/assets.go b/service/application/basicAssets/basicAssetsLedger/assets.go index 1c43f3d..de4da3e 100644 --- a/service/application/basicAssets/basicAssetsLedger/assets.go +++ b/service/application/basicAssets/basicAssetsLedger/assets.go @@ -18,146 +18,146 @@ package basicAssetsLedger import ( - "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" - "github.com/SealSC/SealABC/crypto" - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/metadata/seal" - "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" - "bytes" - "encoding/json" - "errors" + "bytes" + "encoding/json" + "errors" + "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" + "github.com/SealSC/SealABC/crypto" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/metadata/seal" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" ) -var AssetsTypes struct{ - General enum.Element - Copyright enum.Element +var AssetsTypes struct { + General enum.Element + Copyright enum.Element } type AssetsData struct { - Name string - Symbol string - Supply uint64 `json:",string"` - Type uint32 `json:",string"` - Increasable bool - ExtraInfo []byte + Name string + Symbol string + Supply uint64 `json:",string"` + Type uint32 `json:",string"` + Increasable bool + ExtraInfo []byte } type Assets struct { - AssetsData + AssetsData - DateTime string - IssuedSeal seal.Entity - MetaSeal seal.Entity + DateTime string + IssuedSeal seal.Entity + MetaSeal seal.Entity } type Copyright struct { - Assets - Owner []byte + Assets + Owner []byte } func (a Assets) getUniqueHash() (hash []byte) { - return a.MetaSeal.Hash + return a.MetaSeal.Hash } func (a Assets) verify(tools crypto.Tools) (err error) { - if !bytes.Equal(a.IssuedSeal.SignerPublicKey, a.MetaSeal.SignerPublicKey) { - err = errors.New("with and without supply's signer are not equal") - return - } - - fullBytes, err := structSerializer.ToMFBytes(a.AssetsData) - if err != nil { - return - } - - a.Supply = 0 - withoutSupplyBytes, _ := structSerializer.ToMFBytes(a.AssetsData) - - _, err = a.IssuedSeal.Verify(fullBytes, tools.HashCalculator) - if err != nil { - err = errors.New("invalid full assets data signature: " + err.Error()) - return - } - - _, err = a.MetaSeal.Verify(withoutSupplyBytes, tools.HashCalculator) - if err != nil { - err = errors.New("invalid assets without supply data signature: " + err.Error()) - return - } - - return + if !bytes.Equal(a.IssuedSeal.SignerPublicKey, a.MetaSeal.SignerPublicKey) { + err = errors.New("with and without supply's signer are not equal") + return + } + + fullBytes, err := structSerializer.ToMFBytes(a.AssetsData) + if err != nil { + return + } + + a.Supply = 0 + withoutSupplyBytes, _ := structSerializer.ToMFBytes(a.AssetsData) + + _, err = a.IssuedSeal.Verify(fullBytes, tools.HashCalculator) + if err != nil { + err = errors.New("invalid full assets data signature: " + err.Error()) + return + } + + _, err = a.MetaSeal.Verify(withoutSupplyBytes, tools.HashCalculator) + if err != nil { + err = errors.New("invalid assets without supply data signature: " + err.Error()) + return + } + + return } func (l *Ledger) buildAssetsKey(assets Assets) (key []byte) { - //prefix + without supply hash - key = []byte(StoragePrefixes.Assets.String()) - key = append(key, assets.getUniqueHash()...) - return + //prefix + without supply hash + key = []byte(StoragePrefixes.Assets.String()) + key = append(key, assets.getUniqueHash()...) + return } func (l *Ledger) assetsExists(assets Assets) bool { - key := l.buildAssetsKey(assets) + key := l.buildAssetsKey(assets) - assetsData, _ := l.Storage.Get(key) - exists := assetsData.Exists - return exists + assetsData, _ := l.Storage.Get(key) + exists := assetsData.Exists + return exists } func (l *Ledger) storeAssets(assets Assets) (err error) { - if l.assetsExists(assets) { - err = errors.New("can't issue new assets due to the assets already exists") - return - } + if l.assetsExists(assets) { + err = errors.New("can't issue new assets due to the assets already exists") + return + } - key := l.buildAssetsKey(assets) - assetsBytes, _ := json.Marshal(assets) + key := l.buildAssetsKey(assets) + assetsBytes, _ := json.Marshal(assets) - err = l.Storage.Put(kvDatabase.KVItem{ - Key: key, - Data: assetsBytes, - }) + err = l.Storage.Put(kvDatabase.KVItem{ + Key: key, + Data: assetsBytes, + }) - return + return } func (l *Ledger) updateAssets(assets Assets) (err error) { - if !l.assetsExists(assets) { - err = errors.New("assets not exists") - return - } + if !l.assetsExists(assets) { + err = errors.New("assets not exists") + return + } - key := l.buildAssetsKey(assets) - assetsBytes, _ := json.Marshal(assets) + key := l.buildAssetsKey(assets) + assetsBytes, _ := json.Marshal(assets) - err = l.Storage.Put(kvDatabase.KVItem{ - Key: key, - Data: assetsBytes, - }) + err = l.Storage.Put(kvDatabase.KVItem{ + Key: key, + Data: assetsBytes, + }) - return + return } func (l *Ledger) localAssetsFromHash(hash []byte) (assets Assets, err error) { - assets.MetaSeal.Hash = hash - assets, err = l.getLocalAssets(assets) + assets.MetaSeal.Hash = hash + assets, err = l.getLocalAssets(assets) - return + return } -func (l *Ledger) getLocalAssets(assets Assets) (a Assets, err error){ - assetsKey := l.buildAssetsKey(assets) +func (l *Ledger) getLocalAssets(assets Assets) (a Assets, err error) { + assetsKey := l.buildAssetsKey(assets) - kv, err := l.Storage.Get(assetsKey) - if err != nil { - return - } + kv, err := l.Storage.Get(assetsKey) + if err != nil { + return + } - if !kv.Exists { - err = errors.New("no such assets") - return - } + if !kv.Exists { + err = errors.New("no such assets") + return + } - err = json.Unmarshal(kv.Data, &a) - return + err = json.Unmarshal(kv.Data, &a) + return } diff --git a/service/application/basicAssets/basicAssetsLedger/copyrightStore.go b/service/application/basicAssets/basicAssetsLedger/copyrightStore.go index b6dc29d..e017750 100644 --- a/service/application/basicAssets/basicAssetsLedger/copyrightStore.go +++ b/service/application/basicAssets/basicAssetsLedger/copyrightStore.go @@ -18,10 +18,10 @@ package basicAssetsLedger import ( - "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" "bytes" "encoding/json" "errors" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" ) func (l *Ledger) storeCopyright(assets Assets, owner []byte) error { @@ -33,8 +33,8 @@ func (l *Ledger) storeCopyright(assets Assets, owner []byte) error { key := l.buildCopyrightKey(assets.getUniqueHash()) data, _ := json.Marshal(copyright) return l.Storage.Put(kvDatabase.KVItem{ - Key: key, - Data: data, + Key: key, + Data: data, }) } diff --git a/service/application/basicAssets/basicAssetsLedger/ledger.go b/service/application/basicAssets/basicAssetsLedger/ledger.go index aa1ead4..a35ec3f 100644 --- a/service/application/basicAssets/basicAssetsLedger/ledger.go +++ b/service/application/basicAssets/basicAssetsLedger/ledger.go @@ -18,24 +18,24 @@ package basicAssetsLedger import ( - "github.com/SealSC/SealABC/crypto" - "github.com/SealSC/SealABC/crypto/hashes/sha3" - "github.com/SealSC/SealABC/crypto/signers/ed25519" - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/metadata/blockchainRequest" - "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" - "sync" + "github.com/SealSC/SealABC/crypto" + "github.com/SealSC/SealABC/crypto/hashes/sha3" + "github.com/SealSC/SealABC/crypto/signers/ed25519" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/metadata/blockchainRequest" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" + "sync" ) -var StoragePrefixes struct{ - Assets enum.Element - Copyright enum.Element - Unspent enum.Element - Transactions enum.Element - TransactionWithBlockInfo enum.Element +var StoragePrefixes struct { + Assets enum.Element + Copyright enum.Element + Unspent enum.Element + Transactions enum.Element + TransactionWithBlockInfo enum.Element - Balance enum.Element - SellingList enum.Element + Balance enum.Element + SellingList enum.Element } type txValidator func(tx Transaction) (ret interface{}, err error) @@ -43,69 +43,69 @@ type txActuator func(tx Transaction) (ret interface{}, err error) type ledgerQuery func(param []string) (ret interface{}, err error) type Ledger struct { - operateLock sync.RWMutex - poolLock sync.Mutex - - txPool map[string] blockchainRequest.Entity - memUTXORecord map[string] bool - execUTXORecord map[string] bool - txValidators map[string] txValidator - txActuators map[string] txActuator - ledgerQueries map[string] ledgerQuery - - CryptoTools crypto.Tools - Storage kvDatabase.IDriver + operateLock sync.RWMutex + poolLock sync.Mutex + + txPool map[string]blockchainRequest.Entity + memUTXORecord map[string]bool + execUTXORecord map[string]bool + txValidators map[string]txValidator + txActuators map[string]txActuator + ledgerQueries map[string]ledgerQuery + + CryptoTools crypto.Tools + Storage kvDatabase.IDriver } -func Load() { - enum.SimpleBuild(&TransactionTypes) - enum.SimpleBuild(&StoragePrefixes) - enum.SimpleBuild(&QueryTypes) - enum.SimpleBuild(&AssetsTypes) +func Load() { + enum.SimpleBuild(&TransactionTypes) + enum.SimpleBuild(&StoragePrefixes) + enum.SimpleBuild(&QueryTypes) + enum.SimpleBuild(&AssetsTypes) } func NewLedger(storage kvDatabase.IDriver) (ledger *Ledger) { - ledger = &Ledger{} - - ledger.Storage = storage - - ledger.CryptoTools = crypto.Tools{ - HashCalculator: sha3.Sha256, - SignerGenerator: ed25519.SignerGenerator, - } - - ledger.txPool = map[string] blockchainRequest.Entity{} - ledger.memUTXORecord = map[string] bool{} - ledger.execUTXORecord = map[string] bool{} - - ledger.txValidators = map[string] txValidator { - TransactionTypes.IssueAssets.String(): ledger.verifyIssueAssets, - TransactionTypes.IncreaseSupply.String(): ledger.verifyIncreaseSupply, - TransactionTypes.Transfer.String(): ledger.verifyTransfer, - - TransactionTypes.StartSelling.String(): ledger.verifyStartSelling, - TransactionTypes.StopSelling.String(): ledger.verifyStopSelling, - TransactionTypes.BuyAssets.String(): ledger.verifyBuyAssets, - } - - ledger.txActuators = map[string] txActuator { - TransactionTypes.IssueAssets.String(): ledger.confirmIssueAssets, - TransactionTypes.IncreaseSupply.String(): ledger.confirmIncreaseSupply, - TransactionTypes.Transfer.String(): ledger.confirmTransfer, - - TransactionTypes.StartSelling.String(): ledger.confirmStartSelling, - TransactionTypes.StopSelling.String(): ledger.confirmStopSelling, - TransactionTypes.BuyAssets.String(): ledger.confirmBuyAssets, - } - - ledger.ledgerQueries = map[string] ledgerQuery { - QueryTypes.Assets.String(): ledger.queryAssets, - QueryTypes.AllAssets.String(): ledger.queryAllAssets, - QueryTypes.UnspentList.String(): ledger.queryUnspent, - QueryTypes.Transaction.String(): ledger.queryTransaction, - QueryTypes.SellingList.String(): ledger.querySellingList, - QueryTypes.Copyright.String(): ledger.queryCopyright, - } - - return + ledger = &Ledger{} + + ledger.Storage = storage + + ledger.CryptoTools = crypto.Tools{ + HashCalculator: sha3.Sha256, + SignerGenerator: ed25519.SignerGenerator, + } + + ledger.txPool = map[string]blockchainRequest.Entity{} + ledger.memUTXORecord = map[string]bool{} + ledger.execUTXORecord = map[string]bool{} + + ledger.txValidators = map[string]txValidator{ + TransactionTypes.IssueAssets.String(): ledger.verifyIssueAssets, + TransactionTypes.IncreaseSupply.String(): ledger.verifyIncreaseSupply, + TransactionTypes.Transfer.String(): ledger.verifyTransfer, + + TransactionTypes.StartSelling.String(): ledger.verifyStartSelling, + TransactionTypes.StopSelling.String(): ledger.verifyStopSelling, + TransactionTypes.BuyAssets.String(): ledger.verifyBuyAssets, + } + + ledger.txActuators = map[string]txActuator{ + TransactionTypes.IssueAssets.String(): ledger.confirmIssueAssets, + TransactionTypes.IncreaseSupply.String(): ledger.confirmIncreaseSupply, + TransactionTypes.Transfer.String(): ledger.confirmTransfer, + + TransactionTypes.StartSelling.String(): ledger.confirmStartSelling, + TransactionTypes.StopSelling.String(): ledger.confirmStopSelling, + TransactionTypes.BuyAssets.String(): ledger.confirmBuyAssets, + } + + ledger.ledgerQueries = map[string]ledgerQuery{ + QueryTypes.Assets.String(): ledger.queryAssets, + QueryTypes.AllAssets.String(): ledger.queryAllAssets, + QueryTypes.UnspentList.String(): ledger.queryUnspent, + QueryTypes.Transaction.String(): ledger.queryTransaction, + QueryTypes.SellingList.String(): ledger.querySellingList, + QueryTypes.Copyright.String(): ledger.queryCopyright, + } + + return } diff --git a/service/application/basicAssets/basicAssetsLedger/operationForAssets.go b/service/application/basicAssets/basicAssetsLedger/operationForAssets.go index a5d08e6..deb66b1 100644 --- a/service/application/basicAssets/basicAssetsLedger/operationForAssets.go +++ b/service/application/basicAssets/basicAssetsLedger/operationForAssets.go @@ -18,106 +18,106 @@ package basicAssetsLedger import ( - "github.com/SealSC/SealABC/common" - "bytes" - "errors" - "time" + "bytes" + "errors" + "github.com/SealSC/SealABC/common" + "time" ) func (l *Ledger) verifyIncreaseSupply(tx Transaction) (ret interface{}, err error) { - assets := tx.Assets - err = assets.verify(l.CryptoTools) - if err != nil { - return - } - - localAssets, err := l.getLocalAssets(assets) - if err != nil { - err = errors.New("assets not exist: " + err.Error()) - return - } - - if !l.assetsExists(assets) { - err = errors.New("can't increase assets supply due to no such assets") - return - } - - if !bytes.Equal(localAssets.IssuedSeal.SignerPublicKey, assets.IssuedSeal.SignerPublicKey) { - err = errors.New("invalid owner") - return - } - - if assets.Supply <= localAssets.Supply { - err = errors.New("invalid new supply") - return - } - - return + assets := tx.Assets + err = assets.verify(l.CryptoTools) + if err != nil { + return + } + + localAssets, err := l.getLocalAssets(assets) + if err != nil { + err = errors.New("assets not exist: " + err.Error()) + return + } + + if !l.assetsExists(assets) { + err = errors.New("can't increase assets supply due to no such assets") + return + } + + if !bytes.Equal(localAssets.IssuedSeal.SignerPublicKey, assets.IssuedSeal.SignerPublicKey) { + err = errors.New("invalid owner") + return + } + + if assets.Supply <= localAssets.Supply { + err = errors.New("invalid new supply") + return + } + + return } func (l *Ledger) confirmIncreaseSupply(tx Transaction) (ret interface{}, err error) { - l.operateLock.Lock() - defer l.operateLock.Unlock() + l.operateLock.Lock() + defer l.operateLock.Unlock() - ret, err = l.verifyIncreaseSupply(tx) - if err != nil { - return - } + ret, err = l.verifyIncreaseSupply(tx) + if err != nil { + return + } - assets := tx.Assets - err = l.updateAssets(assets) - return + assets := tx.Assets + err = l.updateAssets(assets) + return } func (l *Ledger) verifyIssueAssets(tx Transaction) (ret interface{}, err error) { - if tx.TxType != TransactionTypes.IssueAssets.String() { - err = errors.New("invalid transaction type") - return - } - - assets := tx.Assets - if l.assetsExists(assets) { - err = errors.New("can't push issue asset transaction, assets already exists") - return - } - - err = assets.verify(l.CryptoTools) - if err != nil { - return - } - - return + if tx.TxType != TransactionTypes.IssueAssets.String() { + err = errors.New("invalid transaction type") + return + } + + assets := tx.Assets + if l.assetsExists(assets) { + err = errors.New("can't push issue asset transaction, assets already exists") + return + } + + err = assets.verify(l.CryptoTools) + if err != nil { + return + } + + return } func (l *Ledger) confirmIssueAssets(tx Transaction) (ret interface{}, err error) { - l.operateLock.Lock() - defer l.operateLock.Unlock() - - if tx.TxType != TransactionTypes.IssueAssets.String() { - err = errors.New("invalid transaction type") - return - } - - assets := tx.Assets - err = assets.verify(l.CryptoTools) - if err != nil { - return - } - - assets.DateTime = time.Now().Format(common.BASIC_TIME_FORMAT) - err = l.storeAssets(assets) - if err != nil { - return - } - - if uint32(AssetsTypes.Copyright.Int()) == assets.Type { - err = l.storeCopyright(assets, tx.Seal.SignerPublicKey) - if err != nil { - return - } - } - - ret, err = l.saveUnspentInsideIssueAssetsTransaction(tx) - - return + l.operateLock.Lock() + defer l.operateLock.Unlock() + + if tx.TxType != TransactionTypes.IssueAssets.String() { + err = errors.New("invalid transaction type") + return + } + + assets := tx.Assets + err = assets.verify(l.CryptoTools) + if err != nil { + return + } + + assets.DateTime = time.Now().Format(common.BASIC_TIME_FORMAT) + err = l.storeAssets(assets) + if err != nil { + return + } + + if uint32(AssetsTypes.Copyright.Int()) == assets.Type { + err = l.storeCopyright(assets, tx.Seal.SignerPublicKey) + if err != nil { + return + } + } + + ret, err = l.saveUnspentInsideIssueAssetsTransaction(tx) + + return } diff --git a/service/application/basicAssets/basicAssetsLedger/operationForQuery.go b/service/application/basicAssets/basicAssetsLedger/operationForQuery.go index cd33daf..b015f62 100644 --- a/service/application/basicAssets/basicAssetsLedger/operationForQuery.go +++ b/service/application/basicAssets/basicAssetsLedger/operationForQuery.go @@ -18,134 +18,134 @@ package basicAssetsLedger import ( - "github.com/SealSC/SealABC/log" - "encoding/base64" - "encoding/json" - "errors" + "encoding/base64" + "encoding/json" + "errors" + "github.com/SealSC/SealABC/log" ) -func (l *Ledger)DoQuery(req QueryRequest) (data interface{}, err error) { - l.operateLock.RLock() - defer l.operateLock.RUnlock() +func (l *Ledger) DoQuery(req QueryRequest) (data interface{}, err error) { + l.operateLock.RLock() + defer l.operateLock.RUnlock() - queryHandle, exists := l.ledgerQueries[req.QueryType] - if !exists { - err = errors.New("no query action named " + req.QueryType) - return - } + queryHandle, exists := l.ledgerQueries[req.QueryType] + if !exists { + err = errors.New("no query action named " + req.QueryType) + return + } - return queryHandle(req.Parameter) + return queryHandle(req.Parameter) } func (l *Ledger) queryAssets(p []string) (result interface{}, err error) { - var hashBytes []byte - err = json.Unmarshal([]byte(p[0]), &hashBytes) - if err != nil { - return - } - - result, err = l.localAssetsFromHash(hashBytes) - return + var hashBytes []byte + err = json.Unmarshal([]byte(p[0]), &hashBytes) + if err != nil { + return + } + + result, err = l.localAssetsFromHash(hashBytes) + return } func (l *Ledger) queryAllAssets(_ []string) (result interface{}, err error) { - prefix := []byte(StoragePrefixes.Assets.String()) - - kvList := l.Storage.Traversal(prefix) - assetsList := AssetsList{} - for _, kv := range kvList { - assets := Assets{} - _ = json.Unmarshal(kv.Data, &assets) - assetsList.List = append(assetsList.List, assets) - } - - result = assetsList - return + prefix := []byte(StoragePrefixes.Assets.String()) + + kvList := l.Storage.Traversal(prefix) + assetsList := AssetsList{} + for _, kv := range kvList { + assets := Assets{} + _ = json.Unmarshal(kv.Data, &assets) + assetsList.List = append(assetsList.List, assets) + } + + result = assetsList + return } func (l *Ledger) queryUnspent(p []string) (result interface{}, err error) { - queryParam := UnspentQueryParameter{} - err = json.Unmarshal([]byte(p[0]), &queryParam) - if err != nil { - log.Log.Error("bad request: ", err.Error()) - return - } - - prefix := l.buildUnspentQueryPrefix(queryParam.Address, queryParam.Assets) - kvList := l.Storage.Traversal(prefix) - - unspentList := UnspentList{} - unspentList.List = map[string] *UnspentUnderAssets{} - - for _, kv := range kvList { - u := Unspent{} - err = json.Unmarshal(kv.Data, &u) - if err != nil { - log.Log.Error("unmarshal u from storage failed: ", err.Error()) - continue - } - - assetsHash := u.AssetsHash - assetsHashString := base64.StdEncoding.EncodeToString(assetsHash) - _, exist := unspentList.List[assetsHashString] - - if !exist { - assets, err := l.localAssetsFromHash(assetsHash) - if err != nil { - log.Log.Error("get local assets ", assetsHashString, " failed: ", err.Error()) - continue - } - unspentList.List[assetsHashString] = &UnspentUnderAssets{ - Assets: assets, - } - } - - unspentList.List[assetsHashString].UnspentList = append(unspentList.List[assetsHashString].UnspentList, u) - } - - result = unspentList - return + queryParam := UnspentQueryParameter{} + err = json.Unmarshal([]byte(p[0]), &queryParam) + if err != nil { + log.Log.Error("bad request: ", err.Error()) + return + } + + prefix := l.buildUnspentQueryPrefix(queryParam.Address, queryParam.Assets) + kvList := l.Storage.Traversal(prefix) + + unspentList := UnspentList{} + unspentList.List = map[string]*UnspentUnderAssets{} + + for _, kv := range kvList { + u := Unspent{} + err = json.Unmarshal(kv.Data, &u) + if err != nil { + log.Log.Error("unmarshal u from storage failed: ", err.Error()) + continue + } + + assetsHash := u.AssetsHash + assetsHashString := base64.StdEncoding.EncodeToString(assetsHash) + _, exist := unspentList.List[assetsHashString] + + if !exist { + assets, err := l.localAssetsFromHash(assetsHash) + if err != nil { + log.Log.Error("get local assets ", assetsHashString, " failed: ", err.Error()) + continue + } + unspentList.List[assetsHashString] = &UnspentUnderAssets{ + Assets: assets, + } + } + + unspentList.List[assetsHashString].UnspentList = append(unspentList.List[assetsHashString].UnspentList, u) + } + + result = unspentList + return } func (l *Ledger) queryTransaction(p []string) (result interface{}, err error) { - var hashBytes []byte - err = json.Unmarshal([]byte(p[0]), &hashBytes) - if err != nil { - return - } - - result, err = l.getLocalTransaction(hashBytes) - return + var hashBytes []byte + err = json.Unmarshal([]byte(p[0]), &hashBytes) + if err != nil { + return + } + + result, err = l.getLocalTransaction(hashBytes) + return } func (l *Ledger) querySellingList(_ []string) (result interface{}, err error) { - list := l.Storage.Traversal([]byte(StoragePrefixes.SellingList.String())) - - var sellingList []SellingData - - for _, data := range list { - sellingData := SellingData{} - jsonErr := json.Unmarshal(data.Data, &sellingData) - if jsonErr != nil { - continue - } - sellingList = append(sellingList, sellingData) - } - return sellingList, nil + list := l.Storage.Traversal([]byte(StoragePrefixes.SellingList.String())) + + var sellingList []SellingData + + for _, data := range list { + sellingData := SellingData{} + jsonErr := json.Unmarshal(data.Data, &sellingData) + if jsonErr != nil { + continue + } + sellingList = append(sellingList, sellingData) + } + return sellingList, nil } func (l *Ledger) queryCopyright(_ []string) (result interface{}, err error) { - list := l.Storage.Traversal([]byte(StoragePrefixes.Copyright.String())) - - var copyrightList []Copyright - - for _, data := range list { - cr := Copyright{} - jsonErr := json.Unmarshal(data.Data, &cr) - if jsonErr != nil { - continue - } - copyrightList = append(copyrightList, cr) - } - return copyrightList, nil + list := l.Storage.Traversal([]byte(StoragePrefixes.Copyright.String())) + + var copyrightList []Copyright + + for _, data := range list { + cr := Copyright{} + jsonErr := json.Unmarshal(data.Data, &cr) + if jsonErr != nil { + continue + } + copyrightList = append(copyrightList, cr) + } + return copyrightList, nil } diff --git a/service/application/basicAssets/basicAssetsLedger/operationForSelling.go b/service/application/basicAssets/basicAssetsLedger/operationForSelling.go index 28bfb11..20d56cd 100644 --- a/service/application/basicAssets/basicAssetsLedger/operationForSelling.go +++ b/service/application/basicAssets/basicAssetsLedger/operationForSelling.go @@ -30,7 +30,7 @@ type SellingOperationResult struct { SellingData } -func (l *Ledger) sellingDataVerify(tx Transaction) (data SellingData, err error) { +func (l *Ledger) sellingDataVerify(tx Transaction) (data SellingData, err error) { err = json.Unmarshal(tx.ExtraData, &data) if err != nil { return @@ -54,7 +54,7 @@ func (l *Ledger) verifyStartSelling(tx Transaction) (ret interface{}, err error) } sellingData, err := l.sellingDataVerify(tx) - if err != nil { + if err != nil { return } @@ -85,7 +85,7 @@ func (l *Ledger) verifyStopSelling(tx Transaction) (ret interface{}, err error) return nil, errors.New("invalid input or output count") } sellingData, err := l.sellingDataVerify(tx) - if err != nil { + if err != nil { return } @@ -109,7 +109,7 @@ func (l *Ledger) verifyBuyAssets(tx Transaction) (ret interface{}, err error) { return nil, errors.New("invalid input or output count") } - target := tx.Input[inCount - 1] + target := tx.Input[inCount-1] sellingKey := l.buildAssetsSellingKey(target.Transaction) data, err := l.Storage.Get(sellingKey) if err != nil { @@ -126,7 +126,7 @@ func (l *Ledger) verifyBuyAssets(tx Transaction) (ret interface{}, err error) { inAmount := uint64(0) var uList []Unspent - for i:=0; i < inCount - 1; i++ { + for i := 0; i < inCount-1; i++ { key := l.buildUnspentStorageKey(tx.Seal.SignerPublicKey, tx.Assets.getUniqueHash(), tx.Input[i].Transaction, tx.Input[i].OutputIndex) unspent, dbErr := l.getUnspent(key) if dbErr != nil { @@ -189,9 +189,7 @@ func (l *Ledger) confirmStartSelling(tx Transaction) (ret interface{}, err error return } - - - ret = SellingOperationResult { + ret = SellingOperationResult{ UnspentListWithBalance: ul, SellingData: sellingData, } @@ -232,7 +230,7 @@ func (l *Ledger) confirmStopSelling(tx Transaction) (ret interface{}, err error) _ = l.deleteSellingData(sellingData.Transaction) - ret = SellingOperationResult { + ret = SellingOperationResult{ UnspentListWithBalance: ul, SellingData: sellingData, } @@ -244,7 +242,7 @@ func (l *Ledger) confirmBuyAssets(tx Transaction) (ret interface{}, err error) { defer l.operateLock.Unlock() inCount := len(tx.Input) - target := tx.Input[inCount - 1] + target := tx.Input[inCount-1] sellingKey := l.buildAssetsSellingKey(target.Transaction) data, err := l.Storage.Get(sellingKey) @@ -257,7 +255,7 @@ func (l *Ledger) confirmBuyAssets(tx Transaction) (ret interface{}, err error) { var uList []Unspent - for i:=0; i < inCount - 1; i++ { + for i := 0; i < inCount-1; i++ { key := l.buildUnspentStorageKey(tx.Seal.SignerPublicKey, tx.Assets.getUniqueHash(), tx.Input[i].Transaction, tx.Input[i].OutputIndex) unspent, dbErr := l.getUnspent(key) if dbErr != nil { @@ -284,7 +282,7 @@ func (l *Ledger) confirmBuyAssets(tx Transaction) (ret interface{}, err error) { sellAssets, _ := l.localAssetsFromHash(sellingData.SellingAssets) tx.Input = []UTXOInput{} - tx.Output =[]UTXOOutput{{ + tx.Output = []UTXOOutput{{ To: tx.Seal.SignerPublicKey, Value: sellingData.Amount, }} diff --git a/service/application/basicAssets/basicAssetsLedger/operationForTransaction.go b/service/application/basicAssets/basicAssetsLedger/operationForTransaction.go index a118aad..a1ea18f 100644 --- a/service/application/basicAssets/basicAssetsLedger/operationForTransaction.go +++ b/service/application/basicAssets/basicAssetsLedger/operationForTransaction.go @@ -18,188 +18,188 @@ package basicAssetsLedger import ( - "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/metadata/blockchainRequest" - "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" - "encoding/json" - "errors" - "time" + "encoding/json" + "errors" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/metadata/blockchainRequest" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" + "time" ) -func (l *Ledger) buildTransactionKey(txHash []byte) (key [] byte) { - //prefix + sender + transaction hash - key = []byte(StoragePrefixes.Transactions.String()) - key = append(key, txHash...) - return +func (l *Ledger) buildTransactionKey(txHash []byte) (key []byte) { + //prefix + sender + transaction hash + key = []byte(StoragePrefixes.Transactions.String()) + key = append(key, txHash...) + return } func (l *Ledger) verifyTransaction(tx Transaction) (err error) { - validator, exists := l.txValidators[tx.TxType] - if !exists { - err = errors.New("no validator for this transaction: " + tx.TxType) - return - } - - _, err = validator(tx) - if err != nil { - log.Log.Error("invalid transaction: ", err.Error(), "\r\n", tx) - return - } - - return + validator, exists := l.txValidators[tx.TxType] + if !exists { + err = errors.New("no validator for this transaction: " + tx.TxType) + return + } + + _, err = validator(tx) + if err != nil { + log.Log.Error("invalid transaction: ", err.Error(), "\r\n", tx) + return + } + + return } func (l *Ledger) getLocalTransaction(txHash []byte) (tx TransactionWithBlockInfo, err error) { - key := l.buildTransactionKey(txHash) + key := l.buildTransactionKey(txHash) - kv, err := l.Storage.Get(key) - if err != nil { - return - } + kv, err := l.Storage.Get(key) + if err != nil { + return + } - if !kv.Exists { - err = errors.New("no such transaction") - return - } + if !kv.Exists { + err = errors.New("no such transaction") + return + } - err = json.Unmarshal(kv.Data, &tx) - return + err = json.Unmarshal(kv.Data, &tx) + return } func (l *Ledger) PushTransaction(req blockchainRequest.Entity) (err error) { - l.operateLock.Lock() - defer l.operateLock.Unlock() - - tx := Transaction{} - err = json.Unmarshal(req.Data, &tx) - if err != nil { - return - } - - err = l.verifyTransaction(tx) - if err != nil { - return - } - - if tx.TxType == TransactionTypes.Transfer.String() { - usList, _, _ := l.getUnspentListFromTransaction(tx) - - err = l.doubleSpentCheck(usList, l.memUTXORecord) - if err != nil { - return err - } - } - - l.poolLock.Lock() - defer l.poolLock.Unlock() - - tx.CreateTime = time.Now().Unix() - l.txPool[tx.HashString()] = req - return + l.operateLock.Lock() + defer l.operateLock.Unlock() + + tx := Transaction{} + err = json.Unmarshal(req.Data, &tx) + if err != nil { + return + } + + err = l.verifyTransaction(tx) + if err != nil { + return + } + + if tx.TxType == TransactionTypes.Transfer.String() { + usList, _, _ := l.getUnspentListFromTransaction(tx) + + err = l.doubleSpentCheck(usList, l.memUTXORecord) + if err != nil { + return err + } + } + + l.poolLock.Lock() + defer l.poolLock.Unlock() + + tx.CreateTime = time.Now().Unix() + l.txPool[tx.HashString()] = req + return } func (l *Ledger) GetTransactionsFromPool() (txList []blockchainRequest.Entity, count uint32) { - l.poolLock.Lock() - defer l.poolLock.Unlock() + l.poolLock.Lock() + defer l.poolLock.Unlock() - count = 0 - for _, tx := range l.txPool { - count += 1 - txList = append(txList, tx) - } + count = 0 + for _, tx := range l.txPool { + count += 1 + txList = append(txList, tx) + } - return + return } func (l *Ledger) RemoveTransactionFromPool(txKey string) { - l.poolLock.Lock() - defer l.poolLock.Unlock() - delete(l.txPool, txKey) + l.poolLock.Lock() + defer l.poolLock.Unlock() + delete(l.txPool, txKey) - return + return } //wrap verify transaction method to solve interlock func (l *Ledger) VerifyTransaction(tx Transaction) (err error) { - l.operateLock.Lock() - defer l.operateLock.Unlock() - - err = l.verifyTransaction(tx) - if err != nil { - return - } - - if tx.TxType == TransactionTypes.Transfer.String() { - usList, _, _ := l.getUnspentListFromTransaction(tx) - err = l.doubleSpentCheck(usList, l.execUTXORecord) - if err != nil{ - return err - } - } - - return + l.operateLock.Lock() + defer l.operateLock.Unlock() + + err = l.verifyTransaction(tx) + if err != nil { + return + } + + if tx.TxType == TransactionTypes.Transfer.String() { + usList, _, _ := l.getUnspentListFromTransaction(tx) + err = l.doubleSpentCheck(usList, l.execUTXORecord) + if err != nil { + return err + } + } + + return } func (l *Ledger) ExecuteTransaction(tx Transaction) (ret interface{}, err error) { - handle, exists := l.txActuators[tx.TxType] - if !exists { - err = errors.New("no actuator for this transaction: " + tx.TxType) - return - } - - ret, err = handle(tx) - if err != nil { - log.Log.Error("execute transaction failed: ", tx) - return - } - - return + handle, exists := l.txActuators[tx.TxType] + if !exists { + err = errors.New("no actuator for this transaction: " + tx.TxType) + return + } + + ret, err = handle(tx) + if err != nil { + log.Log.Error("execute transaction failed: ", tx) + return + } + + return } func (l *Ledger) GetOriginalTransactionWithBlockInfo(hash []byte) (tx TransactionWithBlockInfo, err error) { - l.operateLock.Lock() - defer l.operateLock.Unlock() + l.operateLock.Lock() + defer l.operateLock.Unlock() - key := l.buildTransactionKey(hash) - kv, err := l.Storage.Get(key) + key := l.buildTransactionKey(hash) + kv, err := l.Storage.Get(key) - if err != nil { - return - } + if err != nil { + return + } - if !kv.Exists { - err = errors.New("no such transaction") - return - } + if !kv.Exists { + err = errors.New("no such transaction") + return + } - err = json.Unmarshal(kv.Data, &tx) - return + err = json.Unmarshal(kv.Data, &tx) + return } func (l *Ledger) SaveTransactionWithBlockInfo(tx Transaction, reqHash []byte, blockHeight uint64, actIndex uint32) (err error) { - l.operateLock.Lock() - defer l.operateLock.Unlock() + l.operateLock.Lock() + defer l.operateLock.Unlock() - key := l.buildTransactionKey(tx.Seal.Hash) + key := l.buildTransactionKey(tx.Seal.Hash) - txWithBlkInfo := TransactionWithBlockInfo { - Transaction:tx, - } + txWithBlkInfo := TransactionWithBlockInfo{ + Transaction: tx, + } - txWithBlkInfo.BlockInfo.RequestHash = reqHash - txWithBlkInfo.BlockInfo.BlockHeight = blockHeight - txWithBlkInfo.BlockInfo.ActionIndex = actIndex + txWithBlkInfo.BlockInfo.RequestHash = reqHash + txWithBlkInfo.BlockInfo.BlockHeight = blockHeight + txWithBlkInfo.BlockInfo.ActionIndex = actIndex - txBytes, err := json.Marshal(txWithBlkInfo) + txBytes, err := json.Marshal(txWithBlkInfo) - if err != nil { - return - } + if err != nil { + return + } - err = l.Storage.Put(kvDatabase.KVItem{ - Key:key, - Data: txBytes, - }) + err = l.Storage.Put(kvDatabase.KVItem{ + Key: key, + Data: txBytes, + }) - return + return } diff --git a/service/application/basicAssets/basicAssetsLedger/operationForTransfer.go b/service/application/basicAssets/basicAssetsLedger/operationForTransfer.go index e70c107..20e2634 100644 --- a/service/application/basicAssets/basicAssetsLedger/operationForTransfer.go +++ b/service/application/basicAssets/basicAssetsLedger/operationForTransfer.go @@ -18,72 +18,71 @@ package basicAssetsLedger import ( - "errors" - "fmt" + "errors" + "fmt" ) func (l *Ledger) verifyTransfer(tx Transaction) (ret interface{}, err error) { - unspentList, totalIn, err := l.getUnspentListFromTransaction(tx) + unspentList, totalIn, err := l.getUnspentListFromTransaction(tx) - if err != nil { - return - } + if err != nil { + return + } - //verify transfer input is equal to output - var totalOut uint64 = 0 - for _, output := range tx.Output { - totalOut += output.Value - } + //verify transfer input is equal to output + var totalOut uint64 = 0 + for _, output := range tx.Output { + totalOut += output.Value + } - if totalIn != totalOut { - err = errors.New("input not equal output") - return - } + if totalIn != totalOut { + err = errors.New("input not equal output") + return + } - ret = unspentList - return + ret = unspentList + return } -func (l *Ledger) doubleSpentCheck(usList []Unspent, cachePool map[string] bool) (err error) { - for _, utxo := range usList { - key := string(utxo.Transaction) + fmt.Sprintf("%d", utxo.OutputIndex) - if cachePool[key] { - err = errors.New("double spent") - break - } else { - cachePool[key] = true - } - } - - return +func (l *Ledger) doubleSpentCheck(usList []Unspent, cachePool map[string]bool) (err error) { + for _, utxo := range usList { + key := string(utxo.Transaction) + fmt.Sprintf("%d", utxo.OutputIndex) + if cachePool[key] { + err = errors.New("double spent") + break + } else { + cachePool[key] = true + } + } + + return } -func (l *Ledger)updateDoubleSpentCache(usList []Unspent) { - for _, utxo := range usList { - key := string(utxo.Transaction) + fmt.Sprintf("%d", utxo.OutputIndex) - delete(l.memUTXORecord, key) - delete(l.execUTXORecord, key) - } +func (l *Ledger) updateDoubleSpentCache(usList []Unspent) { + for _, utxo := range usList { + key := string(utxo.Transaction) + fmt.Sprintf("%d", utxo.OutputIndex) + delete(l.memUTXORecord, key) + delete(l.execUTXORecord, key) + } } func (l *Ledger) confirmTransfer(tx Transaction) (ret interface{}, err error) { - l.operateLock.Lock() - defer l.operateLock.Unlock() + l.operateLock.Lock() + defer l.operateLock.Unlock() - //tx in this phase was verified, get unspent list directly - usList, _, err := l.getUnspentListFromTransaction(tx) - if err != nil { - return - } + //tx in this phase was verified, get unspent list directly + usList, _, err := l.getUnspentListFromTransaction(tx) + if err != nil { + return + } - localAssets, _ := l.localAssetsFromHash(tx.Assets.getUniqueHash()) + localAssets, _ := l.localAssetsFromHash(tx.Assets.getUniqueHash()) - //save transaction - ret, err = l.saveUnspent(localAssets, tx, usList) + //save transaction + ret, err = l.saveUnspent(localAssets, tx, usList) - if err == nil { - l.updateDoubleSpentCache(usList) - } - return + if err == nil { + l.updateDoubleSpentCache(usList) + } + return } - diff --git a/service/application/basicAssets/basicAssetsLedger/query.go b/service/application/basicAssets/basicAssetsLedger/query.go index f52c633..f43a66f 100644 --- a/service/application/basicAssets/basicAssetsLedger/query.go +++ b/service/application/basicAssets/basicAssetsLedger/query.go @@ -20,34 +20,34 @@ package basicAssetsLedger import "github.com/SealSC/SealABC/dataStructure/enum" var QueryTypes struct { - Assets enum.Element - AllAssets enum.Element - UnspentList enum.Element - Transaction enum.Element - SellingList enum.Element - Copyright enum.Element + Assets enum.Element + AllAssets enum.Element + UnspentList enum.Element + Transaction enum.Element + SellingList enum.Element + Copyright enum.Element } type AssetsList struct { - List []Assets + List []Assets } type UnspentUnderAssets struct { - Assets Assets - UnspentList []Unspent + Assets Assets + UnspentList []Unspent } type UnspentList struct { - List map[string] *UnspentUnderAssets + List map[string]*UnspentUnderAssets } type UnspentQueryParameter struct { - Address []byte - Assets []byte + Address []byte + Assets []byte } type QueryRequest struct { - DBType string - QueryType string - Parameter []string + DBType string + QueryType string + Parameter []string } diff --git a/service/application/basicAssets/basicAssetsLedger/transaction.go b/service/application/basicAssets/basicAssetsLedger/transaction.go index dd23fcd..772d07c 100644 --- a/service/application/basicAssets/basicAssetsLedger/transaction.go +++ b/service/application/basicAssets/basicAssetsLedger/transaction.go @@ -18,69 +18,69 @@ package basicAssetsLedger import ( - "github.com/SealSC/SealABC/metadata/seal" - "encoding/hex" - "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" - "github.com/SealSC/SealABC/crypto" - "github.com/SealSC/SealABC/dataStructure/enum" + "encoding/hex" + "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" + "github.com/SealSC/SealABC/crypto" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/metadata/seal" ) -var TransactionTypes struct{ - IssueAssets enum.Element - Transfer enum.Element - IncreaseSupply enum.Element +var TransactionTypes struct { + IssueAssets enum.Element + Transfer enum.Element + IncreaseSupply enum.Element - StartSelling enum.Element - StopSelling enum.Element - BuyAssets enum.Element + StartSelling enum.Element + StopSelling enum.Element + BuyAssets enum.Element } type SellingData struct { - Price uint64 `json:",string"` - Amount uint64 `json:",string"` - Seller []byte - SellingAssets []byte - PaymentAssets []byte - Transaction []byte + Price uint64 `json:",string"` + Amount uint64 `json:",string"` + Seller []byte + SellingAssets []byte + PaymentAssets []byte + Transaction []byte } type TransactionData struct { - TxType string - Assets Assets - Memo string + TxType string + Assets Assets + Memo string - Input []UTXOInput - Output []UTXOOutput + Input []UTXOInput + Output []UTXOOutput - ExtraData []byte + ExtraData []byte } type Transaction struct { - TransactionData + TransactionData - CreateTime int64 - Seal seal.Entity + CreateTime int64 + Seal seal.Entity } type TransactionWithBlockInfo struct { - Transaction - BlockInfo struct{ - RequestHash []byte - BlockHeight uint64 - ActionIndex uint32 - } + Transaction + BlockInfo struct { + RequestHash []byte + BlockHeight uint64 + ActionIndex uint32 + } } func (t *Transaction) HashString() string { - return hex.EncodeToString(t.Seal.Hash) + return hex.EncodeToString(t.Seal.Hash) } func (t *Transaction) Verify(tools crypto.Tools) (err error) { - txBytes, err := structSerializer.ToMFBytes(t.TransactionData) - if err != nil { - return - } + txBytes, err := structSerializer.ToMFBytes(t.TransactionData) + if err != nil { + return + } - _, err = t.Seal.Verify(txBytes, tools.HashCalculator) - return + _, err = t.Seal.Verify(txBytes, tools.HashCalculator) + return } diff --git a/service/application/basicAssets/basicAssetsLedger/utxo.go b/service/application/basicAssets/basicAssetsLedger/utxo.go index 604a3e9..9018bb1 100644 --- a/service/application/basicAssets/basicAssetsLedger/utxo.go +++ b/service/application/basicAssets/basicAssetsLedger/utxo.go @@ -18,341 +18,342 @@ package basicAssetsLedger import ( - "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" - "encoding/binary" - "encoding/json" - "errors" + "encoding/binary" + "encoding/json" + "errors" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" ) type UTXOInput struct { - Transaction []byte - OutputIndex uint64 `json:",string"` + Transaction []byte + OutputIndex uint64 `json:",string"` } type UTXOOutput struct { - To []byte - Value uint64 `json:",string"` + To []byte + Value uint64 `json:",string"` } type Unspent struct { - Owner []byte - AssetsHash []byte - Transaction []byte - Singer []byte - OutputIndex uint64 `json:",string"` - Value uint64 `json:",string"` + Owner []byte + AssetsHash []byte + Transaction []byte + Singer []byte + OutputIndex uint64 `json:",string"` + Value uint64 `json:",string"` } type Balance struct { - Address []byte - Assets Assets - Amount uint64 + Address []byte + Assets Assets + Amount uint64 } type UnspentListWithBalance struct { - UnspentList []Unspent - BalanceList []Balance + UnspentList []Unspent + BalanceList []Balance } -func (l *Ledger) buildUnspentStorageKey(addr []byte, assets []byte, txHash []byte, outputIdx uint64) (key []byte){ - //prefix + addr + assets hash + transaction hash + output index - key = []byte(StoragePrefixes.Unspent.String()) - key = append(key, addr...) - key = append(key, assets...) - key = append(key, txHash...) - outputIdxBytes := make([]byte, 8, 8) - binary.BigEndian.PutUint64(outputIdxBytes, outputIdx) - - key = append(key, outputIdxBytes...) - return +func (l *Ledger) buildUnspentStorageKey(addr []byte, assets []byte, txHash []byte, outputIdx uint64) (key []byte) { + //prefix + addr + assets hash + transaction hash + output index + key = []byte(StoragePrefixes.Unspent.String()) + key = append(key, addr...) + key = append(key, assets...) + key = append(key, txHash...) + outputIdxBytes := make([]byte, 8, 8) + binary.BigEndian.PutUint64(outputIdxBytes, outputIdx) + + key = append(key, outputIdxBytes...) + return } func (l *Ledger) buildBalanceKey(address []byte, assets Assets) (addressBalanceKey []byte, assetsBalanceKey []byte) { - baseKey := []byte(StoragePrefixes.Balance.String()) + baseKey := []byte(StoragePrefixes.Balance.String()) - assetsHash := assets.getUniqueHash() - addressBalanceKey = append(address, assetsHash...) - addressBalanceKey = append(baseKey, addressBalanceKey...) + assetsHash := assets.getUniqueHash() + addressBalanceKey = append(address, assetsHash...) + addressBalanceKey = append(baseKey, addressBalanceKey...) - assetsBalanceKey = append(assetsHash, address...) - assetsBalanceKey = append(baseKey, assetsBalanceKey...) + assetsBalanceKey = append(assetsHash, address...) + assetsBalanceKey = append(baseKey, assetsBalanceKey...) - return + return } -func (l *Ledger) buildUnspentQueryPrefix(addr []byte, assets []byte) (prefix []byte){ - prefix = []byte(StoragePrefixes.Unspent.String()) - prefix = append(prefix, addr...) - prefix = append(prefix, assets...) - return +func (l *Ledger) buildUnspentQueryPrefix(addr []byte, assets []byte) (prefix []byte) { + prefix = []byte(StoragePrefixes.Unspent.String()) + prefix = append(prefix, addr...) + prefix = append(prefix, assets...) + return } func (l *Ledger) buildAssetsSellingKey(txHash []byte) []byte { - baseKey := []byte(StoragePrefixes.SellingList.String()) + baseKey := []byte(StoragePrefixes.SellingList.String()) - return append(baseKey, txHash...) + return append(baseKey, txHash...) } -func (l *Ledger) buildCopyrightQueryPrefix(addr []byte) (prefix []byte){ - prefix = []byte(StoragePrefixes.Unspent.String()) - prefix = append(prefix, addr...) - return +func (l *Ledger) buildCopyrightQueryPrefix(addr []byte) (prefix []byte) { + prefix = []byte(StoragePrefixes.Unspent.String()) + prefix = append(prefix, addr...) + return } func (l *Ledger) buildCopyrightKey(assetsHash []byte) []byte { - baseKey := []byte(StoragePrefixes.Copyright.String()) - return append(baseKey, assetsHash...) + baseKey := []byte(StoragePrefixes.Copyright.String()) + return append(baseKey, assetsHash...) } func (l *Ledger) getUnspent(key []byte) (unspent Unspent, err error) { - kv, err := l.Storage.Get(key) - if err != nil { - return - } - - if !kv.Exists { - err = errors.New("no such unspent") - return - } - - err = json.Unmarshal(kv.Data, &unspent) - return + kv, err := l.Storage.Get(key) + if err != nil { + return + } + + if !kv.Exists { + err = errors.New("no such unspent") + return + } + + err = json.Unmarshal(kv.Data, &unspent) + return } func (l *Ledger) getUnspentListFromTransaction(tx Transaction) (list []Unspent, amount uint64, err error) { - amount = 0 - for _, ref := range tx.Input { - key := l.buildUnspentStorageKey(tx.Seal.SignerPublicKey, tx.Assets.getUniqueHash(), ref.Transaction, ref.OutputIndex) - unspent, dbErr := l.getUnspent(key) - if dbErr != nil { - err = errors.New("get Unspent failed: " + dbErr.Error()) - break - } - - amount += unspent.Value - list = append(list, unspent) - } - - return + amount = 0 + for _, ref := range tx.Input { + key := l.buildUnspentStorageKey(tx.Seal.SignerPublicKey, tx.Assets.getUniqueHash(), ref.Transaction, ref.OutputIndex) + unspent, dbErr := l.getUnspent(key) + if dbErr != nil { + err = errors.New("get Unspent failed: " + dbErr.Error()) + break + } + + amount += unspent.Value + list = append(list, unspent) + } + + return } func (l *Ledger) deleteUnspent(in []Unspent) (err error) { - var keyForDel [][]byte - for _, ref := range in { - key := l.buildUnspentStorageKey(ref.Owner, ref.AssetsHash, ref.Transaction, ref.OutputIndex) - keyForDel = append(keyForDel, key) - } - - err = l.Storage.BatchDelete(keyForDel) - return + var keyForDel [][]byte + for _, ref := range in { + key := l.buildUnspentStorageKey(ref.Owner, ref.AssetsHash, ref.Transaction, ref.OutputIndex) + keyForDel = append(keyForDel, key) + } + + err = l.Storage.BatchDelete(keyForDel) + return } func (l *Ledger) storeBalance(key []byte, change uint64, isIncrease bool) (amount uint64, err error) { - bKV, err :=l.Storage.Get(key) - if err != nil || !bKV.Exists { - if !isIncrease { - err = errors.New("invalid address") - return - } - amount = change - } else { - current := binary.BigEndian.Uint64(bKV.Data) - if isIncrease { - amount = current + change - } else { - if current < change { - err = errors.New("reduce must <= current") - return - } - - amount = current - change - } - } - - varBytes := make([]byte, 8) - binary.BigEndian.PutUint64(varBytes, amount) - kv := kvDatabase.KVItem{ - Key: key, - Data: varBytes, - } - - err = l.Storage.Put(kv) - - return + bKV, err := l.Storage.Get(key) + if err != nil || !bKV.Exists { + if !isIncrease { + err = errors.New("invalid address") + return + } + amount = change + } else { + current := binary.BigEndian.Uint64(bKV.Data) + if isIncrease { + amount = current + change + } else { + if current < change { + err = errors.New("reduce must <= current") + return + } + + amount = current - change + } + } + + varBytes := make([]byte, 8) + binary.BigEndian.PutUint64(varBytes, amount) + kv := kvDatabase.KVItem{ + Key: key, + Data: varBytes, + } + + err = l.Storage.Put(kv) + + return } func (l *Ledger) updateBalance(address []byte, assets Assets, change uint64, isIncrease bool) (amount uint64, err error) { - addressKey, assetsKey := l.buildBalanceKey(address, assets) - amount, err = l.storeBalance(addressKey, change, isIncrease) - if err != nil { - return - } + addressKey, assetsKey := l.buildBalanceKey(address, assets) + amount, err = l.storeBalance(addressKey, change, isIncrease) + if err != nil { + return + } - _, err = l.storeBalance(assetsKey, change, isIncrease) - if err != nil { - return - } + _, err = l.storeBalance(assetsKey, change, isIncrease) + if err != nil { + return + } - return + return } type balanceDataInTx struct { - address []byte - assets Assets - val uint64 - isIncrease bool + address []byte + assets Assets + val uint64 + isIncrease bool } + func (l *Ledger) saveUnspent(localAssets Assets, tx Transaction, in []Unspent) (list UnspentListWithBalance, err error) { - var unspentList []kvDatabase.KVItem - - balanceIncreaseList := map[string] *balanceDataInTx{} - assetsHash := localAssets.getUniqueHash() - - for idx, output := range tx.Output { - key := l.buildUnspentStorageKey(output.To, assetsHash, tx.Seal.Hash, uint64(idx)) - - u := Unspent{ - Owner: output.To, - AssetsHash: assetsHash, - Transaction: tx.Seal.Hash, - OutputIndex: uint64(idx), - Singer: tx.Seal.SignerPublicKey, - Value: output.Value, - } - data, _ := json.Marshal(u) - - unspentList = append(unspentList, kvDatabase.KVItem{ - Key: key, - Data: data, - }) - - bKey := string(output.To) + string(assetsHash) - if _, exist := balanceIncreaseList[bKey]; exist { - balanceIncreaseList[bKey].val += output.Value - } else { - balanceIncreaseList[bKey] = &balanceDataInTx{ - address: output.To, - assets: localAssets, - val: output.Value, - isIncrease: true, - } - } - } - - err = l.Storage.BatchPut(unspentList) - if err != nil { - return - } - - err = l.deleteUnspent(in) - if err != nil { - return - } - - balanceReduceList := map[string] *balanceDataInTx{} - for _, i := range in { - bKey := string(i.Owner) + string(i.AssetsHash) - if _, exist := balanceReduceList[bKey]; exist { - balanceReduceList[bKey].val += i.Value - } else { - balanceReduceList[bKey] = &balanceDataInTx{ - address: i.Owner, - assets: localAssets, - val: i.Value, - isIncrease: false, - } - } - } - - var balanceList []Balance - for _, b := range balanceIncreaseList { - amount, err := l.updateBalance(b.address, b.assets, b.val, true) - if err != nil { - continue - } - balanceList = append(balanceList, Balance { - Address: b.address, - Assets: localAssets, - Amount: amount, - }) - } - - for _, b := range balanceReduceList { - amount, err := l.updateBalance(b.address, b.assets, b.val, false) - if err != nil { - continue - } - balanceList = append(balanceList, Balance{ - Address: b.address, - Assets: localAssets, - Amount: amount, - }) - } - - list.UnspentList = in - list.BalanceList = balanceList - return + var unspentList []kvDatabase.KVItem + + balanceIncreaseList := map[string]*balanceDataInTx{} + assetsHash := localAssets.getUniqueHash() + + for idx, output := range tx.Output { + key := l.buildUnspentStorageKey(output.To, assetsHash, tx.Seal.Hash, uint64(idx)) + + u := Unspent{ + Owner: output.To, + AssetsHash: assetsHash, + Transaction: tx.Seal.Hash, + OutputIndex: uint64(idx), + Singer: tx.Seal.SignerPublicKey, + Value: output.Value, + } + data, _ := json.Marshal(u) + + unspentList = append(unspentList, kvDatabase.KVItem{ + Key: key, + Data: data, + }) + + bKey := string(output.To) + string(assetsHash) + if _, exist := balanceIncreaseList[bKey]; exist { + balanceIncreaseList[bKey].val += output.Value + } else { + balanceIncreaseList[bKey] = &balanceDataInTx{ + address: output.To, + assets: localAssets, + val: output.Value, + isIncrease: true, + } + } + } + + err = l.Storage.BatchPut(unspentList) + if err != nil { + return + } + + err = l.deleteUnspent(in) + if err != nil { + return + } + + balanceReduceList := map[string]*balanceDataInTx{} + for _, i := range in { + bKey := string(i.Owner) + string(i.AssetsHash) + if _, exist := balanceReduceList[bKey]; exist { + balanceReduceList[bKey].val += i.Value + } else { + balanceReduceList[bKey] = &balanceDataInTx{ + address: i.Owner, + assets: localAssets, + val: i.Value, + isIncrease: false, + } + } + } + + var balanceList []Balance + for _, b := range balanceIncreaseList { + amount, err := l.updateBalance(b.address, b.assets, b.val, true) + if err != nil { + continue + } + balanceList = append(balanceList, Balance{ + Address: b.address, + Assets: localAssets, + Amount: amount, + }) + } + + for _, b := range balanceReduceList { + amount, err := l.updateBalance(b.address, b.assets, b.val, false) + if err != nil { + continue + } + balanceList = append(balanceList, Balance{ + Address: b.address, + Assets: localAssets, + Amount: amount, + }) + } + + list.UnspentList = in + list.BalanceList = balanceList + return } func (l *Ledger) saveUnspentInsideIssueAssetsTransaction(tx Transaction) (balance Balance, err error) { - u := Unspent{ - Owner: tx.Assets.IssuedSeal.SignerPublicKey, - AssetsHash: tx.Assets.getUniqueHash(), - Transaction: tx.Seal.Hash, - OutputIndex: uint64(0), - Value: tx.Assets.Supply, - } - - key := l.buildUnspentStorageKey(tx.Assets.IssuedSeal.SignerPublicKey, tx.Assets.getUniqueHash(), tx.Seal.Hash, uint64(0)) - - data, _ := json.Marshal(u) - err = l.Storage.Put(kvDatabase.KVItem{ - Key: key, - Data: data, - }) - - if err != nil { - return - } - - amount, err := l.updateBalance(u.Owner, tx.Assets, u.Value, true) - - balance = Balance{ - Address: u.Owner, - Assets: tx.Assets, - Amount: amount, - } - return + u := Unspent{ + Owner: tx.Assets.IssuedSeal.SignerPublicKey, + AssetsHash: tx.Assets.getUniqueHash(), + Transaction: tx.Seal.Hash, + OutputIndex: uint64(0), + Value: tx.Assets.Supply, + } + + key := l.buildUnspentStorageKey(tx.Assets.IssuedSeal.SignerPublicKey, tx.Assets.getUniqueHash(), tx.Seal.Hash, uint64(0)) + + data, _ := json.Marshal(u) + err = l.Storage.Put(kvDatabase.KVItem{ + Key: key, + Data: data, + }) + + if err != nil { + return + } + + amount, err := l.updateBalance(u.Owner, tx.Assets, u.Value, true) + + balance = Balance{ + Address: u.Owner, + Assets: tx.Assets, + Amount: amount, + } + return } func (l *Ledger) storeSellingData(txHash []byte, data []byte) error { - key := l.buildAssetsSellingKey(txHash) + key := l.buildAssetsSellingKey(txHash) - return l.Storage.Put(kvDatabase.KVItem{ - Key: key, - Data: data, - Exists: true, - }) + return l.Storage.Put(kvDatabase.KVItem{ + Key: key, + Data: data, + Exists: true, + }) } func (l *Ledger) getSellingData(txHash []byte) ([]byte, error) { - key := l.buildAssetsSellingKey(txHash) + key := l.buildAssetsSellingKey(txHash) - data, err := l.Storage.Get(key) - if err != nil { - return nil, err - } + data, err := l.Storage.Get(key) + if err != nil { + return nil, err + } - if !data.Exists { - return nil, errors.New("no such selling") - } + if !data.Exists { + return nil, errors.New("no such selling") + } - return data.Data, nil + return data.Data, nil } func (l *Ledger) deleteSellingData(txHash []byte) error { - key := l.buildAssetsSellingKey(txHash) + key := l.buildAssetsSellingKey(txHash) - return l.Storage.Delete(key) + return l.Storage.Delete(key) } diff --git a/service/application/basicAssets/basicAssetsSQLStorage/query.go b/service/application/basicAssets/basicAssetsSQLStorage/query.go index 16f7c85..3ad3372 100644 --- a/service/application/basicAssets/basicAssetsSQLStorage/query.go +++ b/service/application/basicAssets/basicAssetsSQLStorage/query.go @@ -18,348 +18,347 @@ package basicAssetsSQLStorage import ( - "github.com/SealSC/SealABC/metadata/httpJSONResult/rowsWithCount" - "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsSQLTables" - "errors" + "errors" + "github.com/SealSC/SealABC/metadata/httpJSONResult/rowsWithCount" + "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsSQLTables" ) const rowsPerPage = 20 func (s *Storage) GetAssetsList(p []string) (ret interface{}, err error) { - page, err := pageFromParam(p) - if err != nil { - return - } - - table := basicAssetsSQLTables.AssetsList.Name() - rowType := basicAssetsSQLTables.AssetsListRow{} - start := rowsPerPage * page - - pSQL := "select * from " + - "`" + table + "`" + - " where `c_id` >=? order by `c_id` desc limit 0,?" - - rows, err := s.Driver.Query(rowType, pSQL, - []interface{}{ - start, - rowsPerPage, - }) - - if err != nil { - return - } - - count, err := s.Driver.RowCount(table, "", nil) - if err != nil { - return - } - - result := rowsWithCount.Entity { - Rows: rows, - Total: count, - } - - return result, err + page, err := pageFromParam(p) + if err != nil { + return + } + + table := basicAssetsSQLTables.AssetsList.Name() + rowType := basicAssetsSQLTables.AssetsListRow{} + start := rowsPerPage * page + + pSQL := "select * from " + + "`" + table + "`" + + " where `c_id` >=? order by `c_id` desc limit 0,?" + + rows, err := s.Driver.Query(rowType, pSQL, + []interface{}{ + start, + rowsPerPage, + }) + + if err != nil { + return + } + + count, err := s.Driver.RowCount(table, "", nil) + if err != nil { + return + } + + result := rowsWithCount.Entity{ + Rows: rows, + Total: count, + } + + return result, err } func (s *Storage) GetTransferList(p []string) (ret interface{}, err error) { - page, err := pageFromParam(p) - if err != nil { - return - } - - rowType := basicAssetsSQLTables.TransfersRow{} - table := basicAssetsSQLTables.Transfers.Name() - count, err := s.Driver.RowCount(table, "", nil) - if err != nil { - return - } - - start := count - (page * rowsPerPage) - queryData := []interface{} { - start, - rowsPerPage, - } - - pSQL := "select * from " + - "`" + table + "`" + - " where `c_id`<=? order by `c_id` desc limit 0,?" - - rows, err := s.Driver.Query(rowType, pSQL, queryData) - if err != nil { - return - } - - result := rowsWithCount.Entity { - Rows: rows, - Total: count, - } - - return result, err + page, err := pageFromParam(p) + if err != nil { + return + } + + rowType := basicAssetsSQLTables.TransfersRow{} + table := basicAssetsSQLTables.Transfers.Name() + count, err := s.Driver.RowCount(table, "", nil) + if err != nil { + return + } + + start := count - (page * rowsPerPage) + queryData := []interface{}{ + start, + rowsPerPage, + } + + pSQL := "select * from " + + "`" + table + "`" + + " where `c_id`<=? order by `c_id` desc limit 0,?" + + rows, err := s.Driver.Query(rowType, pSQL, queryData) + if err != nil { + return + } + + result := rowsWithCount.Entity{ + Rows: rows, + Total: count, + } + + return result, err } func (s *Storage) GetTransfer(p []string) (ret interface{}, err error) { - txHash, err := hashFromParam(p) - if err != nil { - return - } - - rowType := basicAssetsSQLTables.TransfersRow{} - table := basicAssetsSQLTables.Transfers.Name() - - rows, err := s.Driver.SimpleSelect(rowType, table, `c_tx_hash`, txHash) - if err != nil { - return - } - - if len(rows) == 0 { - err = errors.New("no such transfer") - return - } - - ret = rows[0] - return + txHash, err := hashFromParam(p) + if err != nil { + return + } + + rowType := basicAssetsSQLTables.TransfersRow{} + table := basicAssetsSQLTables.Transfers.Name() + + rows, err := s.Driver.SimpleSelect(rowType, table, `c_tx_hash`, txHash) + if err != nil { + return + } + + if len(rows) == 0 { + err = errors.New("no such transfer") + return + } + + ret = rows[0] + return } func (s *Storage) GetTransfersUnderAssets(p []string) (ret interface{}, err error) { - page, assets, err := pageAndHashFromParam(p) - if err != nil { - return - } - - row := basicAssetsSQLTables.TransfersRow{} - table := basicAssetsSQLTables.Transfers.Name() - count, err := s.Driver.RowCount(table, "where `c_assets_hash`=?", []interface{}{assets}) - if err != nil { - return - } - - start := page * rowsPerPage - queryData := []interface{} { - assets, - start, - rowsPerPage, - } - - pSQL := "select * from " + - "`" + table + "`" + - " where `c_assets_hash`=? order by `c_id` desc limit ?,?" - - rows, err := s.Driver.Query(row, pSQL, queryData) - if err != nil { - return - } - - result := rowsWithCount.Entity { - Rows: rows, - Total: count, - } - - return result, err + page, assets, err := pageAndHashFromParam(p) + if err != nil { + return + } + + row := basicAssetsSQLTables.TransfersRow{} + table := basicAssetsSQLTables.Transfers.Name() + count, err := s.Driver.RowCount(table, "where `c_assets_hash`=?", []interface{}{assets}) + if err != nil { + return + } + + start := page * rowsPerPage + queryData := []interface{}{ + assets, + start, + rowsPerPage, + } + + pSQL := "select * from " + + "`" + table + "`" + + " where `c_assets_hash`=? order by `c_id` desc limit ?,?" + + rows, err := s.Driver.Query(row, pSQL, queryData) + if err != nil { + return + } + + result := rowsWithCount.Entity{ + Rows: rows, + Total: count, + } + + return result, err } -func (s *Storage) GetAssets(p []string) (ret interface{}, err error) { - assetsHash, err := hashFromParam(p) - if err != nil { - return - } +func (s *Storage) GetAssets(p []string) (ret interface{}, err error) { + assetsHash, err := hashFromParam(p) + if err != nil { + return + } - row := basicAssetsSQLTables.AssetsListRow{} - table := basicAssetsSQLTables.AssetsList.Name() + row := basicAssetsSQLTables.AssetsListRow{} + table := basicAssetsSQLTables.AssetsList.Name() - pSQL := "select * from " + - "`" + table + "`" + - " where `c_meta_hash`=?" + pSQL := "select * from " + + "`" + table + "`" + + " where `c_meta_hash`=?" - assets, err := s.Driver.Query(row, pSQL, []interface{}{assetsHash}) - if err != nil { - return - } + assets, err := s.Driver.Query(row, pSQL, []interface{}{assetsHash}) + if err != nil { + return + } - if len(assets) < 1 { - err = errors.New("no such assets") - return - } + if len(assets) < 1 { + err = errors.New("no such assets") + return + } - return assets[0], err + return assets[0], err } func (s *Storage) GetAddressesList(p []string) (ret interface{}, err error) { - page, err := pageFromParam(p) - if err != nil { - return - } - - table := basicAssetsSQLTables.AddressList.Name() - offsetStart := page * rowsPerPage - - count, err := s.Driver.RowCount(table, "", nil) - if err != nil { - return - } - - if offsetStart > count { - return rowsWithCount.Entity { - Rows: nil, - Total: count, - }, nil - } - - pSQL := "select * from " + - "`" + table + "`" + - " order by `c_id` desc limit ?,?" - - row := basicAssetsSQLTables.AddressListRow{} - rows, err := s.Driver.Query(row, pSQL, []interface{} { - offsetStart, - rowsPerPage, - }) - if err != nil { - return - } - - list := rowsWithCount.Entity { - Rows: rows, - Total: count, - } - - return list, err + page, err := pageFromParam(p) + if err != nil { + return + } + + table := basicAssetsSQLTables.AddressList.Name() + offsetStart := page * rowsPerPage + + count, err := s.Driver.RowCount(table, "", nil) + if err != nil { + return + } + + if offsetStart > count { + return rowsWithCount.Entity{ + Rows: nil, + Total: count, + }, nil + } + + pSQL := "select * from " + + "`" + table + "`" + + " order by `c_id` desc limit ?,?" + + row := basicAssetsSQLTables.AddressListRow{} + rows, err := s.Driver.Query(row, pSQL, []interface{}{ + offsetStart, + rowsPerPage, + }) + if err != nil { + return + } + + list := rowsWithCount.Entity{ + Rows: rows, + Total: count, + } + + return list, err } func (s *Storage) GetBalancesUnderAssetsList(p []string) (ret interface{}, err error) { - page, assets, err := pageAndHashFromParam(p) - if err != nil { - return - } - - table := basicAssetsSQLTables.Balance.Name() - rowType := basicAssetsSQLTables.BalanceRow{} - count, err := s.Driver.RowCount(table, "where `c_assets`=?", []interface{}{assets}) - if err != nil { - return - } - - startPage := page * rowsPerPage - pSQL := "select * from " + - "`" + table + "`" + - " where `c_assets`=? order by `c_id` desc limit ?,?" - - rows, err := s.Driver.Query(rowType, pSQL, []interface{} { - assets, - startPage, - rowsPerPage, - }) - if err != nil { - return - } - - list := rowsWithCount.Entity { - Rows: rows, - Total: count, - } - - return list, err + page, assets, err := pageAndHashFromParam(p) + if err != nil { + return + } + + table := basicAssetsSQLTables.Balance.Name() + rowType := basicAssetsSQLTables.BalanceRow{} + count, err := s.Driver.RowCount(table, "where `c_assets`=?", []interface{}{assets}) + if err != nil { + return + } + + startPage := page * rowsPerPage + pSQL := "select * from " + + "`" + table + "`" + + " where `c_assets`=? order by `c_id` desc limit ?,?" + + rows, err := s.Driver.Query(rowType, pSQL, []interface{}{ + assets, + startPage, + rowsPerPage, + }) + if err != nil { + return + } + + list := rowsWithCount.Entity{ + Rows: rows, + Total: count, + } + + return list, err } func (s *Storage) GetAddressActionRecord(p []string) (ret interface{}, err error) { - page, address, err := pageAndHashFromParam(p) - if err != nil { - return - } - - table := basicAssetsSQLTables.AddressRecord.Name() - rowType := basicAssetsSQLTables.AddressRecordRow{} - - offsetStart := page * rowsPerPage - - pSQL := "select * from " + - "`" + table + "`" + - " where `c_address`=? order by `c_id` desc limit ?,?" - - rows, err := s.Driver.Query(rowType, pSQL, []interface{} { - address, - offsetStart, - rowsPerPage, - }) - - if err != nil { - return - } - - count, err := s.Driver.RowCount(table, "where `c_address`=?", []interface{}{ - address, - }) - if err != nil { - return - } - - list := rowsWithCount.Entity { - Rows: rows, - Total: count, - } - - return list, err + page, address, err := pageAndHashFromParam(p) + if err != nil { + return + } + + table := basicAssetsSQLTables.AddressRecord.Name() + rowType := basicAssetsSQLTables.AddressRecordRow{} + + offsetStart := page * rowsPerPage + + pSQL := "select * from " + + "`" + table + "`" + + " where `c_address`=? order by `c_id` desc limit ?,?" + + rows, err := s.Driver.Query(rowType, pSQL, []interface{}{ + address, + offsetStart, + rowsPerPage, + }) + + if err != nil { + return + } + + count, err := s.Driver.RowCount(table, "where `c_address`=?", []interface{}{ + address, + }) + if err != nil { + return + } + + list := rowsWithCount.Entity{ + Rows: rows, + Total: count, + } + + return list, err } func (s *Storage) GetAddressBalance(p []string) (ret interface{}, err error) { - page, addr, err := pageAndHashFromParam(p) - if err != nil { - return - } - - table := basicAssetsSQLTables.Balance.Name() - rowType := basicAssetsSQLTables.BalanceRow{} - - count, err := s.Driver.RowCount(table, "where `c_address`=?", []interface{}{ - addr, - }) - if err != nil { - return - } - - offsetStart := page * rowsPerPage - pSQL := "select * from `" + table +"` where `c_address`=? order by `c_id` asc limit ?,?" - - rows, err := s.Driver.Query(rowType, pSQL, []interface{}{ - addr, - offsetStart, - rowsPerPage, - }) - - if err != nil { - return - } - - list := rowsWithCount.Entity { - Rows: rows, - Total: count, - } - - return list, err + page, addr, err := pageAndHashFromParam(p) + if err != nil { + return + } + + table := basicAssetsSQLTables.Balance.Name() + rowType := basicAssetsSQLTables.BalanceRow{} + + count, err := s.Driver.RowCount(table, "where `c_address`=?", []interface{}{ + addr, + }) + if err != nil { + return + } + + offsetStart := page * rowsPerPage + pSQL := "select * from `" + table + "` where `c_address`=? order by `c_id` asc limit ?,?" + + rows, err := s.Driver.Query(rowType, pSQL, []interface{}{ + addr, + offsetStart, + rowsPerPage, + }) + + if err != nil { + return + } + + list := rowsWithCount.Entity{ + Rows: rows, + Total: count, + } + + return list, err } - func (s *Storage) GetSellingHistory(p []string) (ret interface{}, err error) { - table := basicAssetsSQLTables.SellingList.Name() - rowType := basicAssetsSQLTables.SellingListRow{} + table := basicAssetsSQLTables.SellingList.Name() + rowType := basicAssetsSQLTables.SellingListRow{} - count, err := s.Driver.RowCount(table, "", []interface{}{}) - if err != nil { - return - } + count, err := s.Driver.RowCount(table, "", []interface{}{}) + if err != nil { + return + } - pSQL := "select * from `" + table +"` order by `c_id` desc" + pSQL := "select * from `" + table + "` order by `c_id` desc" - rows, err := s.Driver.Query(rowType, pSQL, []interface{}{}) + rows, err := s.Driver.Query(rowType, pSQL, []interface{}{}) - if err != nil { - return - } + if err != nil { + return + } - list := rowsWithCount.Entity { - Rows: rows, - Total: count, - } + list := rowsWithCount.Entity{ + Rows: rows, + Total: count, + } - return list, err + return list, err } diff --git a/service/application/basicAssets/basicAssetsSQLStorage/storage.go b/service/application/basicAssets/basicAssetsSQLStorage/storage.go index 9c041d4..a9118c5 100644 --- a/service/application/basicAssets/basicAssetsSQLStorage/storage.go +++ b/service/application/basicAssets/basicAssetsSQLStorage/storage.go @@ -18,65 +18,65 @@ package basicAssetsSQLStorage import ( - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "errors" + "errors" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" ) -var QueryTypes struct{ - AssetsList enum.Element - Assets enum.Element +var QueryTypes struct { + AssetsList enum.Element + Assets enum.Element - Transfer enum.Element - TransferList enum.Element - TransfersUnderAssets enum.Element - BalancesUnderAssets enum.Element + Transfer enum.Element + TransferList enum.Element + TransfersUnderAssets enum.Element + BalancesUnderAssets enum.Element - AddressList enum.Element - AddressActionRecord enum.Element - AddressBalanceList enum.Element + AddressList enum.Element + AddressActionRecord enum.Element + AddressBalanceList enum.Element - SellingHistory enum.Element + SellingHistory enum.Element } type queryHandler func([]string) (interface{}, error) type Storage struct { - queryHandlers map[string] queryHandler - Driver simpleSQLDatabase.IDriver + queryHandlers map[string]queryHandler + Driver simpleSQLDatabase.IDriver } -func Load() { - enum.SimpleBuild(&QueryTypes) +func Load() { + enum.SimpleBuild(&QueryTypes) } func NewStorage(sqlDriver simpleSQLDatabase.IDriver) (s *Storage) { - s = &Storage{ - Driver: sqlDriver, - } + s = &Storage{ + Driver: sqlDriver, + } - s.queryHandlers = map[string] queryHandler { - QueryTypes.AssetsList.String(): s.GetAssetsList, - QueryTypes.TransferList.String(): s.GetTransferList, - QueryTypes.Transfer.String(): s.GetTransfer, - QueryTypes.Assets.String(): s.GetAssets, - QueryTypes.AddressList.String(): s.GetAddressesList, - QueryTypes.TransfersUnderAssets.String(): s.GetTransfersUnderAssets, - QueryTypes.BalancesUnderAssets.String(): s.GetBalancesUnderAssetsList, + s.queryHandlers = map[string]queryHandler{ + QueryTypes.AssetsList.String(): s.GetAssetsList, + QueryTypes.TransferList.String(): s.GetTransferList, + QueryTypes.Transfer.String(): s.GetTransfer, + QueryTypes.Assets.String(): s.GetAssets, + QueryTypes.AddressList.String(): s.GetAddressesList, + QueryTypes.TransfersUnderAssets.String(): s.GetTransfersUnderAssets, + QueryTypes.BalancesUnderAssets.String(): s.GetBalancesUnderAssetsList, - QueryTypes.AddressActionRecord.String(): s.GetAddressActionRecord, - QueryTypes.AddressBalanceList.String(): s.GetAddressBalance, + QueryTypes.AddressActionRecord.String(): s.GetAddressActionRecord, + QueryTypes.AddressBalanceList.String(): s.GetAddressBalance, - QueryTypes.SellingHistory.String(): s.GetSellingHistory, - } - return + QueryTypes.SellingHistory.String(): s.GetSellingHistory, + } + return } func (s *Storage) DoQuery(queryReq basicAssetsLedger.QueryRequest) (result interface{}, err error) { - if handler, exists := s.queryHandlers[queryReq.QueryType]; !exists { - err = errors.New("no such query handler: " + queryReq.QueryType) - return - } else { - return handler(queryReq.Parameter) - } + if handler, exists := s.queryHandlers[queryReq.QueryType]; !exists { + err = errors.New("no such query handler: " + queryReq.QueryType) + return + } else { + return handler(queryReq.Parameter) + } } diff --git a/service/application/basicAssets/basicAssetsSQLStorage/store.go b/service/application/basicAssets/basicAssetsSQLStorage/store.go index 0ab5731..030e379 100644 --- a/service/application/basicAssets/basicAssetsSQLStorage/store.go +++ b/service/application/basicAssets/basicAssetsSQLStorage/store.go @@ -18,173 +18,173 @@ package basicAssetsSQLStorage import ( - "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" - "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsSQLTables" - "encoding/hex" + "encoding/hex" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" + "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsSQLTables" ) func (s *Storage) StoreAssets(tx basicAssetsLedger.TransactionWithBlockInfo) (err error) { - assetsRows := basicAssetsSQLTables.AssetsList.NewRows().(basicAssetsSQLTables.AssetsListRows) - assetsRows.InsertAssets(tx) - _, err = s.Driver.Insert(&assetsRows, true) - if err != nil { - log.Log.Error("insert assets to sql database failed: ", err.Error()) - } - - transfersRows := basicAssetsSQLTables.Transfers.NewRows().(basicAssetsSQLTables.TransfersRows) - transfersRows.InsertTransferInsideIssueTransaction(tx) - _, err = s.Driver.Insert(&transfersRows, true) - if err != nil { - log.Log.Error("insert transfer to sql database failed: ", err.Error()) - } - - issueToAddr := hex.EncodeToString(tx.Assets.MetaSeal.SignerPublicKey) - - addressRecordRows := basicAssetsSQLTables.AddressRecord.NewRows().(basicAssetsSQLTables.AddressRecordRows) - addressRecordRows.InsertAddress(tx, issueToAddr, basicAssetsSQLTables.AddressRoles.Issuer) - _, err = s.Driver.Insert(&addressRecordRows, true) - if err != nil { - log.Log.Error("insert address record to sql database failed: ", err.Error()) - } - - addressListRows := basicAssetsSQLTables.AddressList.NewRows().(basicAssetsSQLTables.AddressListRows) - addressListRows.InsertAddress(tx, issueToAddr) - _, err = s.Driver.Insert(&addressListRows, true) - if err != nil { - log.Log.Error("insert address to sql database failed: ", err.Error()) - } - - return + assetsRows := basicAssetsSQLTables.AssetsList.NewRows().(basicAssetsSQLTables.AssetsListRows) + assetsRows.InsertAssets(tx) + _, err = s.Driver.Insert(&assetsRows, true) + if err != nil { + log.Log.Error("insert assets to sql database failed: ", err.Error()) + } + + transfersRows := basicAssetsSQLTables.Transfers.NewRows().(basicAssetsSQLTables.TransfersRows) + transfersRows.InsertTransferInsideIssueTransaction(tx) + _, err = s.Driver.Insert(&transfersRows, true) + if err != nil { + log.Log.Error("insert transfer to sql database failed: ", err.Error()) + } + + issueToAddr := hex.EncodeToString(tx.Assets.MetaSeal.SignerPublicKey) + + addressRecordRows := basicAssetsSQLTables.AddressRecord.NewRows().(basicAssetsSQLTables.AddressRecordRows) + addressRecordRows.InsertAddress(tx, issueToAddr, basicAssetsSQLTables.AddressRoles.Issuer) + _, err = s.Driver.Insert(&addressRecordRows, true) + if err != nil { + log.Log.Error("insert address record to sql database failed: ", err.Error()) + } + + addressListRows := basicAssetsSQLTables.AddressList.NewRows().(basicAssetsSQLTables.AddressListRows) + addressListRows.InsertAddress(tx, issueToAddr) + _, err = s.Driver.Insert(&addressListRows, true) + if err != nil { + log.Log.Error("insert address to sql database failed: ", err.Error()) + } + + return } func (s *Storage) StoreUnspent(tx basicAssetsLedger.TransactionWithBlockInfo, inputUnspent []basicAssetsLedger.Unspent) (err error) { - transfersRows := basicAssetsSQLTables.Transfers.NewRows().(basicAssetsSQLTables.TransfersRows) - transfersRows.InsertTransfer(tx, inputUnspent) - _, err = s.Driver.Insert(&transfersRows, true) - if err != nil { - log.Log.Error("insert transfer to sql database failed: ", err.Error()) - } - - addressRecordRows := basicAssetsSQLTables.AddressRecord.NewRows().(basicAssetsSQLTables.AddressRecordRows) - addressRecordRows.InsertAddressesInTransfer(tx, inputUnspent) - _, err = s.Driver.Insert(&addressRecordRows, true) - if err != nil { - log.Log.Error("insert address record to sql database failed: ", err.Error()) - } - - addressListRows := basicAssetsSQLTables.AddressList.NewRows().(basicAssetsSQLTables.AddressListRows) - addrCache := map[string] bool {} - for _, out := range tx.Output { - outAddr := hex.EncodeToString(out.To) - if _, exists := addrCache[outAddr]; exists{ - continue - } - - addressListRows.InsertAddress(tx, outAddr) - } - - for _, in := range inputUnspent { - inAddr := hex.EncodeToString(in.Owner) - if _, exists := addrCache[inAddr]; exists{ - continue - } - - addressListRows.InsertAddress(tx, inAddr) - } - _, err = s.Driver.Insert(&addressListRows, true) - if err != nil { - log.Log.Error("insert address to sql database failed: ", err.Error()) - } - - return + transfersRows := basicAssetsSQLTables.Transfers.NewRows().(basicAssetsSQLTables.TransfersRows) + transfersRows.InsertTransfer(tx, inputUnspent) + _, err = s.Driver.Insert(&transfersRows, true) + if err != nil { + log.Log.Error("insert transfer to sql database failed: ", err.Error()) + } + + addressRecordRows := basicAssetsSQLTables.AddressRecord.NewRows().(basicAssetsSQLTables.AddressRecordRows) + addressRecordRows.InsertAddressesInTransfer(tx, inputUnspent) + _, err = s.Driver.Insert(&addressRecordRows, true) + if err != nil { + log.Log.Error("insert address record to sql database failed: ", err.Error()) + } + + addressListRows := basicAssetsSQLTables.AddressList.NewRows().(basicAssetsSQLTables.AddressListRows) + addrCache := map[string]bool{} + for _, out := range tx.Output { + outAddr := hex.EncodeToString(out.To) + if _, exists := addrCache[outAddr]; exists { + continue + } + + addressListRows.InsertAddress(tx, outAddr) + } + + for _, in := range inputUnspent { + inAddr := hex.EncodeToString(in.Owner) + if _, exists := addrCache[inAddr]; exists { + continue + } + + addressListRows.InsertAddress(tx, inAddr) + } + _, err = s.Driver.Insert(&addressListRows, true) + if err != nil { + log.Log.Error("insert address to sql database failed: ", err.Error()) + } + + return } func (s *Storage) StoreBalance(height uint64, tm int64, balanceList []basicAssetsLedger.Balance) (err error) { - rows := basicAssetsSQLTables.Balance.NewRows().(basicAssetsSQLTables.BalanceRows) - rows.InsertBalances(height, tm, balanceList) - - _, err = s.Driver.Replace(&rows) - if err != nil { - log.Log.Error("insert balance failed: ", err.Error()) - } - return + rows := basicAssetsSQLTables.Balance.NewRows().(basicAssetsSQLTables.BalanceRows) + rows.InsertBalances(height, tm, balanceList) + + _, err = s.Driver.Replace(&rows) + if err != nil { + log.Log.Error("insert balance failed: ", err.Error()) + } + return } func (s *Storage) StoreSelling(tx basicAssetsLedger.TransactionWithBlockInfo, result basicAssetsLedger.SellingOperationResult) (err error) { - //store transfer - transferRows := basicAssetsSQLTables.Transfers.NewRows().(basicAssetsSQLTables.TransfersRows) - var outAddress []byte - switch tx.TxType { - case basicAssetsLedger.TransactionTypes.StartSelling.String(): - outAddress = []byte(basicAssetsLedger.MarketAddress) - fallthrough - case basicAssetsLedger.TransactionTypes.StopSelling.String(): - assets := result.SellingAssets - if len(outAddress) == 0 { - outAddress = result.Seller - } - in := result.UnspentList - out := []basicAssetsLedger.UTXOOutput{{ - To: outAddress, - Value: result.Amount, - }} - transferRows.InsertTransferByDetail(tx, assets, in, out) - - case basicAssetsLedger.TransactionTypes.BuyAssets.String(): - assets := result.PaymentAssets - unspentCount := len(result.UnspentList) - in := result.UnspentList[:unspentCount - 1] - - transferRows.InsertTransferByDetail(tx, assets, in, tx.Output) - - assets = result.SellingAssets - in = result.UnspentList[unspentCount - 1:] - out := []basicAssetsLedger.UTXOOutput{ - { - To: tx.Seal.SignerPublicKey, - Value: result.Amount, - }, - } - transferRows.InsertTransferByDetail(tx, assets, in, out) - - } - - _, err = s.Driver.Insert(&transferRows, false) - if err != nil { - log.Log.Warn("insert transfers in selling transaction failed: ", err.Error()) - } - - //store selling list - rows := basicAssetsSQLTables.SellingList.NewRows().(basicAssetsSQLTables.SellingListRows) - rows.InsertRow(tx, result.SellingData) - - switch tx.TxType { - case basicAssetsLedger.TransactionTypes.StartSelling.String(): - log.Log.Warn("try store start selling data") - _, err = s.Driver.Insert(&rows, false) - - case basicAssetsLedger.TransactionTypes.StopSelling.String(): - log.Log.Warn("try store stop selling data") - fallthrough - case basicAssetsLedger.TransactionTypes.BuyAssets.String(): - log.Log.Warn("try store buy data") - fields, condition := rows.GetUpdateInfo() - in := tx.Input - inputLen := len(in) - var targetTx = "" - if inputLen > 0 { - target := in[len(in) - 1] - targetTx = hex.EncodeToString(target.Transaction) - } else { - targetTx = hex.EncodeToString(result.Transaction) - } - - _, err = s.Driver.Update(&rows, fields, condition, []interface{}{targetTx}) - if err != nil { - log.Log.Warn("update failed: ", err.Error()) - } - } - - return + //store transfer + transferRows := basicAssetsSQLTables.Transfers.NewRows().(basicAssetsSQLTables.TransfersRows) + var outAddress []byte + switch tx.TxType { + case basicAssetsLedger.TransactionTypes.StartSelling.String(): + outAddress = []byte(basicAssetsLedger.MarketAddress) + fallthrough + case basicAssetsLedger.TransactionTypes.StopSelling.String(): + assets := result.SellingAssets + if len(outAddress) == 0 { + outAddress = result.Seller + } + in := result.UnspentList + out := []basicAssetsLedger.UTXOOutput{{ + To: outAddress, + Value: result.Amount, + }} + transferRows.InsertTransferByDetail(tx, assets, in, out) + + case basicAssetsLedger.TransactionTypes.BuyAssets.String(): + assets := result.PaymentAssets + unspentCount := len(result.UnspentList) + in := result.UnspentList[:unspentCount-1] + + transferRows.InsertTransferByDetail(tx, assets, in, tx.Output) + + assets = result.SellingAssets + in = result.UnspentList[unspentCount-1:] + out := []basicAssetsLedger.UTXOOutput{ + { + To: tx.Seal.SignerPublicKey, + Value: result.Amount, + }, + } + transferRows.InsertTransferByDetail(tx, assets, in, out) + + } + + _, err = s.Driver.Insert(&transferRows, false) + if err != nil { + log.Log.Warn("insert transfers in selling transaction failed: ", err.Error()) + } + + //store selling list + rows := basicAssetsSQLTables.SellingList.NewRows().(basicAssetsSQLTables.SellingListRows) + rows.InsertRow(tx, result.SellingData) + + switch tx.TxType { + case basicAssetsLedger.TransactionTypes.StartSelling.String(): + log.Log.Warn("try store start selling data") + _, err = s.Driver.Insert(&rows, false) + + case basicAssetsLedger.TransactionTypes.StopSelling.String(): + log.Log.Warn("try store stop selling data") + fallthrough + case basicAssetsLedger.TransactionTypes.BuyAssets.String(): + log.Log.Warn("try store buy data") + fields, condition := rows.GetUpdateInfo() + in := tx.Input + inputLen := len(in) + var targetTx = "" + if inputLen > 0 { + target := in[len(in)-1] + targetTx = hex.EncodeToString(target.Transaction) + } else { + targetTx = hex.EncodeToString(result.Transaction) + } + + _, err = s.Driver.Update(&rows, fields, condition, []interface{}{targetTx}) + if err != nil { + log.Log.Warn("update failed: ", err.Error()) + } + } + + return } diff --git a/service/application/basicAssets/basicAssetsSQLStorage/utils.go b/service/application/basicAssets/basicAssetsSQLStorage/utils.go index de43846..53e58e6 100644 --- a/service/application/basicAssets/basicAssetsSQLStorage/utils.go +++ b/service/application/basicAssets/basicAssetsSQLStorage/utils.go @@ -18,52 +18,52 @@ package basicAssetsSQLStorage import ( - "encoding/hex" - "errors" - "strconv" + "encoding/hex" + "errors" + "strconv" ) func pageFromParam(param []string) (page uint64, err error) { - if len(param) != 1 { - err = errors.New("invalid parameters") - return - } + if len(param) != 1 { + err = errors.New("invalid parameters") + return + } - page, err = strconv.ParseUint(param[0], 10, 64) - return + page, err = strconv.ParseUint(param[0], 10, 64) + return } func hashFromParam(param []string) (hash string, err error) { - if len(param) != 1 { - err = errors.New("invalid parameters") - return - } + if len(param) != 1 { + err = errors.New("invalid parameters") + return + } - _, err = hex.DecodeString(param[0]) - if err != nil { - return - } + _, err = hex.DecodeString(param[0]) + if err != nil { + return + } - hash = param[0] - return + hash = param[0] + return } func pageAndHashFromParam(param []string) (page uint64, hash string, err error) { - if len(param) != 2 { - err = errors.New("invalid parameters") - return - } + if len(param) != 2 { + err = errors.New("invalid parameters") + return + } - page, err = strconv.ParseUint(param[0], 10, 64) - if err != nil { - return - } + page, err = strconv.ParseUint(param[0], 10, 64) + if err != nil { + return + } - _, err = hex.DecodeString(param[1]) - if err != nil { - return - } + _, err = hex.DecodeString(param[1]) + if err != nil { + return + } - hash = param[1] - return + hash = param[1] + return } diff --git a/service/application/basicAssets/basicAssetsSQLTables/addressList.go b/service/application/basicAssets/basicAssetsSQLTables/addressList.go index 5f0fbd4..b33c91f 100644 --- a/service/application/basicAssets/basicAssetsSQLTables/addressList.go +++ b/service/application/basicAssets/basicAssetsSQLTables/addressList.go @@ -18,60 +18,60 @@ package basicAssetsSQLTables import ( - "github.com/SealSC/SealABC/common" - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "fmt" - "time" + "fmt" + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" + "time" ) type AddressListTable struct { - ID enum.Element `col:"c_id" ignoreInsert:"true"` - Height enum.Element `col:"c_height"` - Address enum.Element `col:"c_address"` - Time enum.Element `col:"c_time"` + ID enum.Element `col:"c_id" ignoreInsert:"true"` + Height enum.Element `col:"c_height"` + Address enum.Element `col:"c_address"` + Time enum.Element `col:"c_time"` - simpleSQLDatabase.BasicTable + simpleSQLDatabase.BasicTable } var AddressList AddressListTable func (a AddressListTable) NewRows() interface{} { - return simpleSQLDatabase.NewRowsInstance(AddressListRows{}) + return simpleSQLDatabase.NewRowsInstance(AddressListRows{}) } func (a AddressListTable) Name() (name string) { - return "t_basic_assets_address_list" + return "t_basic_assets_address_list" } func (a *AddressListTable) load() { - enum.SimpleBuild(a) - a.Instance = *a + enum.SimpleBuild(a) + a.Instance = *a } type AddressListRow struct { - ID string - Height string - Address string - Time string + ID string + Height string + Address string + Time string } type AddressListRows struct { - simpleSQLDatabase.BasicRows + simpleSQLDatabase.BasicRows } -func (b *AddressListRows) InsertAddress(tx basicAssetsLedger.TransactionWithBlockInfo, address string) { - timestamp := time.Unix(tx.CreateTime, 0) - newAddressRow := AddressListRow{ - Address: address, - Height: fmt.Sprintf("%d", tx.BlockInfo.BlockHeight), - Time: timestamp.Format(common.BASIC_TIME_FORMAT), - } +func (b *AddressListRows) InsertAddress(tx basicAssetsLedger.TransactionWithBlockInfo, address string) { + timestamp := time.Unix(tx.CreateTime, 0) + newAddressRow := AddressListRow{ + Address: address, + Height: fmt.Sprintf("%d", tx.BlockInfo.BlockHeight), + Time: timestamp.Format(common.BASIC_TIME_FORMAT), + } - b.Rows = append(b.Rows, newAddressRow) + b.Rows = append(b.Rows, newAddressRow) } func (b *AddressListRows) Table() simpleSQLDatabase.ITable { - return &AddressList + return &AddressList } diff --git a/service/application/basicAssets/basicAssetsSQLTables/addressRecord.go b/service/application/basicAssets/basicAssetsSQLTables/addressRecord.go index 426954a..9722284 100644 --- a/service/application/basicAssets/basicAssetsSQLTables/addressRecord.go +++ b/service/application/basicAssets/basicAssetsSQLTables/addressRecord.go @@ -18,85 +18,85 @@ package basicAssetsSQLTables import ( - "github.com/SealSC/SealABC/common" - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "encoding/hex" - "fmt" - "time" + "encoding/hex" + "fmt" + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" + "time" ) -var AddressRoles struct{ - Issuer enum.Element - Payer enum.Element - Payee enum.Element +var AddressRoles struct { + Issuer enum.Element + Payer enum.Element + Payee enum.Element } type AddressRecordTable struct { - ID enum.Element `col:"c_id" ignoreInsert:"true"` - Address enum.Element `col:"c_address"` - Height enum.Element `col:"c_height"` - TxHash enum.Element `col:"c_tx_hash"` - Role enum.Element `col:"c_tx_role"` - Time enum.Element `col:"c_time"` - - simpleSQLDatabase.BasicTable + ID enum.Element `col:"c_id" ignoreInsert:"true"` + Address enum.Element `col:"c_address"` + Height enum.Element `col:"c_height"` + TxHash enum.Element `col:"c_tx_hash"` + Role enum.Element `col:"c_tx_role"` + Time enum.Element `col:"c_time"` + + simpleSQLDatabase.BasicTable } var AddressRecord AddressRecordTable func (a AddressRecordTable) Name() (name string) { - return "t_basic_assets_address_record" + return "t_basic_assets_address_record" } func (a AddressRecordTable) NewRows() interface{} { - return simpleSQLDatabase.NewRowsInstance(AddressRecordRows{}) + return simpleSQLDatabase.NewRowsInstance(AddressRecordRows{}) } func (a *AddressRecordTable) load() { - enum.SimpleBuild(a) - enum.SimpleBuild(&AddressRoles) + enum.SimpleBuild(a) + enum.SimpleBuild(&AddressRoles) - a.Instance = *a + a.Instance = *a } type AddressRecordRow struct { - ID string - Address string - Height string - TxHash string - Role string - Time string + ID string + Address string + Height string + TxHash string + Role string + Time string } type AddressRecordRows struct { - simpleSQLDatabase.BasicRows + simpleSQLDatabase.BasicRows } -func (b *AddressRecordRows) InsertAddress(tx basicAssetsLedger.TransactionWithBlockInfo, address string, role enum.Element) { - timestamp := time.Unix(tx.CreateTime, 0) - newAddressRow := AddressRecordRow{ - Address: address, - Height: fmt.Sprintf("%d", tx.BlockInfo.BlockHeight), - TxHash: hex.EncodeToString(tx.Seal.Hash), - Role: role.String(), - Time: timestamp.Format(common.BASIC_TIME_FORMAT), - } - - b.Rows = append(b.Rows, newAddressRow) +func (b *AddressRecordRows) InsertAddress(tx basicAssetsLedger.TransactionWithBlockInfo, address string, role enum.Element) { + timestamp := time.Unix(tx.CreateTime, 0) + newAddressRow := AddressRecordRow{ + Address: address, + Height: fmt.Sprintf("%d", tx.BlockInfo.BlockHeight), + TxHash: hex.EncodeToString(tx.Seal.Hash), + Role: role.String(), + Time: timestamp.Format(common.BASIC_TIME_FORMAT), + } + + b.Rows = append(b.Rows, newAddressRow) } -func (b *AddressRecordRows) InsertAddressesInTransfer(tx basicAssetsLedger.TransactionWithBlockInfo, unspentList []basicAssetsLedger.Unspent) { - for _, in := range unspentList { - b.InsertAddress(tx, hex.EncodeToString(in.Owner), AddressRoles.Payer) - } +func (b *AddressRecordRows) InsertAddressesInTransfer(tx basicAssetsLedger.TransactionWithBlockInfo, unspentList []basicAssetsLedger.Unspent) { + for _, in := range unspentList { + b.InsertAddress(tx, hex.EncodeToString(in.Owner), AddressRoles.Payer) + } - for _, out := range tx.Output { - b.InsertAddress(tx, hex.EncodeToString(out.To), AddressRoles.Payee) - } + for _, out := range tx.Output { + b.InsertAddress(tx, hex.EncodeToString(out.To), AddressRoles.Payee) + } } func (b *AddressRecordRows) Table() simpleSQLDatabase.ITable { - return &AddressRecord + return &AddressRecord } diff --git a/service/application/basicAssets/basicAssetsSQLTables/assetsList.go b/service/application/basicAssets/basicAssetsSQLTables/assetsList.go index 5a70f65..dac71f5 100644 --- a/service/application/basicAssets/basicAssetsSQLTables/assetsList.go +++ b/service/application/basicAssets/basicAssetsSQLTables/assetsList.go @@ -18,104 +18,103 @@ package basicAssetsSQLTables import ( - "github.com/SealSC/SealABC/common" - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "encoding/hex" - "fmt" - "time" + "encoding/hex" + "fmt" + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" + "time" ) type AssetsListTable struct { - ID enum.Element `col:"c_id" ignoreInsert:"true"` - Height enum.Element `col:"c_height"` - ReqHash enum.Element `col:"c_req_hash"` - TxHash enum.Element `col:"c_tx_hash"` - AssetsName enum.Element `col:"c_name"` - AssetsSymbol enum.Element `col:"c_symbol"` - Supply enum.Element `col:"c_supply"` - Increasable enum.Element `col:"c_increasable"` - MetaHash enum.Element `col:"c_meta_hash"` - MetaSignature enum.Element `col:"c_meta_signature"` - IssuedHash enum.Element `col:"c_issued_hash"` - IssuedSignature enum.Element `col:"c_issued_signature"` - IssueTo enum.Element `col:"c_issue_to"` - Time enum.Element `col:"c_time"` - - simpleSQLDatabase.BasicTable + ID enum.Element `col:"c_id" ignoreInsert:"true"` + Height enum.Element `col:"c_height"` + ReqHash enum.Element `col:"c_req_hash"` + TxHash enum.Element `col:"c_tx_hash"` + AssetsName enum.Element `col:"c_name"` + AssetsSymbol enum.Element `col:"c_symbol"` + Supply enum.Element `col:"c_supply"` + Increasable enum.Element `col:"c_increasable"` + MetaHash enum.Element `col:"c_meta_hash"` + MetaSignature enum.Element `col:"c_meta_signature"` + IssuedHash enum.Element `col:"c_issued_hash"` + IssuedSignature enum.Element `col:"c_issued_signature"` + IssueTo enum.Element `col:"c_issue_to"` + Time enum.Element `col:"c_time"` + + simpleSQLDatabase.BasicTable } var AssetsList AssetsListTable func (a AssetsListTable) Name() (name string) { - return "t_basic_assets_list" + return "t_basic_assets_list" } func (a AssetsListTable) NewRows() interface{} { - return simpleSQLDatabase.NewRowsInstance(AssetsListRows{}) + return simpleSQLDatabase.NewRowsInstance(AssetsListRows{}) } - func (a *AssetsListTable) load() { - enum.SimpleBuild(a) - a.Instance = *a + enum.SimpleBuild(a) + a.Instance = *a } type AssetsListRow struct { - ID string - Height string - ReqHash string - TxHash string - AssetsName string - AssetsSymbol string - Supply string - Increasable string - MetaHash string - MetaSignature string - IssuedHash string - IssuedSignature string - IssueTo string - Time string + ID string + Height string + ReqHash string + TxHash string + AssetsName string + AssetsSymbol string + Supply string + Increasable string + MetaHash string + MetaSignature string + IssuedHash string + IssuedSignature string + IssueTo string + Time string } -func (b *AssetsListRow) FromTransaction(tx basicAssetsLedger.TransactionWithBlockInfo) { - b.Height = fmt.Sprintf("%d", tx.BlockInfo.BlockHeight) - b.ReqHash = hex.EncodeToString(tx.BlockInfo.RequestHash) - b.TxHash = hex.EncodeToString(tx.Seal.Hash) - b.AssetsName = tx.Assets.Name - b.AssetsSymbol = tx.Assets.Symbol - b.Supply = fmt.Sprintf("%d", tx.Assets.Supply) - if tx.Assets.Increasable { - b.Increasable = "1" - } else { - b.Increasable = "0" - } +func (b *AssetsListRow) FromTransaction(tx basicAssetsLedger.TransactionWithBlockInfo) { + b.Height = fmt.Sprintf("%d", tx.BlockInfo.BlockHeight) + b.ReqHash = hex.EncodeToString(tx.BlockInfo.RequestHash) + b.TxHash = hex.EncodeToString(tx.Seal.Hash) + b.AssetsName = tx.Assets.Name + b.AssetsSymbol = tx.Assets.Symbol + b.Supply = fmt.Sprintf("%d", tx.Assets.Supply) + if tx.Assets.Increasable { + b.Increasable = "1" + } else { + b.Increasable = "0" + } - b.MetaHash = hex.EncodeToString(tx.Assets.MetaSeal.Hash) - b.MetaSignature = hex.EncodeToString(tx.Assets.MetaSeal.Signature) + b.MetaHash = hex.EncodeToString(tx.Assets.MetaSeal.Hash) + b.MetaSignature = hex.EncodeToString(tx.Assets.MetaSeal.Signature) - b.IssuedHash = hex.EncodeToString(tx.Assets.IssuedSeal.Hash) - b.IssuedSignature = hex.EncodeToString(tx.Assets.IssuedSeal.Signature) + b.IssuedHash = hex.EncodeToString(tx.Assets.IssuedSeal.Hash) + b.IssuedSignature = hex.EncodeToString(tx.Assets.IssuedSeal.Signature) - b.IssueTo = hex.EncodeToString(tx.Assets.MetaSeal.SignerPublicKey) + b.IssueTo = hex.EncodeToString(tx.Assets.MetaSeal.SignerPublicKey) - timestamp := time.Unix(int64(tx.CreateTime), 0) - b.Time = timestamp.Format(common.BASIC_TIME_FORMAT) + timestamp := time.Unix(int64(tx.CreateTime), 0) + b.Time = timestamp.Format(common.BASIC_TIME_FORMAT) - return + return } type AssetsListRows struct { - simpleSQLDatabase.BasicRows + simpleSQLDatabase.BasicRows } func (b *AssetsListRows) InsertAssets(issueTX basicAssetsLedger.TransactionWithBlockInfo) { - newRow := AssetsListRow{} - newRow.FromTransaction(issueTX) - b.Rows = append(b.Rows, newRow) + newRow := AssetsListRow{} + newRow.FromTransaction(issueTX) + b.Rows = append(b.Rows, newRow) } func (b *AssetsListRows) Table() simpleSQLDatabase.ITable { - return &AssetsList + return &AssetsList } diff --git a/service/application/basicAssets/basicAssetsSQLTables/assetsTransfers.go b/service/application/basicAssets/basicAssetsSQLTables/assetsTransfers.go index 3d6ac49..a0b718d 100644 --- a/service/application/basicAssets/basicAssetsSQLTables/assetsTransfers.go +++ b/service/application/basicAssets/basicAssetsSQLTables/assetsTransfers.go @@ -18,164 +18,163 @@ package basicAssetsSQLTables import ( - "github.com/SealSC/SealABC/common" - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "encoding/hex" - "encoding/json" - "fmt" - "time" + "encoding/hex" + "encoding/json" + "fmt" + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" + "time" ) type TransfersTable struct { - ID enum.Element `col:"c_id" ignoreInsert:"true"` - Height enum.Element `col:"c_height"` - ReqHash enum.Element `col:"c_req_hash"` - TxHash enum.Element `col:"c_tx_hash"` - From enum.Element `col:"c_from"` - To enum.Element `col:"c_to"` - Assets enum.Element `col:"c_assets_hash"` - Amount enum.Element `col:"c_amount"` - Type enum.Element `col:"c_transaction_type"` - Memo enum.Element `col:"c_transaction_memo"` - Time enum.Element `col:"c_time"` - - simpleSQLDatabase.BasicTable + ID enum.Element `col:"c_id" ignoreInsert:"true"` + Height enum.Element `col:"c_height"` + ReqHash enum.Element `col:"c_req_hash"` + TxHash enum.Element `col:"c_tx_hash"` + From enum.Element `col:"c_from"` + To enum.Element `col:"c_to"` + Assets enum.Element `col:"c_assets_hash"` + Amount enum.Element `col:"c_amount"` + Type enum.Element `col:"c_transaction_type"` + Memo enum.Element `col:"c_transaction_memo"` + Time enum.Element `col:"c_time"` + + simpleSQLDatabase.BasicTable } var Transfers TransfersTable func (b TransfersTable) Name() (name string) { - return "t_basic_assets_transfers" + return "t_basic_assets_transfers" } func (b TransfersTable) NewRows() interface{} { - return simpleSQLDatabase.NewRowsInstance(TransfersRows{}) + return simpleSQLDatabase.NewRowsInstance(TransfersRows{}) } func (b *TransfersTable) load() { - enum.SimpleBuild(b) - b.Instance = *b + enum.SimpleBuild(b) + b.Instance = *b } - type TransfersRow struct { - ID string - Height string - ReqHash string - TxHash string - From string - To string - Assets string - Amount string - Type string - Memo string - Time string + ID string + Height string + ReqHash string + TxHash string + From string + To string + Assets string + Amount string + Type string + Memo string + Time string } type TransfersRows struct { - simpleSQLDatabase.BasicRows + simpleSQLDatabase.BasicRows } -func (b *TransfersRows) InsertTransferInsideIssueTransaction(tx basicAssetsLedger.TransactionWithBlockInfo) { - fromJson, _ := json.Marshal(map[string] uint64 {"blockchain": tx.Assets.Supply}) - toJson, _ := json.Marshal(map[string] uint64 { - hex.EncodeToString(tx.Assets.MetaSeal.SignerPublicKey): tx.Assets.Supply, - }) - - timestamp := time.Unix(tx.CreateTime, 0) - newTransfersRow := TransfersRow{ - Height: fmt.Sprintf("%d", tx.BlockInfo.BlockHeight), - ReqHash: hex.EncodeToString(tx.BlockInfo.RequestHash), - TxHash: hex.EncodeToString(tx.Seal.Hash), - From: string(fromJson), - To: string(toJson), - Assets: hex.EncodeToString(tx.Assets.MetaSeal.Hash), - Amount: fmt.Sprintf("%d", tx.Assets.Supply), - Type: tx.TxType, - Memo: tx.Memo, - Time: timestamp.Format(common.BASIC_TIME_FORMAT), - } - - b.Rows = append(b.Rows, newTransfersRow) +func (b *TransfersRows) InsertTransferInsideIssueTransaction(tx basicAssetsLedger.TransactionWithBlockInfo) { + fromJson, _ := json.Marshal(map[string]uint64{"blockchain": tx.Assets.Supply}) + toJson, _ := json.Marshal(map[string]uint64{ + hex.EncodeToString(tx.Assets.MetaSeal.SignerPublicKey): tx.Assets.Supply, + }) + + timestamp := time.Unix(tx.CreateTime, 0) + newTransfersRow := TransfersRow{ + Height: fmt.Sprintf("%d", tx.BlockInfo.BlockHeight), + ReqHash: hex.EncodeToString(tx.BlockInfo.RequestHash), + TxHash: hex.EncodeToString(tx.Seal.Hash), + From: string(fromJson), + To: string(toJson), + Assets: hex.EncodeToString(tx.Assets.MetaSeal.Hash), + Amount: fmt.Sprintf("%d", tx.Assets.Supply), + Type: tx.TxType, + Memo: tx.Memo, + Time: timestamp.Format(common.BASIC_TIME_FORMAT), + } + + b.Rows = append(b.Rows, newTransfersRow) } -func (b *TransfersRows) InsertTransfer(tx basicAssetsLedger.TransactionWithBlockInfo, unspentList []basicAssetsLedger.Unspent) { - from := map[string] uint64 {} - for _, in := range unspentList { - ownerKey := hex.EncodeToString(in.Owner) - from[ownerKey] += in.Value - } - fromJson, _ := json.Marshal(from) - - to := map[string] uint64 {} - var amount uint64 = 0 - for _, out := range tx.Output { - outKey := hex.EncodeToString(out.To) - to[outKey] += out.Value - amount += out.Value - } - toJson, _ := json.Marshal(to) - - timestamp := time.Unix(tx.CreateTime, 0) - newTransfersRow := TransfersRow{ - Height: fmt.Sprintf("%d", tx.BlockInfo.BlockHeight), - ReqHash: hex.EncodeToString(tx.BlockInfo.RequestHash), - TxHash: hex.EncodeToString(tx.Seal.Hash), - From: string(fromJson), - To: string(toJson), - Assets: hex.EncodeToString(tx.Assets.MetaSeal.Hash), - Amount: fmt.Sprintf("%d", amount), - Type: tx.TxType, - Memo: tx.Memo, - Time: timestamp.Format(common.BASIC_TIME_FORMAT), - } - - b.Rows = append(b.Rows, newTransfersRow) +func (b *TransfersRows) InsertTransfer(tx basicAssetsLedger.TransactionWithBlockInfo, unspentList []basicAssetsLedger.Unspent) { + from := map[string]uint64{} + for _, in := range unspentList { + ownerKey := hex.EncodeToString(in.Owner) + from[ownerKey] += in.Value + } + fromJson, _ := json.Marshal(from) + + to := map[string]uint64{} + var amount uint64 = 0 + for _, out := range tx.Output { + outKey := hex.EncodeToString(out.To) + to[outKey] += out.Value + amount += out.Value + } + toJson, _ := json.Marshal(to) + + timestamp := time.Unix(tx.CreateTime, 0) + newTransfersRow := TransfersRow{ + Height: fmt.Sprintf("%d", tx.BlockInfo.BlockHeight), + ReqHash: hex.EncodeToString(tx.BlockInfo.RequestHash), + TxHash: hex.EncodeToString(tx.Seal.Hash), + From: string(fromJson), + To: string(toJson), + Assets: hex.EncodeToString(tx.Assets.MetaSeal.Hash), + Amount: fmt.Sprintf("%d", amount), + Type: tx.TxType, + Memo: tx.Memo, + Time: timestamp.Format(common.BASIC_TIME_FORMAT), + } + + b.Rows = append(b.Rows, newTransfersRow) } func (b *TransfersRows) InsertTransferByDetail( - tx basicAssetsLedger.TransactionWithBlockInfo, - assets []byte, - input []basicAssetsLedger.Unspent, - output []basicAssetsLedger.UTXOOutput) { - - var amount uint64 = 0 - from := map[string] uint64 {} - for _, in := range input { - ownerKey := hex.EncodeToString(in.Owner) - from[ownerKey] += in.Value - } - fromJson, _ := json.Marshal(from) - - to := map[string] uint64 {} - for _, o := range output { - outKey := hex.EncodeToString(o.To) - to[outKey] += o.Value - amount += o.Value - } - - toJson, _ := json.Marshal(to) - - timestamp := time.Unix(tx.CreateTime, 0) - - newRow := TransfersRow { - Height: fmt.Sprintf("%d", tx.BlockInfo.BlockHeight), - ReqHash: hex.EncodeToString(tx.BlockInfo.RequestHash), - TxHash: hex.EncodeToString(tx.Seal.Hash), - From: string(fromJson), - To: string(toJson), - Assets: hex.EncodeToString(assets), - Amount: fmt.Sprintf("%d", amount), - Type: tx.TxType, - Memo: tx.Memo, - Time: timestamp.Format(common.BASIC_TIME_FORMAT), - } - - b.Rows = append(b.Rows, newRow) + tx basicAssetsLedger.TransactionWithBlockInfo, + assets []byte, + input []basicAssetsLedger.Unspent, + output []basicAssetsLedger.UTXOOutput) { + + var amount uint64 = 0 + from := map[string]uint64{} + for _, in := range input { + ownerKey := hex.EncodeToString(in.Owner) + from[ownerKey] += in.Value + } + fromJson, _ := json.Marshal(from) + + to := map[string]uint64{} + for _, o := range output { + outKey := hex.EncodeToString(o.To) + to[outKey] += o.Value + amount += o.Value + } + + toJson, _ := json.Marshal(to) + + timestamp := time.Unix(tx.CreateTime, 0) + + newRow := TransfersRow{ + Height: fmt.Sprintf("%d", tx.BlockInfo.BlockHeight), + ReqHash: hex.EncodeToString(tx.BlockInfo.RequestHash), + TxHash: hex.EncodeToString(tx.Seal.Hash), + From: string(fromJson), + To: string(toJson), + Assets: hex.EncodeToString(assets), + Amount: fmt.Sprintf("%d", amount), + Type: tx.TxType, + Memo: tx.Memo, + Time: timestamp.Format(common.BASIC_TIME_FORMAT), + } + + b.Rows = append(b.Rows, newRow) } func (b *TransfersRows) Table() simpleSQLDatabase.ITable { - return &Transfers + return &Transfers } diff --git a/service/application/basicAssets/basicAssetsSQLTables/balance.go b/service/application/basicAssets/basicAssetsSQLTables/balance.go index 7250ab3..dbd7af2 100644 --- a/service/application/basicAssets/basicAssetsSQLTables/balance.go +++ b/service/application/basicAssets/basicAssetsSQLTables/balance.go @@ -18,75 +18,75 @@ package basicAssetsSQLTables import ( - "github.com/SealSC/SealABC/common" - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "encoding/hex" - "fmt" - "time" + "encoding/hex" + "fmt" + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" + "time" ) type BalanceTable struct { - ID enum.Element `col:"c_id" ignoreInsert:"true"` - LastHeight enum.Element `col:"c_last_height"` - Address enum.Element `col:"c_address"` - Assets enum.Element `col:"c_assets"` - AssetsName enum.Element `col:"c_assets_name"` - AssetsSymbol enum.Element `col:"c_assets_symbol"` - Amount enum.Element `col:"c_amount"` - Time enum.Element `col:"c_time"` + ID enum.Element `col:"c_id" ignoreInsert:"true"` + LastHeight enum.Element `col:"c_last_height"` + Address enum.Element `col:"c_address"` + Assets enum.Element `col:"c_assets"` + AssetsName enum.Element `col:"c_assets_name"` + AssetsSymbol enum.Element `col:"c_assets_symbol"` + Amount enum.Element `col:"c_amount"` + Time enum.Element `col:"c_time"` - simpleSQLDatabase.BasicTable + simpleSQLDatabase.BasicTable } var Balance BalanceTable func (b BalanceTable) NewRows() interface{} { - return simpleSQLDatabase.NewRowsInstance(BalanceRows{}) + return simpleSQLDatabase.NewRowsInstance(BalanceRows{}) } func (b BalanceTable) Name() (name string) { - return "t_basic_assets_balance" + return "t_basic_assets_balance" } func (b *BalanceTable) load() { - enum.SimpleBuild(b) - b.Instance = *b + enum.SimpleBuild(b) + b.Instance = *b } type BalanceRow struct { - ID string - LastHeight string - Address string - Assets string - AssetsName string - AssetsSymbol string - Amount string - Time string + ID string + LastHeight string + Address string + Assets string + AssetsName string + AssetsSymbol string + Amount string + Time string } type BalanceRows struct { - simpleSQLDatabase.BasicRows + simpleSQLDatabase.BasicRows } -func (b *BalanceRows) InsertBalances(height uint64, tm int64, balanceList []basicAssetsLedger.Balance) { - timestamp := time.Unix(tm, 0) - for _, balance := range balanceList { - newAddressRow := BalanceRow{ - LastHeight: fmt.Sprintf("%d", height), - Address: hex.EncodeToString(balance.Address), - Assets: hex.EncodeToString(balance.Assets.MetaSeal.Hash), - AssetsName: balance.Assets.Name, - AssetsSymbol: balance.Assets.Symbol, - Amount: fmt.Sprintf("%d", balance.Amount), - Time: timestamp.Format(common.BASIC_TIME_FORMAT), - } +func (b *BalanceRows) InsertBalances(height uint64, tm int64, balanceList []basicAssetsLedger.Balance) { + timestamp := time.Unix(tm, 0) + for _, balance := range balanceList { + newAddressRow := BalanceRow{ + LastHeight: fmt.Sprintf("%d", height), + Address: hex.EncodeToString(balance.Address), + Assets: hex.EncodeToString(balance.Assets.MetaSeal.Hash), + AssetsName: balance.Assets.Name, + AssetsSymbol: balance.Assets.Symbol, + Amount: fmt.Sprintf("%d", balance.Amount), + Time: timestamp.Format(common.BASIC_TIME_FORMAT), + } - b.Rows = append(b.Rows, newAddressRow) - } + b.Rows = append(b.Rows, newAddressRow) + } } func (b *BalanceRows) Table() simpleSQLDatabase.ITable { - return &Balance + return &Balance } diff --git a/service/application/basicAssets/basicAssetsSQLTables/sellingList.go b/service/application/basicAssets/basicAssetsSQLTables/sellingList.go index b89d87d..26a807b 100644 --- a/service/application/basicAssets/basicAssetsSQLTables/sellingList.go +++ b/service/application/basicAssets/basicAssetsSQLTables/sellingList.go @@ -18,12 +18,12 @@ package basicAssetsSQLTables import ( + "encoding/hex" + "fmt" "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/dataStructure/enum" "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsLedger" "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "encoding/hex" - "fmt" "time" ) @@ -54,7 +54,6 @@ func (s SellingListTable) NewRows() interface{} { return simpleSQLDatabase.NewRowsInstance(SellingListRows{}) } - func (s *SellingListTable) load() { enum.SimpleBuild(s) s.Instance = *s @@ -75,7 +74,7 @@ type SellingListRow struct { StopTime string } -func (s *SellingListRow) FromTransaction(tx basicAssetsLedger.TransactionWithBlockInfo, sellingData basicAssetsLedger.SellingData) { +func (s *SellingListRow) FromTransaction(tx basicAssetsLedger.TransactionWithBlockInfo, sellingData basicAssetsLedger.SellingData) { s.Height = fmt.Sprintf("%d", tx.BlockInfo.BlockHeight) s.Seller = hex.EncodeToString(sellingData.Seller) @@ -116,13 +115,13 @@ func (s *SellingListRows) InsertRow(tx basicAssetsLedger.TransactionWithBlockInf func (s *SellingListRows) GetUpdateInfo() ([]string, string) { return []string{ - "Height", - "StopTransaction", - "Buyer", - "Status", - "StopTime", - }, - "where c_start_transaction=?" + "Height", + "StopTransaction", + "Buyer", + "Status", + "StopTime", + }, + "where c_start_transaction=?" } func (s *SellingListRows) Table() simpleSQLDatabase.ITable { diff --git a/service/application/basicAssets/basicAssetsSQLTables/tables.go b/service/application/basicAssets/basicAssetsSQLTables/tables.go index a1886ba..24075bd 100644 --- a/service/application/basicAssets/basicAssetsSQLTables/tables.go +++ b/service/application/basicAssets/basicAssetsSQLTables/tables.go @@ -17,11 +17,11 @@ package basicAssetsSQLTables -func Load() { - AssetsList.load() - Transfers.load() - AddressRecord.load() - AddressList.load() - Balance.load() - SellingList.load() +func Load() { + AssetsList.load() + Transfers.load() + AddressRecord.load() + AddressList.load() + Balance.load() + SellingList.load() } diff --git a/service/application/basicAssets/config.go b/service/application/basicAssets/config.go index ecca8bf..b2df1a7 100644 --- a/service/application/basicAssets/config.go +++ b/service/application/basicAssets/config.go @@ -20,5 +20,5 @@ package basicAssets import "github.com/SealSC/SealABC/metadata/applicationCommonConfig" type Config struct { - applicationCommonConfig.Config + applicationCommonConfig.Config } diff --git a/service/application/basicAssets/service.go b/service/application/basicAssets/service.go index 2d1e31b..be62020 100644 --- a/service/application/basicAssets/service.go +++ b/service/application/basicAssets/service.go @@ -18,30 +18,30 @@ package basicAssets import ( + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsInterface" "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsSQLTables" - "github.com/SealSC/SealABC/storage/db" - "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/service/application/basicAssets/basicAssetsInterface" - "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" + "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" + "github.com/SealSC/SealABC/storage/db" ) func Load() { - basicAssetsSQLTables.Load() - basicAssetsInterface.Load() + basicAssetsSQLTables.Load() + basicAssetsInterface.Load() } func NewBasicAssetsApplication(config Config) (app chainStructure.IBlockchainExternalApplication, err error) { - kvDriver, err := db.NewKVDatabaseDriver(config.KVDBName, config.KVDBConfig) - if err != nil { - log.Log.Error("can't load basic assets app for now: ", err.Error()) - return - } + kvDriver, err := db.NewKVDatabaseDriver(config.KVDBName, config.KVDBConfig) + if err != nil { + log.Log.Error("can't load basic assets app for now: ", err.Error()) + return + } - sqlStorage := config.SQLStorage - if !config.EnableSQLDB { - sqlStorage = nil - } - app = basicAssetsInterface.NewApplicationInterface(kvDriver, sqlStorage) + sqlStorage := config.SQLStorage + if !config.EnableSQLDB { + sqlStorage = nil + } + app = basicAssetsInterface.NewApplicationInterface(kvDriver, sqlStorage) - return + return } diff --git a/service/application/copyright/config.go b/service/application/copyright/config.go index 41d7ddb..118672f 100644 --- a/service/application/copyright/config.go +++ b/service/application/copyright/config.go @@ -31,17 +31,17 @@ type Config struct { } func DefaultConfig() *Config { - return &Config { - Config: commonCfg.Config { + return &Config{ + Config: commonCfg.Config{ KVDBName: dbInterface.LevelDB, KVDBConfig: levelDB.Config{ DBFilePath: "./copyright", }, - EnableSQLDB: false, - SQLStorage: nil, + EnableSQLDB: false, + SQLStorage: nil, - CryptoTools: crypto.Tools{ + CryptoTools: crypto.Tools{ HashCalculator: sha3.Sha256, SignerGenerator: ed25519.SignerGenerator, }, diff --git a/service/application/copyright/copyrightData/copyrightData.go b/service/application/copyright/copyrightData/copyrightData.go index 1615756..6df397e 100644 --- a/service/application/copyright/copyrightData/copyrightData.go +++ b/service/application/copyright/copyrightData/copyrightData.go @@ -23,25 +23,25 @@ import ( ) type CopyrightResource struct { - ID [] byte - Owner []byte - ResourceHash []byte + ID []byte + Owner []byte + ResourceHash []byte } type CopyrightCertificate struct { - ID []byte - Applicant []byte - ApplicantSeal seal.Entity + ID []byte + Applicant []byte + ApplicantSeal seal.Entity - Owner []byte - OwnSeal seal.Entity + Owner []byte + OwnSeal seal.Entity - BasicHash []byte - ExtraHash []byte + BasicHash []byte + ExtraHash []byte - CustomData []byte + CustomData []byte - PlatformSeal seal.Entity + PlatformSeal seal.Entity IssuanceTransaction []byte IssuanceTime string @@ -50,7 +50,6 @@ type CopyrightCertificate struct { } type CopyrightTrading struct { - } const APPName = "Traceable Storage" diff --git a/service/application/copyright/copyrightInterface/copyrightInterface.go b/service/application/copyright/copyrightInterface/copyrightInterface.go index 8afb2d9..a31c4e4 100644 --- a/service/application/copyright/copyrightInterface/copyrightInterface.go +++ b/service/application/copyright/copyrightInterface/copyrightInterface.go @@ -39,7 +39,7 @@ type CopyrightStorageApplication struct { chainStructure.BlankApplication reqList []string - reqMap map[string] blockchainRequest.Entity + reqMap map[string]blockchainRequest.Entity poolLimit int @@ -98,7 +98,7 @@ func (t *CopyrightStorageApplication) PreExecute(req blockchainRequest.Entity, _ } func (t *CopyrightStorageApplication) removeTransactionsFromPool(list RequestList) { - removedReq := map[string] bool {} + removedReq := map[string]bool{} for _, req := range list.Requests { reqKey := string(req.Seal.Hash) @@ -119,7 +119,7 @@ func (t *CopyrightStorageApplication) removeTransactionsFromPool(list RequestLis t.reqList = newTxPoolRecord } -func (t *CopyrightStorageApplication) Execute ( +func (t *CopyrightStorageApplication) Execute( req blockchainRequest.Entity, blk block.Entity, actIndex uint32, @@ -160,11 +160,10 @@ func (t *CopyrightStorageApplication) Information() (info service.BasicInformati info.Api.Protocol = service.ApiProtocols.INTERNAL.String() info.Api.Address = "" - info.Api.ApiList = []service.ApiInterface {} + info.Api.ApiList = []service.ApiInterface{} return } - func (t *CopyrightStorageApplication) RequestsForBlock(_ block.Entity) (reqList []blockchainRequest.Entity, cnt uint32) { t.poolLock.Lock() defer t.poolLock.Unlock() @@ -200,7 +199,7 @@ func (t *CopyrightStorageApplication) RequestsForBlock(_ block.Entity) (reqList Packed: true, PackedCount: cnt, - Seal: seal.Entity{ + Seal: seal.Entity{ Hash: txRoot, //use merkle tree root as seal hash for packed actions Signature: nil, SignerPublicKey: nil, @@ -211,13 +210,13 @@ func (t *CopyrightStorageApplication) RequestsForBlock(_ block.Entity) (reqList return []blockchainRequest.Entity{packedReq}, 1 } -func Load() { +func Load() { tsLedger.Load() } func NewApplicationInterface(kvDriver kvDatabase.IDriver, sqlDriver simpleSQLDatabase.IDriver) (app chainStructure.IBlockchainExternalApplication) { ts := CopyrightStorageApplication{ - reqList: []string {}, + reqList: []string{}, reqMap: map[string]blockchainRequest.Entity{}, poolLock: sync.RWMutex{}, poolLimit: 1000, @@ -227,4 +226,3 @@ func NewApplicationInterface(kvDriver kvDatabase.IDriver, sqlDriver simpleSQLDat app = &ts return } - diff --git a/service/application/memo/config.go b/service/application/memo/config.go index 3c41643..a933fd2 100644 --- a/service/application/memo/config.go +++ b/service/application/memo/config.go @@ -20,5 +20,5 @@ package memo import "github.com/SealSC/SealABC/metadata/applicationCommonConfig" type Config struct { - applicationCommonConfig.Config + applicationCommonConfig.Config } diff --git a/service/application/memo/memoInterface/memoInterface.go b/service/application/memo/memoInterface/memoInterface.go index 5fd4406..6fa1529 100644 --- a/service/application/memo/memoInterface/memoInterface.go +++ b/service/application/memo/memoInterface/memoInterface.go @@ -18,196 +18,194 @@ package memoInterface import ( - "github.com/SealSC/SealABC/crypto" - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/metadata/applicationResult" - "github.com/SealSC/SealABC/metadata/block" - "github.com/SealSC/SealABC/metadata/blockchainRequest" - "github.com/SealSC/SealABC/service" - "github.com/SealSC/SealABC/service/application/memo/memoSQLStorage" - "github.com/SealSC/SealABC/service/application/memo/memoSpace" - "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" - "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "encoding/json" - "errors" - "sync" - "time" + "encoding/json" + "errors" + "github.com/SealSC/SealABC/crypto" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/metadata/applicationResult" + "github.com/SealSC/SealABC/metadata/block" + "github.com/SealSC/SealABC/metadata/blockchainRequest" + "github.com/SealSC/SealABC/service" + "github.com/SealSC/SealABC/service/application/memo/memoSQLStorage" + "github.com/SealSC/SealABC/service/application/memo/memoSpace" + "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" + "sync" + "time" ) type MemoApplication struct { - chainStructure.BlankApplication + chainStructure.BlankApplication - operateLock sync.RWMutex - poolLock sync.Mutex + operateLock sync.RWMutex + poolLock sync.Mutex - reqPool map[string] blockchainRequest.Entity + reqPool map[string]blockchainRequest.Entity - - CryptoTools crypto.Tools - kvStorage kvDatabase.IDriver - sqlStorage *memoSQLStorage.Storage + CryptoTools crypto.Tools + kvStorage kvDatabase.IDriver + sqlStorage *memoSQLStorage.Storage } var applicationActions struct { - Query enum.Element - Record enum.Element + Query enum.Element + Record enum.Element } func (m *MemoApplication) Name() (name string) { - return "Memo" + return "Memo" } func (m *MemoApplication) kvQuery(req memoSpace.QueryRequest) (result interface{}, err error) { - if len(req.Parameter) == 0 { - err = errors.New("invalid parameter") - return - } - result, err = m.QueryMemo(req.Parameter[0]) - return + if len(req.Parameter) == 0 { + err = errors.New("invalid parameter") + return + } + result, err = m.QueryMemo(req.Parameter[0]) + return } func (m *MemoApplication) doRecord(req blockchainRequest.Entity) (result string, err error) { - _, _, err = m.VerifyReq(req) - if err != nil { - log.Log.Error("verify memo failed: ", err.Error()) - return - } + _, _, err = m.VerifyReq(req) + if err != nil { + log.Log.Error("verify memo failed: ", err.Error()) + return + } - m.poolLock.Lock() - defer m.poolLock.Unlock() + m.poolLock.Lock() + defer m.poolLock.Unlock() - m.reqPool[req.Seal.HexHash()] = req - return + m.reqPool[req.Seal.HexHash()] = req + return } func (m *MemoApplication) PushClientRequest(req blockchainRequest.Entity) (result interface{}, err error) { - switch req.RequestAction { - case applicationActions.Record.String(): - return m.doRecord(req) - - default: - err = errors.New("service not support " + req.RequestAction + "@" + m.Name()) - return - } + switch req.RequestAction { + case applicationActions.Record.String(): + return m.doRecord(req) + + default: + err = errors.New("service not support " + req.RequestAction + "@" + m.Name()) + return + } } func (m *MemoApplication) Query(req []byte) (result interface{}, err error) { - queryReq := memoSpace.QueryRequest{} - err = json.Unmarshal(req, &queryReq) - if err != nil { - return - } - - if m.sqlStorage != nil { - return m.sqlStorage.DoQuery(queryReq) - } else { - return m.kvQuery(queryReq) - } + queryReq := memoSpace.QueryRequest{} + err = json.Unmarshal(req, &queryReq) + if err != nil { + return + } + + if m.sqlStorage != nil { + return m.sqlStorage.DoQuery(queryReq) + } else { + return m.kvQuery(queryReq) + } } func (m *MemoApplication) PreExecute(req blockchainRequest.Entity, _ block.Entity) (result []byte, err error) { - _, _, err = m.VerifyReq(req) - return + _, _, err = m.VerifyReq(req) + return } func (m *MemoApplication) Execute( - req blockchainRequest.Entity, - blk block.Entity, - _ uint32, - ) (result applicationResult.Entity, err error) { - - _, memo, err := m.VerifyReq(req) - if err != nil { - log.Log.Error("verify memo failed: ", err.Error()) - return - } - - memoJson, _ := json.Marshal(memo) - - m.operateLock.Lock() - defer m.operateLock.Unlock() - - m.poolLock.Lock() - defer func() { - delete(m.reqPool, req.Seal.HexHash()) - m.poolLock.Unlock() - }() - - err = m.kvStorage.Put(kvDatabase.KVItem{ - Key: memo.Seal.Hash, - Data: memoJson, - }) - - if err != nil { - log.Log.Error("save memo failed: ", err.Error()) - return - } - - if m.sqlStorage != nil { - _ = m.sqlStorage.StoreMemo(blk.Header.Height, time.Now().Unix(), req, memo) - } - - return + req blockchainRequest.Entity, + blk block.Entity, + _ uint32, +) (result applicationResult.Entity, err error) { + + _, memo, err := m.VerifyReq(req) + if err != nil { + log.Log.Error("verify memo failed: ", err.Error()) + return + } + + memoJson, _ := json.Marshal(memo) + + m.operateLock.Lock() + defer m.operateLock.Unlock() + + m.poolLock.Lock() + defer func() { + delete(m.reqPool, req.Seal.HexHash()) + m.poolLock.Unlock() + }() + + err = m.kvStorage.Put(kvDatabase.KVItem{ + Key: memo.Seal.Hash, + Data: memoJson, + }) + + if err != nil { + log.Log.Error("save memo failed: ", err.Error()) + return + } + + if m.sqlStorage != nil { + _ = m.sqlStorage.StoreMemo(blk.Header.Height, time.Now().Unix(), req, memo) + } + + return } func (m *MemoApplication) RequestsForBlock(_ block.Entity) (reqList []blockchainRequest.Entity, cnt uint32) { - m.operateLock.Lock() - defer m.operateLock.Unlock() + m.operateLock.Lock() + defer m.operateLock.Unlock() - m.poolLock.Lock() - defer m.poolLock.Unlock() + m.poolLock.Lock() + defer m.poolLock.Unlock() - for _, req := range m.reqPool { - reqList = append(reqList, req) - } + for _, req := range m.reqPool { + reqList = append(reqList, req) + } - cnt = uint32(len(reqList)) - return + cnt = uint32(len(reqList)) + return } func (m *MemoApplication) Information() (info service.BasicInformation) { - info.Name = m.Name() - info.Description = "this is a memo application" + info.Name = m.Name() + info.Description = "this is a memo application" - info.Api.Protocol = service.ApiProtocols.INTERNAL.String() - info.Api.Address = "" - info.Api.ApiList = []service.ApiInterface {} - return + info.Api.Protocol = service.ApiProtocols.INTERNAL.String() + info.Api.Address = "" + info.Api.ApiList = []service.ApiInterface{} + return } func (m *MemoApplication) GetActionAsRequest(req blockchainRequest.Entity) blockchainRequest.Entity { - memo := memoSpace.Memo{} - _ = json.Unmarshal(req.Data, &memo) + memo := memoSpace.Memo{} + _ = json.Unmarshal(req.Data, &memo) - newReq := blockchainRequest.Entity{} - newReq.Seal = memo.Seal - newReq.RequestApplication = m.Name() - newReq.RequestAction = req.RequestAction - newReq.Data, _ = json.Marshal(memo.MemoData) + newReq := blockchainRequest.Entity{} + newReq.Seal = memo.Seal + newReq.RequestApplication = m.Name() + newReq.RequestAction = req.RequestAction + newReq.Data, _ = json.Marshal(memo.MemoData) - return newReq + return newReq } - -func Load() { - enum.SimpleBuild(&applicationActions) +func Load() { + enum.SimpleBuild(&applicationActions) } -func NewApplicationInterface(kvDriver kvDatabase.IDriver, sqlDriver simpleSQLDatabase.IDriver , tools crypto.Tools) (app chainStructure.IBlockchainExternalApplication) { - var storage *memoSQLStorage.Storage = nil - if sqlDriver != nil { - storage = memoSQLStorage.NewStorage(sqlDriver) - } - m := MemoApplication{ - CryptoTools: tools, - kvStorage: kvDriver, - sqlStorage: storage, - } - - m.reqPool = map[string] blockchainRequest.Entity{} - - app = &m - return +func NewApplicationInterface(kvDriver kvDatabase.IDriver, sqlDriver simpleSQLDatabase.IDriver, tools crypto.Tools) (app chainStructure.IBlockchainExternalApplication) { + var storage *memoSQLStorage.Storage = nil + if sqlDriver != nil { + storage = memoSQLStorage.NewStorage(sqlDriver) + } + m := MemoApplication{ + CryptoTools: tools, + kvStorage: kvDriver, + sqlStorage: storage, + } + + m.reqPool = map[string]blockchainRequest.Entity{} + + app = &m + return } diff --git a/service/application/memo/memoInterface/memoOperation.go b/service/application/memo/memoInterface/memoOperation.go index 813980d..456a9e8 100644 --- a/service/application/memo/memoInterface/memoOperation.go +++ b/service/application/memo/memoInterface/memoOperation.go @@ -18,55 +18,55 @@ package memoInterface import ( - "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" - "github.com/SealSC/SealABC/service/application/memo/memoSpace" - "encoding/json" - "github.com/SealSC/SealABC/metadata/blockchainRequest" - "github.com/SealSC/SealABC/log" - "errors" - "encoding/hex" + "encoding/hex" + "encoding/json" + "errors" + "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/metadata/blockchainRequest" + "github.com/SealSC/SealABC/service/application/memo/memoSpace" ) -func (m *MemoApplication) VerifyReq(req blockchainRequest.Entity) (passed bool, memo memoSpace.Memo, err error,) { - err = json.Unmarshal(req.Data, &memo) - if err != nil { - log.Log.Error("unmarshal memo failed") - err = errors.New("unmarshal memo failed") - return - } +func (m *MemoApplication) VerifyReq(req blockchainRequest.Entity) (passed bool, memo memoSpace.Memo, err error) { + err = json.Unmarshal(req.Data, &memo) + if err != nil { + log.Log.Error("unmarshal memo failed") + err = errors.New("unmarshal memo failed") + return + } - //bytes in memo data - memoSize := len(memo.Data) + len(memo.Type) - if memoSize > memoSpace.MaxMemoSize { - err = errors.New("full memo size (type + data) must less than 2MB") - return - } + //bytes in memo data + memoSize := len(memo.Data) + len(memo.Type) + if memoSize > memoSpace.MaxMemoSize { + err = errors.New("full memo size (type + data) must less than 2MB") + return + } - dataBytes, _ := structSerializer.ToMFBytes(memo.MemoData) - passed, err = memo.Seal.Verify(dataBytes, m.CryptoTools.HashCalculator) + dataBytes, _ := structSerializer.ToMFBytes(memo.MemoData) + passed, err = memo.Seal.Verify(dataBytes, m.CryptoTools.HashCalculator) - return + return } func (m *MemoApplication) QueryMemo(hash string) (memo memoSpace.Memo, err error) { - m.operateLock.RLock() - defer m.operateLock.RUnlock() + m.operateLock.RLock() + defer m.operateLock.RUnlock() - byteKey, err := hex.DecodeString(hash) - if err != nil { - return - } + byteKey, err := hex.DecodeString(hash) + if err != nil { + return + } - memoData, err := m.kvStorage.Get(byteKey) - if err != nil { - return - } + memoData, err := m.kvStorage.Get(byteKey) + if err != nil { + return + } - if !memoData.Exists { - err = errors.New("no such memo") - return - } + if !memoData.Exists { + err = errors.New("no such memo") + return + } - err = json.Unmarshal(memoData.Data, &memo) - return + err = json.Unmarshal(memoData.Data, &memo) + return } diff --git a/service/application/memo/memoSQLStorage/query.go b/service/application/memo/memoSQLStorage/query.go index 2fc9fd7..abe5403 100644 --- a/service/application/memo/memoSQLStorage/query.go +++ b/service/application/memo/memoSQLStorage/query.go @@ -18,184 +18,182 @@ package memoSQLStorage import ( - "github.com/SealSC/SealABC/metadata/httpJSONResult/rowsWithCount" - "github.com/SealSC/SealABC/service/application/memo/memoTables" - "errors" + "errors" + "github.com/SealSC/SealABC/metadata/httpJSONResult/rowsWithCount" + "github.com/SealSC/SealABC/service/application/memo/memoTables" ) const rowsPerPage = 20 func (s *Storage) GetMemoList(p []string) (ret interface{}, err error) { - page, err := pageFromParam(p) - if err != nil { - return - } - - table := memoTables.MemoList.Name() - rowType := memoTables.MemoListRow{} - - count, err := s.Driver.RowCount(table, "", nil) - if err != nil { - return - } - - offsetStart := rowsPerPage * page - pSQL := "select * from " + - "`" + table + "`" + - " order by `c_id` desc limit ?,?" - - rows, err := s.Driver.Query(rowType, pSQL, - []interface{}{ - offsetStart, - rowsPerPage, - }) - - if err != nil { - return - } - - result := rowsWithCount.Entity { - Rows: rows, - Total: count, - } - - return result, err + page, err := pageFromParam(p) + if err != nil { + return + } + + table := memoTables.MemoList.Name() + rowType := memoTables.MemoListRow{} + + count, err := s.Driver.RowCount(table, "", nil) + if err != nil { + return + } + + offsetStart := rowsPerPage * page + pSQL := "select * from " + + "`" + table + "`" + + " order by `c_id` desc limit ?,?" + + rows, err := s.Driver.Query(rowType, pSQL, + []interface{}{ + offsetStart, + rowsPerPage, + }) + + if err != nil { + return + } + + result := rowsWithCount.Entity{ + Rows: rows, + Total: count, + } + + return result, err } - func (s *Storage) GetAddressList(p []string) (ret interface{}, err error) { - page, err := pageFromParam(p) - if err != nil { - return - } - - table := memoTables.AddressList.Name() - offsetStart := page * rowsPerPage - - count, err := s.Driver.RowCount(table, "", nil) - if err != nil { - return - } - - if offsetStart > count { - return rowsWithCount.Entity { - Rows: nil, - Total: count, - }, nil - } - - pSQL := "select * from " + - "`" + table + "`" + - " order by `c_id` desc limit ?,?" - - row := memoTables.AddressListRow{} - rows, err := s.Driver.Query(row, pSQL, []interface{} { - offsetStart, - rowsPerPage, - }) - if err != nil { - return - } - - list := rowsWithCount.Entity { - Rows: rows, - Total: count, - } - - return list, err + page, err := pageFromParam(p) + if err != nil { + return + } + + table := memoTables.AddressList.Name() + offsetStart := page * rowsPerPage + + count, err := s.Driver.RowCount(table, "", nil) + if err != nil { + return + } + + if offsetStart > count { + return rowsWithCount.Entity{ + Rows: nil, + Total: count, + }, nil + } + + pSQL := "select * from " + + "`" + table + "`" + + " order by `c_id` desc limit ?,?" + + row := memoTables.AddressListRow{} + rows, err := s.Driver.Query(row, pSQL, []interface{}{ + offsetStart, + rowsPerPage, + }) + if err != nil { + return + } + + list := rowsWithCount.Entity{ + Rows: rows, + Total: count, + } + + return list, err } func (s *Storage) GetMemoByHash(p []string) (memoRow interface{}, err error) { - hash, err := hashFromParam(p) - if err != nil { - return - } - - rowType := memoTables.MemoListRow {} - table := memoTables.MemoList.Name() - rows, err := s.Driver.SimpleSelect(rowType, table, `c_hash`, hash) - if err != nil { - return - } - - if len(rows) != 1 { - err = errors.New("no such memo") - return - } - - memoRow = rows[0] - return + hash, err := hashFromParam(p) + if err != nil { + return + } + + rowType := memoTables.MemoListRow{} + table := memoTables.MemoList.Name() + rows, err := s.Driver.SimpleSelect(rowType, table, `c_hash`, hash) + if err != nil { + return + } + + if len(rows) != 1 { + err = errors.New("no such memo") + return + } + + memoRow = rows[0] + return } func (s *Storage) GetMemoByType(p []string) (memoRows interface{}, err error) { - page, memoType, err := pageAndMemoTypeFromParam(p) - if err != nil { - return - } - - table := memoTables.MemoList.Name() - start := page * rowsPerPage - pSQL := "select * from " + - "`" + table + "`" + - " where `c_type`=? order by `c_id` desc limit ?,?" - - rowType := memoTables.MemoListRow{} - rows, err := s.Driver.Query(rowType, pSQL, []interface{}{ - memoType, - start, - rowsPerPage, - }) - - if err != nil { - return - } - - count, err := s.Driver.RowCount(table, "where `c_type`=?", []interface{}{memoType}) - if err != nil { - return - } - - memoRows = rowsWithCount.Entity { - Rows: rows, - Total: count, - } - - - return + page, memoType, err := pageAndMemoTypeFromParam(p) + if err != nil { + return + } + + table := memoTables.MemoList.Name() + start := page * rowsPerPage + pSQL := "select * from " + + "`" + table + "`" + + " where `c_type`=? order by `c_id` desc limit ?,?" + + rowType := memoTables.MemoListRow{} + rows, err := s.Driver.Query(rowType, pSQL, []interface{}{ + memoType, + start, + rowsPerPage, + }) + + if err != nil { + return + } + + count, err := s.Driver.RowCount(table, "where `c_type`=?", []interface{}{memoType}) + if err != nil { + return + } + + memoRows = rowsWithCount.Entity{ + Rows: rows, + Total: count, + } + + return } func (s *Storage) GetMemoUnderAddress(p []string) (memoRows interface{}, err error) { - page, address, err := pageAndMemoTypeFromParam(p) - if err != nil { - return - } - - table := memoTables.MemoList.Name() - start := page * rowsPerPage - pSQL := "select * from " + - "`" + table + "`" + - " where `c_recorder`=? order by `c_id` desc limit ?,?" - - rowType := memoTables.MemoListRow{} - rows, err := s.Driver.Query(rowType, pSQL, []interface{}{ - address, - start, - rowsPerPage, - }) - - if err != nil { - return - } - - count, err := s.Driver.RowCount(table, "where `c_recorder`=?", []interface{}{address}) - if err != nil { - return - } - - memoRows = rowsWithCount.Entity { - Rows: rows, - Total: count, - } - - return + page, address, err := pageAndMemoTypeFromParam(p) + if err != nil { + return + } + + table := memoTables.MemoList.Name() + start := page * rowsPerPage + pSQL := "select * from " + + "`" + table + "`" + + " where `c_recorder`=? order by `c_id` desc limit ?,?" + + rowType := memoTables.MemoListRow{} + rows, err := s.Driver.Query(rowType, pSQL, []interface{}{ + address, + start, + rowsPerPage, + }) + + if err != nil { + return + } + + count, err := s.Driver.RowCount(table, "where `c_recorder`=?", []interface{}{address}) + if err != nil { + return + } + + memoRows = rowsWithCount.Entity{ + Rows: rows, + Total: count, + } + + return } diff --git a/service/application/memo/memoSQLStorage/statistics.go b/service/application/memo/memoSQLStorage/statistics.go index b0fb263..0c509a8 100644 --- a/service/application/memo/memoSQLStorage/statistics.go +++ b/service/application/memo/memoSQLStorage/statistics.go @@ -17,59 +17,59 @@ package memoSQLStorage -type countStatistics struct { - Count uint64 +type countStatistics struct { + Count uint64 } type distributed struct { - Count uint64 - Group string + Count uint64 + Group string } type statistic struct { - RecorderDistributed []interface{} - TypeDistributed []interface{} - SizeDistributed []interface{} - TotalMemo uint64 - TotalRecorder uint64 + RecorderDistributed []interface{} + TypeDistributed []interface{} + SizeDistributed []interface{} + TotalMemo uint64 + TotalRecorder uint64 } func (s *Storage) GetStatistics(_ []string) (ret interface{}, err error) { - memoCount, err := s.Driver.RowCount(`t_memo_list`, "", nil) - if err != nil { - return - } + memoCount, err := s.Driver.RowCount(`t_memo_list`, "", nil) + if err != nil { + return + } - addressCount, err := s.Driver.RowCount(`t_memo_address_list`, "", nil) - if err != nil { - return - } + addressCount, err := s.Driver.RowCount(`t_memo_address_list`, "", nil) + if err != nil { + return + } - pSQL := "SELECT COUNT(*) as `count`, `c_recorder` FROM `t_memo_list` WHERE 1 GROUP BY `c_recorder` ORDER BY `count` DESC limit 0, 20" - recorderRows, err := s.Driver.Query(distributed{}, pSQL, nil) - if err != nil { - return - } + pSQL := "SELECT COUNT(*) as `count`, `c_recorder` FROM `t_memo_list` WHERE 1 GROUP BY `c_recorder` ORDER BY `count` DESC limit 0, 20" + recorderRows, err := s.Driver.Query(distributed{}, pSQL, nil) + if err != nil { + return + } - pSQL = "SELECT COUNT(*) as `count`, `c_type` FROM `t_memo_list` WHERE 1 GROUP BY `c_type` ORDER BY `count` DESC limit 0, 20" - typeRows, err := s.Driver.Query(distributed{}, pSQL, nil) - if err != nil { - return - } + pSQL = "SELECT COUNT(*) as `count`, `c_type` FROM `t_memo_list` WHERE 1 GROUP BY `c_type` ORDER BY `count` DESC limit 0, 20" + typeRows, err := s.Driver.Query(distributed{}, pSQL, nil) + if err != nil { + return + } - pSQL = "SELECT COUNT(*) as `count`, `c_size` FROM `t_memo_list` WHERE 1 GROUP BY `c_size` ORDER BY `count` DESC limit 0, 20" - sizeRows, err := s.Driver.Query(distributed{}, pSQL, nil) - if err != nil { - return - } + pSQL = "SELECT COUNT(*) as `count`, `c_size` FROM `t_memo_list` WHERE 1 GROUP BY `c_size` ORDER BY `count` DESC limit 0, 20" + sizeRows, err := s.Driver.Query(distributed{}, pSQL, nil) + if err != nil { + return + } - ret = statistic { - RecorderDistributed: recorderRows, - TypeDistributed: typeRows, - SizeDistributed: sizeRows, - TotalMemo: memoCount, - TotalRecorder: addressCount, - } + ret = statistic{ + RecorderDistributed: recorderRows, + TypeDistributed: typeRows, + SizeDistributed: sizeRows, + TotalMemo: memoCount, + TotalRecorder: addressCount, + } - return + return } diff --git a/service/application/memo/memoSQLStorage/storage.go b/service/application/memo/memoSQLStorage/storage.go index 1a91207..38f5bbb 100644 --- a/service/application/memo/memoSQLStorage/storage.go +++ b/service/application/memo/memoSQLStorage/storage.go @@ -18,53 +18,53 @@ package memoSQLStorage import ( - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/service/application/memo/memoSpace" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "errors" + "errors" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/service/application/memo/memoSpace" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" ) -var QueryTypes struct{ - MemoList enum.Element - MemoByHash enum.Element - MemoByType enum.Element +var QueryTypes struct { + MemoList enum.Element + MemoByHash enum.Element + MemoByType enum.Element - AddressList enum.Element - MemoUnderAddress enum.Element - Statistics enum.Element + AddressList enum.Element + MemoUnderAddress enum.Element + Statistics enum.Element } type queryHandler func([]string) (interface{}, error) type Storage struct { - queryHandlers map[string] queryHandler - Driver simpleSQLDatabase.IDriver + queryHandlers map[string]queryHandler + Driver simpleSQLDatabase.IDriver } -func Load() { - enum.SimpleBuild(&QueryTypes) +func Load() { + enum.SimpleBuild(&QueryTypes) } func NewStorage(sqlDriver simpleSQLDatabase.IDriver) (s *Storage) { - s = &Storage{ - Driver: sqlDriver, - } + s = &Storage{ + Driver: sqlDriver, + } - s.queryHandlers = map[string] queryHandler { - QueryTypes.MemoList.String(): s.GetMemoList, - QueryTypes.MemoByHash.String(): s.GetMemoByHash, - QueryTypes.MemoByType.String(): s.GetMemoByType, - QueryTypes.AddressList.String(): s.GetAddressList, - QueryTypes.MemoUnderAddress.String(): s.GetMemoUnderAddress, - QueryTypes.Statistics.String(): s.GetStatistics, - } - return + s.queryHandlers = map[string]queryHandler{ + QueryTypes.MemoList.String(): s.GetMemoList, + QueryTypes.MemoByHash.String(): s.GetMemoByHash, + QueryTypes.MemoByType.String(): s.GetMemoByType, + QueryTypes.AddressList.String(): s.GetAddressList, + QueryTypes.MemoUnderAddress.String(): s.GetMemoUnderAddress, + QueryTypes.Statistics.String(): s.GetStatistics, + } + return } func (s *Storage) DoQuery(queryReq memoSpace.QueryRequest) (result interface{}, err error) { - if handler, exists := s.queryHandlers[queryReq.QueryType]; !exists { - err = errors.New("no such query handler: " + queryReq.QueryType) - return - } else { - return handler(queryReq.Parameter) - } + if handler, exists := s.queryHandlers[queryReq.QueryType]; !exists { + err = errors.New("no such query handler: " + queryReq.QueryType) + return + } else { + return handler(queryReq.Parameter) + } } diff --git a/service/application/memo/memoSQLStorage/store.go b/service/application/memo/memoSQLStorage/store.go index 6b388d5..59d3622 100644 --- a/service/application/memo/memoSQLStorage/store.go +++ b/service/application/memo/memoSQLStorage/store.go @@ -18,27 +18,27 @@ package memoSQLStorage import ( - "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/metadata/blockchainRequest" - "github.com/SealSC/SealABC/service/application/memo/memoSpace" - "github.com/SealSC/SealABC/service/application/memo/memoTables" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/metadata/blockchainRequest" + "github.com/SealSC/SealABC/service/application/memo/memoSpace" + "github.com/SealSC/SealABC/service/application/memo/memoTables" ) func (s *Storage) StoreMemo(height uint64, tm int64, req blockchainRequest.Entity, memo memoSpace.Memo) (err error) { - memoListRows := memoTables.MemoList.NewRows().(memoTables.MemoListRows) - memoListRows.InsertMemo(height, tm, req, memo) + memoListRows := memoTables.MemoList.NewRows().(memoTables.MemoListRows) + memoListRows.InsertMemo(height, tm, req, memo) - _, err = s.Driver.Insert(&memoListRows, true) - if err != nil { - log.Log.Error("insert memo to sql database failed: ", err.Error()) - } + _, err = s.Driver.Insert(&memoListRows, true) + if err != nil { + log.Log.Error("insert memo to sql database failed: ", err.Error()) + } - address := memo.Seal.HexPublicKey() - addressListRows := memoTables.AddressList.NewRows().(memoTables.AddressListRows) - addressListRows.InsertAddress(height, tm, address) - _, err = s.Driver.Insert(&addressListRows, true) - if err != nil { - log.Log.Error("insert memo address to sql database failed: ", err.Error()) - } - return + address := memo.Seal.HexPublicKey() + addressListRows := memoTables.AddressList.NewRows().(memoTables.AddressListRows) + addressListRows.InsertAddress(height, tm, address) + _, err = s.Driver.Insert(&addressListRows, true) + if err != nil { + log.Log.Error("insert memo address to sql database failed: ", err.Error()) + } + return } diff --git a/service/application/memo/memoSQLStorage/utils.go b/service/application/memo/memoSQLStorage/utils.go index 5c65eb0..80a286d 100644 --- a/service/application/memo/memoSQLStorage/utils.go +++ b/service/application/memo/memoSQLStorage/utils.go @@ -18,67 +18,67 @@ package memoSQLStorage import ( - "encoding/hex" - "errors" - "strconv" + "encoding/hex" + "errors" + "strconv" ) func pageFromParam(param []string) (page uint64, err error) { - if len(param) != 1 { - err = errors.New("invalid parameters") - return - } + if len(param) != 1 { + err = errors.New("invalid parameters") + return + } - page, err = strconv.ParseUint(param[0], 10, 64) - return + page, err = strconv.ParseUint(param[0], 10, 64) + return } func hashFromParam(param []string) (hash string, err error) { - if len(param) != 1 { - err = errors.New("invalid parameters") - return - } + if len(param) != 1 { + err = errors.New("invalid parameters") + return + } - _, err = hex.DecodeString(param[0]) - if err != nil { - return - } + _, err = hex.DecodeString(param[0]) + if err != nil { + return + } - hash = param[0] - return + hash = param[0] + return } func pageAndHashFromParam(param []string) (page uint64, hash string, err error) { - if len(param) != 2 { - err = errors.New("invalid parameters") - return - } + if len(param) != 2 { + err = errors.New("invalid parameters") + return + } - page, err = strconv.ParseUint(param[0], 10, 64) - if err != nil { - return - } + page, err = strconv.ParseUint(param[0], 10, 64) + if err != nil { + return + } - _, err = hex.DecodeString(param[1]) - if err != nil { - return - } + _, err = hex.DecodeString(param[1]) + if err != nil { + return + } - hash = param[1] - return + hash = param[1] + return } func pageAndMemoTypeFromParam(param []string) (page uint64, memoType string, err error) { - if len(param) != 2 { - err = errors.New("invalid parameters") - return - } + if len(param) != 2 { + err = errors.New("invalid parameters") + return + } - page, err = strconv.ParseUint(param[0], 10, 64) - if err != nil { - return - } + page, err = strconv.ParseUint(param[0], 10, 64) + if err != nil { + return + } - memoType = param[1] - return + memoType = param[1] + return } diff --git a/service/application/memo/memoSpace/memoSpace.go b/service/application/memo/memoSpace/memoSpace.go index b7ad843..088b2da 100644 --- a/service/application/memo/memoSpace/memoSpace.go +++ b/service/application/memo/memoSpace/memoSpace.go @@ -22,17 +22,16 @@ import "github.com/SealSC/SealABC/metadata/seal" const MaxMemoSize = 2 * 1024 * 1024 type MemoData struct { - Type string - Data string + Type string + Data string } - type QueryRequest struct { - QueryType string - Parameter []string + QueryType string + Parameter []string } type Memo struct { - MemoData - Seal seal.Entity + MemoData + Seal seal.Entity } diff --git a/service/application/memo/memoTables/addressList.go b/service/application/memo/memoTables/addressList.go index adc0700..6d6d631 100644 --- a/service/application/memo/memoTables/addressList.go +++ b/service/application/memo/memoTables/addressList.go @@ -18,59 +18,59 @@ package memoTables import ( - "github.com/SealSC/SealABC/common" - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "fmt" - "time" + "fmt" + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" + "time" ) type AddressListTable struct { - ID enum.Element `col:"c_id" ignoreInsert:"true"` - Height enum.Element `col:"c_height"` - Address enum.Element `col:"c_address"` - Time enum.Element `col:"c_time"` + ID enum.Element `col:"c_id" ignoreInsert:"true"` + Height enum.Element `col:"c_height"` + Address enum.Element `col:"c_address"` + Time enum.Element `col:"c_time"` - simpleSQLDatabase.BasicTable + simpleSQLDatabase.BasicTable } var AddressList AddressListTable func (a AddressListTable) NewRows() interface{} { - return simpleSQLDatabase.NewRowsInstance(AddressListRows{}) + return simpleSQLDatabase.NewRowsInstance(AddressListRows{}) } func (a AddressListTable) Name() (name string) { - return "t_memo_address_list" + return "t_memo_address_list" } func (a *AddressListTable) load() { - enum.SimpleBuild(a) - a.Instance = *a + enum.SimpleBuild(a) + a.Instance = *a } type AddressListRow struct { - ID string - Height string - Address string - Time string + ID string + Height string + Address string + Time string } type AddressListRows struct { - simpleSQLDatabase.BasicRows + simpleSQLDatabase.BasicRows } func (b *AddressListRows) InsertAddress(height uint64, tm int64, address string) { - timestamp := time.Unix(tm, 0) - newAddressRow := AddressListRow{ - Height: fmt.Sprintf("%d", height), - Address: address, - Time: timestamp.Format(common.BASIC_TIME_FORMAT), - } + timestamp := time.Unix(tm, 0) + newAddressRow := AddressListRow{ + Height: fmt.Sprintf("%d", height), + Address: address, + Time: timestamp.Format(common.BASIC_TIME_FORMAT), + } - b.Rows = append(b.Rows, newAddressRow) + b.Rows = append(b.Rows, newAddressRow) } func (b *AddressListRows) Table() simpleSQLDatabase.ITable { - return &AddressList + return &AddressList } diff --git a/service/application/memo/memoTables/memoList.go b/service/application/memo/memoTables/memoList.go index d2954b4..4eb9fb9 100644 --- a/service/application/memo/memoTables/memoList.go +++ b/service/application/memo/memoTables/memoList.go @@ -18,81 +18,81 @@ package memoTables import ( - "github.com/SealSC/SealABC/common" - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/metadata/blockchainRequest" - "github.com/SealSC/SealABC/service/application/memo/memoSpace" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "fmt" - "time" + "fmt" + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/metadata/blockchainRequest" + "github.com/SealSC/SealABC/service/application/memo/memoSpace" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" + "time" ) type MemoListTable struct { - ID enum.Element `col:"c_id" ignoreInsert:"true"` - Height enum.Element `col:"c_height"` - ReqHash enum.Element `col:"c_req_hash"` - Recorder enum.Element `col:"c_recorder"` - Type enum.Element `col:"c_type"` - Data enum.Element `col:"c_data"` - Hash enum.Element `col:"c_hash"` - Sig enum.Element `col:"c_signature"` - Size enum.Element `col:"c_size"` - Time enum.Element `col:"c_time"` + ID enum.Element `col:"c_id" ignoreInsert:"true"` + Height enum.Element `col:"c_height"` + ReqHash enum.Element `col:"c_req_hash"` + Recorder enum.Element `col:"c_recorder"` + Type enum.Element `col:"c_type"` + Data enum.Element `col:"c_data"` + Hash enum.Element `col:"c_hash"` + Sig enum.Element `col:"c_signature"` + Size enum.Element `col:"c_size"` + Time enum.Element `col:"c_time"` - simpleSQLDatabase.BasicTable + simpleSQLDatabase.BasicTable } var MemoList MemoListTable func (m MemoListTable) NewRows() interface{} { - return simpleSQLDatabase.NewRowsInstance(MemoListRows{}) + return simpleSQLDatabase.NewRowsInstance(MemoListRows{}) } func (m MemoListTable) Name() (name string) { - return "t_memo_list" + return "t_memo_list" } func (m *MemoListTable) load() { - enum.SimpleBuild(m) - m.Instance = *m + enum.SimpleBuild(m) + m.Instance = *m } type MemoListRow struct { - ID string - Height string - ReqHash string - Recorder string - Type string - Data string - Hash string - Sig string - Size string - Time string + ID string + Height string + ReqHash string + Recorder string + Type string + Data string + Hash string + Sig string + Size string + Time string } type MemoListRows struct { - simpleSQLDatabase.BasicRows + simpleSQLDatabase.BasicRows } -func (m *MemoListRows) InsertMemo(height uint64, tm int64, tx blockchainRequest.Entity, memo memoSpace.Memo) { - timestamp := time.Unix(tm, 0) +func (m *MemoListRows) InsertMemo(height uint64, tm int64, tx blockchainRequest.Entity, memo memoSpace.Memo) { + timestamp := time.Unix(tm, 0) - memoDataSize := len(memo.Data) + memoDataSize := len(memo.Data) - newAddressRow := MemoListRow { - Height: fmt.Sprintf("%d", height), - ReqHash: tx.Seal.HexHash(), - Recorder: memo.Seal.HexPublicKey(), - Type: memo.Type, - Data: memo.Data, - Hash: memo.Seal.HexHash(), - Sig: memo.Seal.HexSignature(), - Size: fmt.Sprintf("%d", memoDataSize), - Time: timestamp.Format(common.BASIC_TIME_FORMAT), - } - m.Rows = append(m.Rows, newAddressRow) + newAddressRow := MemoListRow{ + Height: fmt.Sprintf("%d", height), + ReqHash: tx.Seal.HexHash(), + Recorder: memo.Seal.HexPublicKey(), + Type: memo.Type, + Data: memo.Data, + Hash: memo.Seal.HexHash(), + Sig: memo.Seal.HexSignature(), + Size: fmt.Sprintf("%d", memoDataSize), + Time: timestamp.Format(common.BASIC_TIME_FORMAT), + } + m.Rows = append(m.Rows, newAddressRow) } func (m *MemoListRows) Table() simpleSQLDatabase.ITable { - return &MemoList + return &MemoList } diff --git a/service/application/memo/memoTables/tables.go b/service/application/memo/memoTables/tables.go index 420be74..46d8bc0 100644 --- a/service/application/memo/memoTables/tables.go +++ b/service/application/memo/memoTables/tables.go @@ -17,7 +17,7 @@ package memoTables -func Load() { - MemoList.load() - AddressList.load() +func Load() { + MemoList.load() + AddressList.load() } diff --git a/service/application/memo/service.go b/service/application/memo/service.go index e120a6a..aefda58 100644 --- a/service/application/memo/service.go +++ b/service/application/memo/service.go @@ -18,34 +18,34 @@ package memo import ( - "github.com/SealSC/SealABC/service/application/memo/memoSQLStorage" - "github.com/SealSC/SealABC/service/application/memo/memoTables" - "github.com/SealSC/SealABC/storage/db" - "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" - "github.com/SealSC/SealABC/service/application/memo/memoInterface" - "github.com/SealSC/SealABC/crypto" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" + "github.com/SealSC/SealABC/crypto" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/service/application/memo/memoInterface" + "github.com/SealSC/SealABC/service/application/memo/memoSQLStorage" + "github.com/SealSC/SealABC/service/application/memo/memoTables" + "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" + "github.com/SealSC/SealABC/storage/db" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" ) func Load() { - memoInterface.Load() - memoSQLStorage.Load() - memoTables.Load() + memoInterface.Load() + memoSQLStorage.Load() + memoTables.Load() } func NewMemoApplication(config Config, tools crypto.Tools) (app chainStructure.IBlockchainExternalApplication, err error) { - kvDriver, err := db.NewKVDatabaseDriver(config.KVDBName, config.KVDBConfig) - if err != nil { - log.Log.Error("can't load basic assets app for now: ", err.Error()) - return - } + kvDriver, err := db.NewKVDatabaseDriver(config.KVDBName, config.KVDBConfig) + if err != nil { + log.Log.Error("can't load basic assets app for now: ", err.Error()) + return + } - var sqlDriver simpleSQLDatabase.IDriver = nil - if config.EnableSQLDB { - sqlDriver = config.SQLStorage - } + var sqlDriver simpleSQLDatabase.IDriver = nil + if config.EnableSQLDB { + sqlDriver = config.SQLStorage + } - app = memoInterface.NewApplicationInterface(kvDriver, sqlDriver, tools) - return + app = memoInterface.NewApplicationInterface(kvDriver, sqlDriver, tools) + return } diff --git a/service/application/smartAssets/config.go b/service/application/smartAssets/config.go index 22d5e72..5e3e8aa 100644 --- a/service/application/smartAssets/config.go +++ b/service/application/smartAssets/config.go @@ -33,17 +33,17 @@ type Config struct { } func DefaultConfig() *Config { - return &Config { + return &Config{ Config: commonCfg.Config{ KVDBName: dbInterface.LevelDB, KVDBConfig: levelDB.Config{ DBFilePath: "./smartAssets", }, - EnableSQLDB: false, - SQLStorage: nil, + EnableSQLDB: false, + SQLStorage: nil, - CryptoTools: crypto.Tools{ + CryptoTools: crypto.Tools{ HashCalculator: sha3.Sha256, SignerGenerator: ed25519.SignerGenerator, }, @@ -54,7 +54,7 @@ func DefaultConfig() *Config { Symbol: "SST", Supply: "1000000000", //one billion Increasable: false, - Owner: "", + Owner: "", }, } } diff --git a/service/application/smartAssets/smartAssetsLedger/errors.go b/service/application/smartAssets/smartAssetsLedger/errors.go index b162f41..0676912 100644 --- a/service/application/smartAssets/smartAssetsLedger/errors.go +++ b/service/application/smartAssets/smartAssetsLedger/errors.go @@ -35,4 +35,4 @@ var Errors struct { InvalidQuery enum.ErrorElement InvalidParameter enum.ErrorElement -} \ No newline at end of file +} diff --git a/service/application/smartAssets/smartAssetsLedger/operationForContractCall.go b/service/application/smartAssets/smartAssetsLedger/operationForContractCall.go index e85c205..7150905 100644 --- a/service/application/smartAssets/smartAssetsLedger/operationForContractCall.go +++ b/service/application/smartAssets/smartAssetsLedger/operationForContractCall.go @@ -25,7 +25,7 @@ import ( func (l *Ledger) preContractCall(tx Transaction, cache txResultCache, blk block.Entity) ([]StateData, txResultCache, error) { if tx.Type != TxType.ContractCall.String() { - return nil, cache, Errors.InvalidTransactionType + return nil, cache, Errors.InvalidTransactionType } if len(tx.To) == 0 { diff --git a/service/application/smartAssets/smartAssetsLedger/operationForContractCreation.go b/service/application/smartAssets/smartAssetsLedger/operationForContractCreation.go index bb78e03..41afa58 100644 --- a/service/application/smartAssets/smartAssetsLedger/operationForContractCreation.go +++ b/service/application/smartAssets/smartAssetsLedger/operationForContractCreation.go @@ -25,7 +25,7 @@ import ( func (l *Ledger) preContractCreation(tx Transaction, cache txResultCache, blk block.Entity) ([]StateData, txResultCache, error) { if tx.Type != TxType.CreateContract.String() { - return nil, cache, Errors.InvalidTransactionType + return nil, cache, Errors.InvalidTransactionType } if len(tx.To) != 0 { @@ -49,11 +49,11 @@ func (l *Ledger) preContractCreation(tx Transaction, cache txResultCache, blk bl contractAddr := contract.Namespace.Bytes() newState = append(newState, - StateData { + StateData{ Key: BuildKey(StoragePrefixes.ContractCode, contractAddr), NewVal: ret.ResultData, }, - StateData { + StateData{ Key: BuildKey(StoragePrefixes.ContractHash, contractAddr), NewVal: contract.Hash.Bytes(), }, diff --git a/service/application/smartAssets/smartAssetsLedger/storage.go b/service/application/smartAssets/smartAssetsLedger/storage.go index 26768b6..6710499 100644 --- a/service/application/smartAssets/smartAssetsLedger/storage.go +++ b/service/application/smartAssets/smartAssetsLedger/storage.go @@ -18,14 +18,15 @@ package smartAssetsLedger import ( + "errors" "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" "github.com/SealSC/SealABC/dataStructure/enum" "github.com/SealSC/SealEVM/environment" "github.com/SealSC/SealEVM/evmInt256" - "errors" ) const ContractAddressLen = 24 + func ContractAddressPrefix() []byte { return []byte("SC:") } @@ -43,7 +44,7 @@ var StoragePrefixes struct { ContractDestructs enum.Element } -func BuildKey(el enum.Element, baseKey []byte, extra ...[]byte) []byte { +func BuildKey(el enum.Element, baseKey []byte, extra ...[]byte) []byte { keyPrefix := []byte(el.String()) if baseKey == nil { diff --git a/service/application/smartAssets/smartAssetsSQLStorage/query.go b/service/application/smartAssets/smartAssetsSQLStorage/query.go index 0144b28..551d240 100644 --- a/service/application/smartAssets/smartAssetsSQLStorage/query.go +++ b/service/application/smartAssets/smartAssetsSQLStorage/query.go @@ -18,16 +18,16 @@ package smartAssetsSQLStorage import ( + "errors" "github.com/SealSC/SealABC/dataStructure/enum" "github.com/SealSC/SealABC/service/application/smartAssets/smartAssetsLedger" "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "errors" ) -type queryParam map[string] string +type queryParam map[string]string type queryHandler func(param queryParam) (interface{}, error) -var QueryTypes struct{ +var QueryTypes struct { TransactionList enum.Element Transaction enum.Element AccountList enum.Element @@ -39,7 +39,7 @@ var QueryTypes struct{ TransferList enum.Element } -var QueryParameterFields struct{ +var QueryParameterFields struct { Account enum.Element Contract enum.Element TxHash enum.Element diff --git a/service/application/smartAssets/smartAssetsSQLStorage/queryAccount.go b/service/application/smartAssets/smartAssetsSQLStorage/queryAccount.go index 3e78a51..8f5afee 100644 --- a/service/application/smartAssets/smartAssetsSQLStorage/queryAccount.go +++ b/service/application/smartAssets/smartAssetsSQLStorage/queryAccount.go @@ -18,25 +18,24 @@ package smartAssetsSQLStorage import ( - "github.com/SealSC/SealABC/service/application/smartAssets/smartAssetsSQLTables" "errors" + "github.com/SealSC/SealABC/service/application/smartAssets/smartAssetsSQLTables" ) - var addressListRowType = smartAssetsSQLTables.AddressListRow{} var addressListTableName = smartAssetsSQLTables.AddressList.Name() func (s Storage) queryAccountList(param queryParam) (interface{}, error) { commonParam := commonPagingQueryParam{ - queryParam: param, - rowType: addressListRowType, - table: addressListTableName, + queryParam: param, + rowType: addressListRowType, + table: addressListTableName, } return s.commonPagingQuery(commonParam) } -func (s Storage) queryAccount(param queryParam) (interface{}, error){ +func (s Storage) queryAccount(param queryParam) (interface{}, error) { account := param[QueryParameterFields.Account.String()] if account == "" { return nil, errors.New("invalid parameters") diff --git a/service/application/smartAssets/smartAssetsSQLStorage/queryContract.go b/service/application/smartAssets/smartAssetsSQLStorage/queryContract.go index 7e19a8f..8d8b2fe 100644 --- a/service/application/smartAssets/smartAssetsSQLStorage/queryContract.go +++ b/service/application/smartAssets/smartAssetsSQLStorage/queryContract.go @@ -18,8 +18,8 @@ package smartAssetsSQLStorage import ( - "github.com/SealSC/SealABC/service/application/smartAssets/smartAssetsSQLTables" "errors" + "github.com/SealSC/SealABC/service/application/smartAssets/smartAssetsSQLTables" ) var contractRowType = smartAssetsSQLTables.ContractRow{} @@ -29,9 +29,9 @@ func (s Storage) queryContractList(param queryParam) (interface{}, error) { account := param[QueryParameterFields.Account.String()] commonParam := commonPagingQueryParam{ - queryParam: param, - rowType: contractRowType, - table: contractTableName, + queryParam: param, + rowType: contractRowType, + table: contractTableName, } if account != "" { @@ -42,7 +42,7 @@ func (s Storage) queryContractList(param queryParam) (interface{}, error) { return s.commonPagingQuery(commonParam) } -func (s Storage) queryContractByTx(param queryParam) (interface{}, error){ +func (s Storage) queryContractByTx(param queryParam) (interface{}, error) { txHash := param[QueryParameterFields.TxHash.String()] if txHash == "" { return nil, errors.New("invalid parameters") @@ -51,7 +51,7 @@ func (s Storage) queryContractByTx(param queryParam) (interface{}, error){ return s.Driver.SimpleSelect(contractRowType, contractTableName, `c_tx_hash`, txHash) } -func (s Storage) queryContractByAddress(param queryParam) (interface{}, error){ +func (s Storage) queryContractByAddress(param queryParam) (interface{}, error) { address := param[QueryParameterFields.Contract.String()] if address == "" { return nil, errors.New("invalid parameters") diff --git a/service/application/smartAssets/smartAssetsSQLStorage/queryContractCall.go b/service/application/smartAssets/smartAssetsSQLStorage/queryContractCall.go index f7cc97a..5f4da46 100644 --- a/service/application/smartAssets/smartAssetsSQLStorage/queryContractCall.go +++ b/service/application/smartAssets/smartAssetsSQLStorage/queryContractCall.go @@ -18,8 +18,8 @@ package smartAssetsSQLStorage import ( - "github.com/SealSC/SealABC/service/application/smartAssets/smartAssetsSQLTables" "errors" + "github.com/SealSC/SealABC/service/application/smartAssets/smartAssetsSQLTables" "strings" ) @@ -49,9 +49,9 @@ func (s Storage) queryContractCallList(param queryParam) (interface{}, error) { contract := param[QueryParameterFields.Contract.String()] commonParam := commonPagingQueryParam{ - queryParam: param, - rowType: contractCallRowType, - table: contractCallTableName, + queryParam: param, + rowType: contractCallRowType, + table: contractCallTableName, } if account != "" || contract != "" { @@ -64,8 +64,7 @@ func (s Storage) queryContractCallList(param queryParam) (interface{}, error) { return s.commonPagingQuery(commonParam) } - -func (s Storage) queryContractCallByHash(param queryParam) (interface{}, error){ +func (s Storage) queryContractCallByHash(param queryParam) (interface{}, error) { txHash := param[QueryParameterFields.TxHash.String()] if txHash == "" { return nil, errors.New("invalid parameters") diff --git a/service/application/smartAssets/smartAssetsSQLStorage/queryTransaction.go b/service/application/smartAssets/smartAssetsSQLStorage/queryTransaction.go index 71f5822..2423579 100644 --- a/service/application/smartAssets/smartAssetsSQLStorage/queryTransaction.go +++ b/service/application/smartAssets/smartAssetsSQLStorage/queryTransaction.go @@ -18,8 +18,8 @@ package smartAssetsSQLStorage import ( - "github.com/SealSC/SealABC/service/application/smartAssets/smartAssetsSQLTables" "errors" + "github.com/SealSC/SealABC/service/application/smartAssets/smartAssetsSQLTables" ) var txRowType = smartAssetsSQLTables.TransactionRow{} @@ -29,9 +29,9 @@ func (s Storage) queryTransactionList(param queryParam) (interface{}, error) { account := param[QueryParameterFields.Account.String()] commonParam := commonPagingQueryParam{ - queryParam: param, - rowType: txRowType, - table: txTableName, + queryParam: param, + rowType: txRowType, + table: txTableName, } if account != "" { @@ -42,7 +42,7 @@ func (s Storage) queryTransactionList(param queryParam) (interface{}, error) { return s.commonPagingQuery(commonParam) } -func (s Storage) queryTransactionByHash(param queryParam) (interface{}, error){ +func (s Storage) queryTransactionByHash(param queryParam) (interface{}, error) { txHash := param[QueryParameterFields.TxHash.String()] if txHash == "" { return nil, errors.New("invalid parameters") diff --git a/service/application/smartAssets/smartAssetsSQLStorage/queryTransfer.go b/service/application/smartAssets/smartAssetsSQLStorage/queryTransfer.go index 7bb1e81..53d6aa9 100644 --- a/service/application/smartAssets/smartAssetsSQLStorage/queryTransfer.go +++ b/service/application/smartAssets/smartAssetsSQLStorage/queryTransfer.go @@ -28,9 +28,9 @@ func (s Storage) queryTransferList(param queryParam) (interface{}, error) { account := param[QueryParameterFields.Account.String()] commonParam := commonPagingQueryParam{ - queryParam: param, - rowType: transferRowType, - table: transferTableName, + queryParam: param, + rowType: transferRowType, + table: transferTableName, } if account != "" { diff --git a/service/application/smartAssets/smartAssetsSQLStorage/storage.go b/service/application/smartAssets/smartAssetsSQLStorage/storage.go index a271439..859ce69 100644 --- a/service/application/smartAssets/smartAssetsSQLStorage/storage.go +++ b/service/application/smartAssets/smartAssetsSQLStorage/storage.go @@ -23,8 +23,8 @@ import ( ) type Storage struct { - queryHandlers map[string] queryHandler - Driver simpleSQLDatabase.IDriver + queryHandlers map[string]queryHandler + Driver simpleSQLDatabase.IDriver } func Load() { @@ -34,10 +34,10 @@ func Load() { func NewStorage(sqlDriver simpleSQLDatabase.IDriver) (s *Storage) { s = &Storage{ - Driver: sqlDriver, + Driver: sqlDriver, } - s.queryHandlers = map[string] queryHandler { + s.queryHandlers = map[string]queryHandler{ QueryTypes.TransactionList.String(): s.queryTransactionList, QueryTypes.Transaction.String(): s.queryTransactionByHash, QueryTypes.AccountList.String(): s.queryAccountList, diff --git a/service/application/smartAssets/smartAssetsSQLStorage/store.go b/service/application/smartAssets/smartAssetsSQLStorage/store.go index fd94a97..6fe4b77 100644 --- a/service/application/smartAssets/smartAssetsSQLStorage/store.go +++ b/service/application/smartAssets/smartAssetsSQLStorage/store.go @@ -18,11 +18,11 @@ package smartAssetsSQLStorage import ( + "bytes" "github.com/SealSC/SealABC/log" "github.com/SealSC/SealABC/metadata/block" "github.com/SealSC/SealABC/service/application/smartAssets/smartAssetsLedger" "github.com/SealSC/SealABC/service/application/smartAssets/smartAssetsSQLTables" - "bytes" "math/big" ) @@ -68,7 +68,7 @@ func (s Storage) StoreTransaction(tx smartAssetsLedger.Transaction, blk block.En if err != nil { log.Log.Error("insert transaction to sql database failed: ", err.Error()) } - + classifiedRows := s.getClassifiedTableRows(tx.Type) if classifiedRows == nil { return @@ -80,7 +80,6 @@ func (s Storage) StoreTransaction(tx smartAssetsLedger.Transaction, blk block.En log.Log.Error("insert classified rows [" + tx.Type + "] failed: " + err.Error()) } - addressListRows := smartAssetsSQLTables.AddressList.NewRows().(smartAssetsSQLTables.AddressListRows) for _, v := range tx.TransactionResult.NewState { if isBalance, addr := s.isNewBalance(v.Key); isBalance { diff --git a/service/application/smartAssets/smartAssetsSQLTables/addressList.go b/service/application/smartAssets/smartAssetsSQLTables/addressList.go index fc73ce4..a496108 100644 --- a/service/application/smartAssets/smartAssetsSQLTables/addressList.go +++ b/service/application/smartAssets/smartAssetsSQLTables/addressList.go @@ -18,12 +18,12 @@ package smartAssetsSQLTables import ( + "encoding/hex" + "fmt" "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/dataStructure/enum" "github.com/SealSC/SealABC/metadata/block" "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "encoding/hex" - "fmt" "math/big" "time" ) @@ -77,7 +77,7 @@ func (a *AddressListRows) Insert(addr []byte, balance *big.Int, blk block.Entity a.Rows = append(a.Rows, newAddressRow) } -func (a *AddressListRows) InsertSystemIssueBalance(balance *big.Int, address string) { +func (a *AddressListRows) InsertSystemIssueBalance(balance *big.Int, address string) { newRow := AddressListRow{ Address: address, Balance: balance.String(), diff --git a/service/application/smartAssets/smartAssetsSQLTables/contract.go b/service/application/smartAssets/smartAssetsSQLTables/contract.go index 7f437bf..5c75c85 100644 --- a/service/application/smartAssets/smartAssetsSQLTables/contract.go +++ b/service/application/smartAssets/smartAssetsSQLTables/contract.go @@ -18,13 +18,13 @@ package smartAssetsSQLTables import ( + "encoding/hex" + "fmt" "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/dataStructure/enum" "github.com/SealSC/SealABC/metadata/block" "github.com/SealSC/SealABC/service/application/smartAssets/smartAssetsLedger" "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "encoding/hex" - "fmt" "time" ) diff --git a/service/application/smartAssets/smartAssetsSQLTables/contractCall.go b/service/application/smartAssets/smartAssetsSQLTables/contractCall.go index bfb873f..0a97466 100644 --- a/service/application/smartAssets/smartAssetsSQLTables/contractCall.go +++ b/service/application/smartAssets/smartAssetsSQLTables/contractCall.go @@ -18,14 +18,14 @@ package smartAssetsSQLTables import ( + "encoding/hex" + "encoding/json" + "fmt" "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/dataStructure/enum" "github.com/SealSC/SealABC/metadata/block" "github.com/SealSC/SealABC/service/application/smartAssets/smartAssetsLedger" "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "encoding/hex" - "encoding/json" - "fmt" "time" ) diff --git a/service/application/smartAssets/smartAssetsSQLTables/tables.go b/service/application/smartAssets/smartAssetsSQLTables/tables.go index 8310c15..528248d 100644 --- a/service/application/smartAssets/smartAssetsSQLTables/tables.go +++ b/service/application/smartAssets/smartAssetsSQLTables/tables.go @@ -28,7 +28,7 @@ type ISQLRows interface { Insert(tx smartAssetsLedger.Transaction, blk block.Entity) } -func Load() { +func Load() { AddressList.load() ContractCall.load() Contract.load() diff --git a/service/application/smartAssets/smartAssetsSQLTables/transaction.go b/service/application/smartAssets/smartAssetsSQLTables/transaction.go index 9a362b0..d6756e4 100644 --- a/service/application/smartAssets/smartAssetsSQLTables/transaction.go +++ b/service/application/smartAssets/smartAssetsSQLTables/transaction.go @@ -18,14 +18,14 @@ package smartAssetsSQLTables import ( + "encoding/hex" + "encoding/json" + "fmt" "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/dataStructure/enum" "github.com/SealSC/SealABC/metadata/block" "github.com/SealSC/SealABC/service/application/smartAssets/smartAssetsLedger" "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "encoding/hex" - "encoding/json" - "fmt" "time" ) @@ -110,4 +110,3 @@ func (t *TransactionRows) Insert(tx smartAssetsLedger.Transaction, blk block.Ent func (t *TransactionRows) Table() simpleSQLDatabase.ITable { return &Transaction } - diff --git a/service/application/smartAssets/smartAssetsSQLTables/transfer.go b/service/application/smartAssets/smartAssetsSQLTables/transfer.go index 8810bbd..b977cf1 100644 --- a/service/application/smartAssets/smartAssetsSQLTables/transfer.go +++ b/service/application/smartAssets/smartAssetsSQLTables/transfer.go @@ -18,13 +18,13 @@ package smartAssetsSQLTables import ( + "encoding/hex" + "fmt" "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/dataStructure/enum" "github.com/SealSC/SealABC/metadata/block" "github.com/SealSC/SealABC/service/application/smartAssets/smartAssetsLedger" "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "encoding/hex" - "fmt" "time" ) @@ -36,7 +36,7 @@ type TransferTable struct { From enum.Element `col:"c_from"` To enum.Element `col:"c_to"` Value enum.Element `col:"c_value"` - Memo enum.Element `col:"c_memo"` + Memo enum.Element `col:"c_memo"` Time enum.Element `col:"c_time"` simpleSQLDatabase.BasicTable diff --git a/service/application/traceableStorage/config.go b/service/application/traceableStorage/config.go index 5efebce..bb89bf8 100644 --- a/service/application/traceableStorage/config.go +++ b/service/application/traceableStorage/config.go @@ -31,17 +31,17 @@ type Config struct { } func DefaultConfig() *Config { - return &Config { - Config: commonCfg.Config { + return &Config{ + Config: commonCfg.Config{ KVDBName: dbInterface.LevelDB, KVDBConfig: levelDB.Config{ DBFilePath: "./traceableStorage", }, - EnableSQLDB: false, - SQLStorage: nil, + EnableSQLDB: false, + SQLStorage: nil, - CryptoTools: crypto.Tools{ + CryptoTools: crypto.Tools{ HashCalculator: sha3.Sha256, SignerGenerator: ed25519.SignerGenerator, }, diff --git a/service/application/traceableStorage/service.go b/service/application/traceableStorage/service.go index 9d81d89..6f4a335 100644 --- a/service/application/traceableStorage/service.go +++ b/service/application/traceableStorage/service.go @@ -48,4 +48,3 @@ func NewTraceableStorageApplication(config *Config) (app chainStructure.IBlockch app = tsInterface.NewApplicationInterface(kvDriver, sqlDriver) return } - diff --git a/service/application/traceableStorage/tsData/tsData.go b/service/application/traceableStorage/tsData/tsData.go index 0dc7831..4c332bf 100644 --- a/service/application/traceableStorage/tsData/tsData.go +++ b/service/application/traceableStorage/tsData/tsData.go @@ -18,16 +18,16 @@ package tsData import ( + "bytes" + "encoding/hex" + "encoding/json" + "errors" "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" "github.com/SealSC/SealABC/crypto" "github.com/SealSC/SealABC/crypto/hashes" "github.com/SealSC/SealABC/dataStructure/enum" "github.com/SealSC/SealABC/metadata/seal" "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" - "bytes" - "encoding/hex" - "encoding/json" - "errors" ) type TSMetaData struct { @@ -149,8 +149,8 @@ func (i *TSData) FromKVStoreItem(data []byte) (err error) { } var RequestTypes struct { - Store enum.Element - Modify enum.Element + Store enum.Element + Modify enum.Element } type TSServiceRequest struct { diff --git a/service/application/traceableStorage/tsInterface/tsInterface.go b/service/application/traceableStorage/tsInterface/tsInterface.go index 3045fd9..8989375 100644 --- a/service/application/traceableStorage/tsInterface/tsInterface.go +++ b/service/application/traceableStorage/tsInterface/tsInterface.go @@ -38,7 +38,7 @@ type TraceableStorageApplication struct { chainStructure.BlankApplication reqList []string - reqMap map[string] blockchainRequest.Entity + reqMap map[string]blockchainRequest.Entity poolLimit int @@ -97,7 +97,7 @@ func (t *TraceableStorageApplication) PreExecute(req blockchainRequest.Entity, _ } func (t *TraceableStorageApplication) removeTransactionsFromPool(list RequestList) { - removedReq := map[string] bool {} + removedReq := map[string]bool{} for _, req := range list.Requests { reqKey := string(req.Seal.Hash) @@ -118,7 +118,7 @@ func (t *TraceableStorageApplication) removeTransactionsFromPool(list RequestLis t.reqList = newTxPoolRecord } -func (t *TraceableStorageApplication) Execute ( +func (t *TraceableStorageApplication) Execute( req blockchainRequest.Entity, blk block.Entity, actIndex uint32, @@ -159,11 +159,10 @@ func (t *TraceableStorageApplication) Information() (info service.BasicInformati info.Api.Protocol = service.ApiProtocols.INTERNAL.String() info.Api.Address = "" - info.Api.ApiList = []service.ApiInterface {} + info.Api.ApiList = []service.ApiInterface{} return } - func (t *TraceableStorageApplication) RequestsForBlock(_ block.Entity) (reqList []blockchainRequest.Entity, cnt uint32) { t.poolLock.Lock() defer t.poolLock.Unlock() @@ -199,7 +198,7 @@ func (t *TraceableStorageApplication) RequestsForBlock(_ block.Entity) (reqList Packed: true, PackedCount: cnt, - Seal: seal.Entity{ + Seal: seal.Entity{ Hash: txRoot, //use merkle tree root as seal hash for packed actions Signature: nil, SignerPublicKey: nil, @@ -210,13 +209,13 @@ func (t *TraceableStorageApplication) RequestsForBlock(_ block.Entity) (reqList return []blockchainRequest.Entity{packedReq}, 1 } -func Load() { +func Load() { tsLedger.Load() } func NewApplicationInterface(kvDriver kvDatabase.IDriver, sqlDriver simpleSQLDatabase.IDriver) (app chainStructure.IBlockchainExternalApplication) { ts := TraceableStorageApplication{ - reqList: []string {}, + reqList: []string{}, reqMap: map[string]blockchainRequest.Entity{}, poolLock: sync.RWMutex{}, poolLimit: 1000, @@ -226,4 +225,3 @@ func NewApplicationInterface(kvDriver kvDatabase.IDriver, sqlDriver simpleSQLDat app = &ts return } - diff --git a/service/application/traceableStorage/tsLedger/tsLedger.go b/service/application/traceableStorage/tsLedger/tsLedger.go index 491f84c..d2caa1f 100644 --- a/service/application/traceableStorage/tsLedger/tsLedger.go +++ b/service/application/traceableStorage/tsLedger/tsLedger.go @@ -28,7 +28,6 @@ import ( "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" ) - type tsServiceValidator func(data tsData.TSData) (err error) type tsServiceActuator func(data tsData.TSData) (ret interface{}, err error) type tsQuery func(param []string) (ret interface{}, err error) @@ -36,18 +35,18 @@ type tsQuery func(param []string) (ret interface{}, err error) type TSLedger struct { reqPool []tsData.TSServiceRequest - validators map[string] tsServiceValidator - actuators map[string] tsServiceActuator + validators map[string]tsServiceValidator + actuators map[string]tsServiceActuator - CryptoTools crypto.Tools - Storage kvDatabase.IDriver + CryptoTools crypto.Tools + Storage kvDatabase.IDriver } -func Load() { +func Load() { enum.SimpleBuild(&tsData.RequestTypes) } -func (t *TSLedger)VerifyRequest(req tsData.TSServiceRequest) (err error) { +func (t *TSLedger) VerifyRequest(req tsData.TSServiceRequest) (err error) { if validator, exists := t.validators[req.ReqType]; exists { return validator(req.Data) } else { @@ -55,7 +54,7 @@ func (t *TSLedger)VerifyRequest(req tsData.TSServiceRequest) (err error) { } } -func (t *TSLedger)ExecuteRequest(req tsData.TSServiceRequest) (ret interface{}, err error) { +func (t *TSLedger) ExecuteRequest(req tsData.TSServiceRequest) (ret interface{}, err error) { if actuator, exists := t.actuators[req.ReqType]; exists { return actuator(req.Data) } else { @@ -64,20 +63,20 @@ func (t *TSLedger)ExecuteRequest(req tsData.TSServiceRequest) (ret interface{}, } func NewTraceableStorage(kvDriver kvDatabase.IDriver, sqlDriver simpleSQLDatabase.IDriver) *TSLedger { - t := &TSLedger { + t := &TSLedger{ CryptoTools: crypto.Tools{ - HashCalculator: sha3.Sha256, - SignerGenerator: ed25519.SignerGenerator, + HashCalculator: sha3.Sha256, + SignerGenerator: ed25519.SignerGenerator, }, - Storage: kvDriver, + Storage: kvDriver, } - t.validators = map[string] tsServiceValidator { + t.validators = map[string]tsServiceValidator{ tsData.RequestTypes.Store.String(): t.VerifyStoreRequest, tsData.RequestTypes.Modify.String(): t.VerifyModifyRequest, } - t.actuators = map[string] tsServiceActuator { + t.actuators = map[string]tsServiceActuator{ tsData.RequestTypes.Store.String(): t.ExecuteStoreIdentification, tsData.RequestTypes.Modify.String(): t.ExecuteModifyIdentification, } diff --git a/service/application/traceableStorage/tsLedger/tsModify.go b/service/application/traceableStorage/tsLedger/tsModify.go index 4dadddc..1ca1034 100644 --- a/service/application/traceableStorage/tsLedger/tsModify.go +++ b/service/application/traceableStorage/tsLedger/tsModify.go @@ -40,7 +40,7 @@ func (t *TSLedger) GetLocalData(id string) (data tsData.TSData, err error) { return } -func (t *TSLedger)VerifyModifyRequest(data tsData.TSData) (err error) { +func (t *TSLedger) VerifyModifyRequest(data tsData.TSData) (err error) { //common verify _, err = t.commonDataInRequestVerify(data) if err != nil { @@ -61,7 +61,7 @@ func (t *TSLedger)VerifyModifyRequest(data tsData.TSData) (err error) { return } -func (t *TSLedger)ExecuteModifyIdentification(data tsData.TSData) (ret interface{}, err error) { +func (t *TSLedger) ExecuteModifyIdentification(data tsData.TSData) (ret interface{}, err error) { prevData, err := t.GetLocalData(data.PrevOnChainID) if err != nil { return diff --git a/service/application/traceableStorage/tsLedger/tsStore.go b/service/application/traceableStorage/tsLedger/tsStore.go index 776e336..d4df551 100644 --- a/service/application/traceableStorage/tsLedger/tsStore.go +++ b/service/application/traceableStorage/tsLedger/tsStore.go @@ -22,7 +22,7 @@ import ( "github.com/SealSC/SealABC/service/application/traceableStorage/tsData" ) -func (t *TSLedger)VerifyStoreRequest(data tsData.TSData) (err error) { +func (t *TSLedger) VerifyStoreRequest(data tsData.TSData) (err error) { //common verify _, err = t.commonDataInRequestVerify(data) if err != nil { @@ -41,7 +41,7 @@ func (t *TSLedger)VerifyStoreRequest(data tsData.TSData) (err error) { return nil } -func (t *TSLedger)ExecuteStoreIdentification(data tsData.TSData) (ret interface{}, err error) { +func (t *TSLedger) ExecuteStoreIdentification(data tsData.TSData) (ret interface{}, err error) { kvData := data.ToKVStoreItem() err = t.Storage.Put(kvData) return diff --git a/service/application/traceableStorage/tsLedger/tsVerify.go b/service/application/traceableStorage/tsLedger/tsVerify.go index afe1e7b..97383d6 100644 --- a/service/application/traceableStorage/tsLedger/tsVerify.go +++ b/service/application/traceableStorage/tsLedger/tsVerify.go @@ -55,4 +55,3 @@ func (t *TSLedger) commonDataInRequestVerify(data tsData.TSData) (passed bool, e return true, nil } - diff --git a/service/application/universalIdentification/service.go b/service/application/universalIdentification/service.go index e74c1e4..62e047c 100644 --- a/service/application/universalIdentification/service.go +++ b/service/application/universalIdentification/service.go @@ -45,4 +45,3 @@ func NewUniversalIdentificationApplication(config Config) (app chainStructure.IB return } - diff --git a/service/application/universalIdentification/uidData/actions.go b/service/application/universalIdentification/uidData/actions.go index 6748d65..734a1c3 100644 --- a/service/application/universalIdentification/uidData/actions.go +++ b/service/application/universalIdentification/uidData/actions.go @@ -23,8 +23,8 @@ import ( ) type UIDCreation struct { - UID UniversalIdentification - Seal seal.Entity + UID UniversalIdentification + Seal seal.Entity } type UIDAppendKeysData struct { @@ -65,7 +65,7 @@ type QueryResult struct { UIDList []UniversalIdentification } -var UIDActionTypes struct{ +var UIDActionTypes struct { Create enum.Element Append enum.Element Update enum.Element diff --git a/service/application/universalIdentification/uidInterface/uidInterface.go b/service/application/universalIdentification/uidInterface/uidInterface.go index 1f80cb9..c030587 100644 --- a/service/application/universalIdentification/uidInterface/uidInterface.go +++ b/service/application/universalIdentification/uidInterface/uidInterface.go @@ -40,8 +40,8 @@ type ActionList struct { type UniversalIdentificationApplication struct { chainStructure.BlankApplication - reqPool map[string] blockchainRequest.Entity - reqList [] blockchainRequest.Entity + reqPool map[string]blockchainRequest.Entity + reqList []blockchainRequest.Entity poolLock sync.Mutex @@ -184,7 +184,7 @@ func (u *UniversalIdentificationApplication) RequestsForBlock(_ block.Entity) (r Packed: true, PackedCount: cnt, - Seal: seal.Entity{ + Seal: seal.Entity{ Hash: txRoot, //use merkle tree root as seal hash for packed actions Signature: nil, SignerPublicKey: nil, @@ -202,11 +202,11 @@ func (u *UniversalIdentificationApplication) Information() (info service.BasicIn info.Api.Protocol = service.ApiProtocols.INTERNAL.String() info.Api.Address = "" - info.Api.ApiList = []service.ApiInterface {} + info.Api.ApiList = []service.ApiInterface{} return } -func Load() {} +func Load() {} func NewApplicationInterface(kvDriver kvDatabase.IDriver, sqlDriver simpleSQLDatabase.IDriver) (app chainStructure.IBlockchainExternalApplication) { uidApp := UniversalIdentificationApplication{} diff --git a/service/application/universalIdentification/uidLedger/operationForAppendUIDKeys.go b/service/application/universalIdentification/uidLedger/operationForAppendUIDKeys.go index e1ee4c3..ddd6a5e 100644 --- a/service/application/universalIdentification/uidLedger/operationForAppendUIDKeys.go +++ b/service/application/universalIdentification/uidLedger/operationForAppendUIDKeys.go @@ -25,7 +25,7 @@ import ( "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" ) -func (u *UIDLedger) verifyUIDKeysAppend(reqData []byte) (ret interface{}, err error){ +func (u *UIDLedger) verifyUIDKeysAppend(reqData []byte) (ret interface{}, err error) { actionData := uidData.UIDAppendKeys{} err = json.Unmarshal(reqData, &actionData) if err != nil { @@ -47,13 +47,11 @@ func (u *UIDLedger) verifyUIDKeysAppend(reqData []byte) (ret interface{}, err er return nil, errors.New("invalid signature of append: " + err.Error()) } - for _, newKey := range actionData.Keys { if newKey.KeyType == uidData.UIDKeyTypes.OracleProof.Int() { return nil, errors.New("type of oracle proof key was not supported for now") } - if len(newKey.KeyProof) != 0 { return nil, errors.New("self proof was in seal field, key proof field must be empty") } @@ -73,7 +71,7 @@ func (u *UIDLedger) verifyUIDKeysAppend(reqData []byte) (ret interface{}, err er return nil, nil } -func (u* UIDLedger) appendUIDKeys(reqData []byte) (err error) { +func (u *UIDLedger) appendUIDKeys(reqData []byte) (err error) { actionData := uidData.UIDAppendKeys{} _ = json.Unmarshal(reqData, &actionData) @@ -86,7 +84,7 @@ func (u* UIDLedger) appendUIDKeys(reqData []byte) (err error) { newData, _ := json.Marshal(&uid) - _ = u.KVStorage.Put(kvDatabase.KVItem { + _ = u.KVStorage.Put(kvDatabase.KVItem{ Key: []byte(uid.Identification), Data: newData, Exists: true, diff --git a/service/application/universalIdentification/uidLedger/operationForCreateUID.go b/service/application/universalIdentification/uidLedger/operationForCreateUID.go index bb8f4d3..00db5d8 100644 --- a/service/application/universalIdentification/uidLedger/operationForCreateUID.go +++ b/service/application/universalIdentification/uidLedger/operationForCreateUID.go @@ -25,7 +25,7 @@ import ( "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" ) -func (u *UIDLedger) verifyUIDCreation(reqData []byte) (ret interface{}, err error){ +func (u *UIDLedger) verifyUIDCreation(reqData []byte) (ret interface{}, err error) { actionData := uidData.UIDCreation{} err = json.Unmarshal(reqData, &actionData) if err != nil { @@ -73,7 +73,7 @@ func (u *UIDLedger) verifyUIDCreation(reqData []byte) (ret interface{}, err erro return nil, nil } -func (u* UIDLedger) createUID(reqData []byte) (err error) { +func (u *UIDLedger) createUID(reqData []byte) (err error) { actionData := uidData.UIDCreation{} _ = json.Unmarshal(reqData, &actionData) diff --git a/service/application/universalIdentification/uidLedger/operationForQueryUID.go b/service/application/universalIdentification/uidLedger/operationForQueryUID.go index 289a250..efd5ffa 100644 --- a/service/application/universalIdentification/uidLedger/operationForQueryUID.go +++ b/service/application/universalIdentification/uidLedger/operationForQueryUID.go @@ -22,7 +22,7 @@ import ( "github.com/SealSC/SealABC/service/application/universalIdentification/uidData" ) -func (u *UIDLedger)QueryUID(queryData uidData.UIDQuery) (ret uidData.QueryResult, err error){ +func (u *UIDLedger) QueryUID(queryData uidData.UIDQuery) (ret uidData.QueryResult, err error) { identification := u.calcIdentification(queryData.PublicKey, queryData.Namespace) dataList := u.KVStorage.Traversal([]byte(identification)) diff --git a/service/application/universalIdentification/uidLedger/operationForUpdateUID.go b/service/application/universalIdentification/uidLedger/operationForUpdateUID.go index b028cb5..ace6358 100644 --- a/service/application/universalIdentification/uidLedger/operationForUpdateUID.go +++ b/service/application/universalIdentification/uidLedger/operationForUpdateUID.go @@ -25,7 +25,7 @@ import ( "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" ) -func (u *UIDLedger) verifyUIDKeysUpdate(reqData []byte) (ret interface{}, err error){ +func (u *UIDLedger) verifyUIDKeysUpdate(reqData []byte) (ret interface{}, err error) { actionData := uidData.UIDUpdateKeys{} err = json.Unmarshal(reqData, &actionData) if err != nil { @@ -55,7 +55,6 @@ func (u *UIDLedger) verifyUIDKeysUpdate(reqData []byte) (ret interface{}, err er return nil, errors.New("type of oracle proof key was not supported for now") } - if len(newKey.KeyProof) != 0 { return nil, errors.New("self proof was in seal field, key proof field must be empty") } @@ -77,7 +76,7 @@ func (u *UIDLedger) verifyUIDKeysUpdate(reqData []byte) (ret interface{}, err er return nil, nil } -func (u* UIDLedger) updateUIDKeys(reqData []byte) (err error) { +func (u *UIDLedger) updateUIDKeys(reqData []byte) (err error) { actionData := uidData.UIDUpdateKeys{} _ = json.Unmarshal(reqData, &actionData) @@ -92,7 +91,7 @@ func (u* UIDLedger) updateUIDKeys(reqData []byte) (err error) { newData, _ := json.Marshal(&uid) - _ = u.KVStorage.Put(kvDatabase.KVItem { + _ = u.KVStorage.Put(kvDatabase.KVItem{ Key: []byte(uid.Identification), Data: newData, Exists: true, diff --git a/service/application/universalIdentification/uidLedger/uidLedger.go b/service/application/universalIdentification/uidLedger/uidLedger.go index b7fa841..2b2ae3d 100644 --- a/service/application/universalIdentification/uidLedger/uidLedger.go +++ b/service/application/universalIdentification/uidLedger/uidLedger.go @@ -26,7 +26,7 @@ import ( "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" ) -func Load() { +func Load() { enum.SimpleBuild(&uidData.UIDKeyTypes) enum.SimpleBuild(&uidData.UIDActionTypes) } @@ -34,13 +34,13 @@ func Load() { func NewLedger(kvDriver kvDatabase.IDriver, sqlDriver simpleSQLDatabase.IDriver) (ledger UIDLedger) { ledger.KVStorage = kvDriver - ledger.validators = map[string]actionValidator { + ledger.validators = map[string]actionValidator{ uidData.UIDActionTypes.Create.String(): ledger.verifyUIDCreation, uidData.UIDActionTypes.Append.String(): ledger.verifyUIDKeysAppend, uidData.UIDActionTypes.Update.String(): ledger.verifyUIDKeysUpdate, } - ledger.executors = map[string]actionExecutor { + ledger.executors = map[string]actionExecutor{ uidData.UIDActionTypes.Create.String(): ledger.createUID, uidData.UIDActionTypes.Append.String(): ledger.appendUIDKeys, uidData.UIDActionTypes.Update.String(): ledger.updateUIDKeys, @@ -53,14 +53,14 @@ type actionValidator func(actData []byte) (ret interface{}, err error) type actionExecutor func(actData []byte) (err error) type UIDLedger struct { - validators map[string] actionValidator - executors map[string] actionExecutor + validators map[string]actionValidator + executors map[string]actionExecutor CryptoTools crypto.Tools KVStorage kvDatabase.IDriver } -func (u *UIDLedger) VerifyAction(action string, data []byte) (ret interface{}, err error){ +func (u *UIDLedger) VerifyAction(action string, data []byte) (ret interface{}, err error) { if validate, exists := u.validators[action]; exists { return validate(data) } @@ -68,7 +68,7 @@ func (u *UIDLedger) VerifyAction(action string, data []byte) (ret interface{}, e return nil, errors.New("action not supported") } -func (u *UIDLedger) ExecuteAction(action string, data []byte) (err error) { +func (u *UIDLedger) ExecuteAction(action string, data []byte) (err error) { if executor, exists := u.executors[action]; exists { return executor(data) } diff --git a/service/system/blockchain/chainApi/api.go b/service/system/blockchain/chainApi/api.go index 32aab02..6dd5e28 100644 --- a/service/system/blockchain/chainApi/api.go +++ b/service/system/blockchain/chainApi/api.go @@ -18,26 +18,26 @@ package chainApi import ( - "github.com/SealSC/SealABC/service/system/blockchain/chainApi/httpJSON" - "github.com/SealSC/SealABC/service/system/blockchain/chainApi/httpJSON/actions" - "github.com/SealSC/SealABC/service/system/blockchain/chainSQLStorage" - "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/service/system/blockchain/chainNetwork" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/service/system/blockchain/chainApi/httpJSON" + "github.com/SealSC/SealABC/service/system/blockchain/chainApi/httpJSON/actions" + "github.com/SealSC/SealABC/service/system/blockchain/chainNetwork" + "github.com/SealSC/SealABC/service/system/blockchain/chainSQLStorage" + "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" ) type ApiServers struct { - HttpJSON *httpJSON.ApiServer + HttpJSON *httpJSON.ApiServer } -func Load() { - enum.SimpleBuild(&actions.URLParameterKeys) +func Load() { + enum.SimpleBuild(&actions.URLParameterKeys) } func NewServer(cfg Config, chain *chainStructure.Blockchain, p2p *chainNetwork.P2PService, sqlStorage *chainSQLStorage.Storage) *ApiServers { - api := ApiServers{} + api := ApiServers{} - api.HttpJSON = httpJSON.NewApiServer(cfg.HttpJSON, chain, p2p, sqlStorage) + api.HttpJSON = httpJSON.NewApiServer(cfg.HttpJSON, chain, p2p, sqlStorage) - return &api + return &api } diff --git a/service/system/blockchain/chainApi/config.go b/service/system/blockchain/chainApi/config.go index d92b537..81af9b6 100644 --- a/service/system/blockchain/chainApi/config.go +++ b/service/system/blockchain/chainApi/config.go @@ -18,9 +18,9 @@ package chainApi import ( - "github.com/SealSC/SealABC/network/http" + "github.com/SealSC/SealABC/network/http" ) type Config struct { - HttpJSON http.Config + HttpJSON http.Config } diff --git a/service/system/blockchain/chainApi/httpJSON/actions/actions.go b/service/system/blockchain/chainApi/httpJSON/actions/actions.go index 09a0048..04b499e 100644 --- a/service/system/blockchain/chainApi/httpJSON/actions/actions.go +++ b/service/system/blockchain/chainApi/httpJSON/actions/actions.go @@ -18,144 +18,144 @@ package actions import ( - "github.com/SealSC/SealABC/network/http" - "github.com/SealSC/SealABC/service" - "github.com/SealSC/SealABC/service/system/blockchain/chainSQLStorage" - "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" - "github.com/gin-gonic/gin" - "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/service/system/blockchain/chainNetwork" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/network/http" + "github.com/SealSC/SealABC/service" + "github.com/SealSC/SealABC/service/system/blockchain/chainNetwork" + "github.com/SealSC/SealABC/service/system/blockchain/chainSQLStorage" + "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" + "github.com/gin-gonic/gin" ) var URLParameterKeys = struct { - HexHash enum.Element - Height enum.Element + HexHash enum.Element + Height enum.Element - Page enum.Element - Count enum.Element + Page enum.Element + Count enum.Element - App enum.Element - Action enum.Element + App enum.Element + Action enum.Element - Type enum.Element - Param enum.Element + Type enum.Element + Param enum.Element }{} type apiHandler interface { - http.IRequestHandler - buildUrlPath() string - setServerInfo(basePath string, - chain *chainStructure.Blockchain, - p2p *chainNetwork.P2PService, - sqlStorage *chainSQLStorage.Storage, - queryHandler map[string] applicationQueryHandler) + http.IRequestHandler + buildUrlPath() string + setServerInfo(basePath string, + chain *chainStructure.Blockchain, + p2p *chainNetwork.P2PService, + sqlStorage *chainSQLStorage.Storage, + queryHandler map[string]applicationQueryHandler) } type baseHandler struct { - serverBasePath string - chain *chainStructure.Blockchain - p2p *chainNetwork.P2PService - sqlStorage *chainSQLStorage.Storage - appQueryHandler map[string] applicationQueryHandler + serverBasePath string + chain *chainStructure.Blockchain + p2p *chainNetwork.P2PService + sqlStorage *chainSQLStorage.Storage + appQueryHandler map[string]applicationQueryHandler } func (b *baseHandler) setServerInfo(basePath string, - chain *chainStructure.Blockchain, - p2p *chainNetwork.P2PService, - sqlStorage *chainSQLStorage.Storage, - queryHandler map[string] applicationQueryHandler) { - - b.serverBasePath = basePath - b.chain = chain - b.p2p = p2p - b.sqlStorage = sqlStorage - b.appQueryHandler = queryHandler + chain *chainStructure.Blockchain, + p2p *chainNetwork.P2PService, + sqlStorage *chainSQLStorage.Storage, + queryHandler map[string]applicationQueryHandler) { + + b.serverBasePath = basePath + b.chain = chain + b.p2p = p2p + b.sqlStorage = sqlStorage + b.appQueryHandler = queryHandler } type applicationQueryHandler func([]byte) (interface{}, error) type ChainApiActions struct { - serverBase string - actionList []apiHandler - appQueryHandler map[string] applicationQueryHandler + serverBase string + actionList []apiHandler + appQueryHandler map[string]applicationQueryHandler - chain *chainStructure.Blockchain - p2p *chainNetwork.P2PService + chain *chainStructure.Blockchain + p2p *chainNetwork.P2PService - apiInformation []service.ApiInterface - sqlStorage *chainSQLStorage.Storage + apiInformation []service.ApiInterface + sqlStorage *chainSQLStorage.Storage } func (c *ChainApiActions) RouteRegister(router gin.IRouter) { - c.serverBase = "/api/v1" - gr := router.Group(c.serverBase) - { - for _, h := range c.actionList { - h.setServerInfo(c.serverBase, c.chain, c.p2p, c.sqlStorage, c.appQueryHandler) - h.RouteRegister(gr) - } - } + c.serverBase = "/api/v1" + gr := router.Group(c.serverBase) + { + for _, h := range c.actionList { + h.setServerInfo(c.serverBase, c.chain, c.p2p, c.sqlStorage, c.appQueryHandler) + h.RouteRegister(gr) + } + } } func (c *ChainApiActions) BasicInformation() (info http.HandlerBasicInformation) { - log.Log.Println("this is placeholder for BasicInformation method.") - return + log.Log.Println("this is placeholder for BasicInformation method.") + return } func (c *ChainApiActions) Handle(_ *gin.Context) { - log.Log.Println("this is placeholder for Handle method.") - return + log.Log.Println("this is placeholder for Handle method.") + return } func NewActions(basePath string, chain *chainStructure.Blockchain, p2p *chainNetwork.P2PService, sqlStorage *chainSQLStorage.Storage) *ChainApiActions { - action := ChainApiActions{} - - action.serverBase = basePath - action.chain = chain - action.p2p = p2p - action.sqlStorage = sqlStorage - - action.actionList = []apiHandler { - &callApplication{}, - &getBlockByHash{}, - &getBlockByHeight{}, - &getTransactions{}, - &queryApplication{}, - } - action.appQueryHandler = map[string] applicationQueryHandler {} - - if sqlStorage != nil { - action.actionList = append(action.actionList, - &getBlockList{}, - &getTransactionByHash{}, - &getTransactionByApplicationAndAction{}, - &getAddressList{}, - &getTransactionByHeight{}) - } - - return &action + action := ChainApiActions{} + + action.serverBase = basePath + action.chain = chain + action.p2p = p2p + action.sqlStorage = sqlStorage + + action.actionList = []apiHandler{ + &callApplication{}, + &getBlockByHash{}, + &getBlockByHeight{}, + &getTransactions{}, + &queryApplication{}, + } + action.appQueryHandler = map[string]applicationQueryHandler{} + + if sqlStorage != nil { + action.actionList = append(action.actionList, + &getBlockList{}, + &getTransactionByHash{}, + &getTransactionByApplicationAndAction{}, + &getAddressList{}, + &getTransactionByHeight{}) + } + + return &action } -func (c *ChainApiActions) RegisterApplicationQueryHandler(exeName string, handler applicationQueryHandler) { - c.appQueryHandler[exeName] = handler +func (c *ChainApiActions) RegisterApplicationQueryHandler(exeName string, handler applicationQueryHandler) { + c.appQueryHandler[exeName] = handler } -func (c *ChainApiActions)Information() []service.ApiInterface { - if len(c.apiInformation) != 0 { - return c.apiInformation - } +func (c *ChainApiActions) Information() []service.ApiInterface { + if len(c.apiInformation) != 0 { + return c.apiInformation + } - for _, act := range c.actionList { - actInfo := act.BasicInformation() - ai := service.ApiInterface{} + for _, act := range c.actionList { + actInfo := act.BasicInformation() + ai := service.ApiInterface{} - ai.Description = actInfo.Description - ai.Path = actInfo.Path - ai.Method = actInfo.Method - ai.Parameters = (service.Parameters)(actInfo.Parameters) + ai.Description = actInfo.Description + ai.Path = actInfo.Path + ai.Method = actInfo.Method + ai.Parameters = (service.Parameters)(actInfo.Parameters) - c.apiInformation = append(c.apiInformation, ai) - } + c.apiInformation = append(c.apiInformation, ai) + } - return c.apiInformation + return c.apiInformation } diff --git a/service/system/blockchain/chainApi/httpJSON/actions/callApplication.go b/service/system/blockchain/chainApi/httpJSON/actions/callApplication.go index 0762580..a2bb5af 100644 --- a/service/system/blockchain/chainApi/httpJSON/actions/callApplication.go +++ b/service/system/blockchain/chainApi/httpJSON/actions/callApplication.go @@ -18,56 +18,56 @@ package actions import ( - "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/metadata/blockchainRequest" - "github.com/SealSC/SealABC/network/http" - "github.com/SealSC/SealABC/service" - "github.com/gin-gonic/gin" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/metadata/blockchainRequest" + "github.com/SealSC/SealABC/network/http" + "github.com/SealSC/SealABC/service" + "github.com/gin-gonic/gin" ) -type callApplication struct{ - baseHandler +type callApplication struct { + baseHandler } -func (c *callApplication)Handle(ctx *gin.Context) { - res := http.NewResponse(ctx) +func (c *callApplication) Handle(ctx *gin.Context) { + res := http.NewResponse(ctx) - reqData := blockchainRequest.Entity{} - _, err := http.GetPostedJson(ctx, &reqData) - if err != nil { - res.BadRequest( "request error: " + err.Error()) - return - } + reqData := blockchainRequest.Entity{} + _, err := http.GetPostedJson(ctx, &reqData) + if err != nil { + res.BadRequest("request error: " + err.Error()) + return + } - result, err := c.chain.Executor.PushRequest(reqData) + result, err := c.chain.Executor.PushRequest(reqData) - if err != nil { - res.BadRequest("call application error: " + err.Error()) - return - } + if err != nil { + res.BadRequest("call application error: " + err.Error()) + return + } - broadcastErr := c.p2p.BroadcastRequest(reqData) - if broadcastErr != nil{ - log.Log.Warn("broadcast request failed: ", broadcastErr) - } - res.OK(result) + broadcastErr := c.p2p.BroadcastRequest(reqData) + if broadcastErr != nil { + log.Log.Warn("broadcast request failed: ", broadcastErr) + } + res.OK(result) } -func (c *callApplication) RouteRegister(router gin.IRouter) { - router.POST(c.buildUrlPath(), c.Handle) +func (c *callApplication) RouteRegister(router gin.IRouter) { + router.POST(c.buildUrlPath(), c.Handle) } -func (c *callApplication)BasicInformation() (info http.HandlerBasicInformation) { +func (c *callApplication) BasicInformation() (info http.HandlerBasicInformation) { - info.Description = "will call application that registered on the blockchain." - info.Path = c.serverBasePath + c.buildUrlPath() - info.Method = service.ApiProtocolMethod.HttpPost.String() + info.Description = "will call application that registered on the blockchain." + info.Path = c.serverBasePath + c.buildUrlPath() + info.Method = service.ApiProtocolMethod.HttpPost.String() - info.Parameters.Type = service.ApiParameterType.JSON.String() - info.Parameters.Template = blockchainRequest.Entity{} - return + info.Parameters.Type = service.ApiParameterType.JSON.String() + info.Parameters.Template = blockchainRequest.Entity{} + return } func (c *callApplication) buildUrlPath() string { - return "/call/application" + return "/call/application" } diff --git a/service/system/blockchain/chainApi/httpJSON/actions/getAddressList.go b/service/system/blockchain/chainApi/httpJSON/actions/getAddressList.go index 1b7978f..6068915 100644 --- a/service/system/blockchain/chainApi/httpJSON/actions/getAddressList.go +++ b/service/system/blockchain/chainApi/httpJSON/actions/getAddressList.go @@ -18,17 +18,17 @@ package actions import ( - "github.com/gin-gonic/gin" "github.com/SealSC/SealABC/network/http" "github.com/SealSC/SealABC/service" + "github.com/gin-gonic/gin" "strconv" ) -type getAddressList struct{ +type getAddressList struct { baseHandler } -func (g *getAddressList)Handle(ctx *gin.Context) { +func (g *getAddressList) Handle(ctx *gin.Context) { res := http.NewResponse(ctx) pageString := ctx.Param(URLParameterKeys.Page.String()) @@ -46,11 +46,11 @@ func (g *getAddressList)Handle(ctx *gin.Context) { res.OK(list) } -func (g *getAddressList)RouteRegister(router gin.IRouter) { +func (g *getAddressList) RouteRegister(router gin.IRouter) { router.GET(g.buildUrlPath(), g.Handle) } -func (g *getAddressList)BasicInformation() (info http.HandlerBasicInformation) { +func (g *getAddressList) BasicInformation() (info http.HandlerBasicInformation) { info.Description = "return address list in blockchain layer." info.Path = g.serverBasePath + g.buildUrlPath() info.Method = service.ApiProtocolMethod.HttpGet.String() @@ -67,4 +67,3 @@ func (g *getAddressList) urlWithoutParameters() string { func (g *getAddressList) buildUrlPath() string { return g.urlWithoutParameters() + "/:" + URLParameterKeys.Page.String() } - diff --git a/service/system/blockchain/chainApi/httpJSON/actions/getBlockByHash.go b/service/system/blockchain/chainApi/httpJSON/actions/getBlockByHash.go index 8894fee..cdf1df4 100644 --- a/service/system/blockchain/chainApi/httpJSON/actions/getBlockByHash.go +++ b/service/system/blockchain/chainApi/httpJSON/actions/getBlockByHash.go @@ -18,47 +18,45 @@ package actions import ( - "github.com/SealSC/SealABC/network/http" - "github.com/SealSC/SealABC/service" - "github.com/gin-gonic/gin" + "github.com/SealSC/SealABC/network/http" + "github.com/SealSC/SealABC/service" + "github.com/gin-gonic/gin" ) -type getBlockByHash struct{ - baseHandler +type getBlockByHash struct { + baseHandler } -func (g *getBlockByHash)Handle(ctx *gin.Context) { - res := http.NewResponse(ctx) - hash := ctx.Param(URLParameterKeys.HexHash.String()) - blk, err := g.chain.GetBlockRowByHash(hash) - if err != nil { - res.BadRequest(err.Error()) - return - } +func (g *getBlockByHash) Handle(ctx *gin.Context) { + res := http.NewResponse(ctx) + hash := ctx.Param(URLParameterKeys.HexHash.String()) + blk, err := g.chain.GetBlockRowByHash(hash) + if err != nil { + res.BadRequest(err.Error()) + return + } - res.OK(blk) + res.OK(blk) } -func (g *getBlockByHash)RouteRegister(router gin.IRouter) { - router.GET(g.buildUrlPath(), g.Handle) +func (g *getBlockByHash) RouteRegister(router gin.IRouter) { + router.GET(g.buildUrlPath(), g.Handle) } -func (g *getBlockByHash)BasicInformation() (info http.HandlerBasicInformation) { - info.Description = "return full block data of the given block hash." - info.Path = g.serverBasePath + g.buildUrlPath() - info.Method = service.ApiProtocolMethod.HttpGet.String() +func (g *getBlockByHash) BasicInformation() (info http.HandlerBasicInformation) { + info.Description = "return full block data of the given block hash." + info.Path = g.serverBasePath + g.buildUrlPath() + info.Method = service.ApiProtocolMethod.HttpGet.String() - info.Parameters.Type = service.ApiParameterType.URL.String() - info.Parameters.Template = g.serverBasePath + g.urlWithoutParameters() + "/1ae9d62bea40f591af7ab6e03e077d85adb33a66cd977e913763a303599c5440" - return + info.Parameters.Type = service.ApiParameterType.URL.String() + info.Parameters.Template = g.serverBasePath + g.urlWithoutParameters() + "/1ae9d62bea40f591af7ab6e03e077d85adb33a66cd977e913763a303599c5440" + return } - -func (g *getBlockByHash) urlWithoutParameters() string { - return "/get/block/by/hash" +func (g *getBlockByHash) urlWithoutParameters() string { + return "/get/block/by/hash" } func (g *getBlockByHash) buildUrlPath() string { - return g.urlWithoutParameters() + "/:" + URLParameterKeys.HexHash.String() + return g.urlWithoutParameters() + "/:" + URLParameterKeys.HexHash.String() } - diff --git a/service/system/blockchain/chainApi/httpJSON/actions/getBlockByHeight.go b/service/system/blockchain/chainApi/httpJSON/actions/getBlockByHeight.go index 32343f2..8efd75d 100644 --- a/service/system/blockchain/chainApi/httpJSON/actions/getBlockByHeight.go +++ b/service/system/blockchain/chainApi/httpJSON/actions/getBlockByHeight.go @@ -18,53 +18,52 @@ package actions import ( - "github.com/gin-gonic/gin" - "github.com/SealSC/SealABC/network/http" - "github.com/SealSC/SealABC/service" - "strconv" + "github.com/SealSC/SealABC/network/http" + "github.com/SealSC/SealABC/service" + "github.com/gin-gonic/gin" + "strconv" ) -type getBlockByHeight struct{ - baseHandler +type getBlockByHeight struct { + baseHandler } -func (g *getBlockByHeight)Handle(ctx *gin.Context) { - res := http.NewResponse(ctx) - heightString := ctx.Param(URLParameterKeys.Height.String()) +func (g *getBlockByHeight) Handle(ctx *gin.Context) { + res := http.NewResponse(ctx) + heightString := ctx.Param(URLParameterKeys.Height.String()) - height, err := strconv.ParseUint(heightString, 10, 64) - if err != nil { - res.BadRequest("parameter [height] is not a number") - return - } + height, err := strconv.ParseUint(heightString, 10, 64) + if err != nil { + res.BadRequest("parameter [height] is not a number") + return + } - blk, err := g.chain.GetBlockRowByHeight(height) - if err != nil { - return - } + blk, err := g.chain.GetBlockRowByHeight(height) + if err != nil { + return + } - res.OK(blk) + res.OK(blk) } -func (g *getBlockByHeight)RouteRegister(router gin.IRouter) { - router.GET(g.buildUrlPath(), g.Handle) +func (g *getBlockByHeight) RouteRegister(router gin.IRouter) { + router.GET(g.buildUrlPath(), g.Handle) } -func (g *getBlockByHeight)BasicInformation() (info http.HandlerBasicInformation) { - info.Description = "return full block data of the given block height." - info.Path = g.serverBasePath + g.buildUrlPath() - info.Method = service.ApiProtocolMethod.HttpGet.String() +func (g *getBlockByHeight) BasicInformation() (info http.HandlerBasicInformation) { + info.Description = "return full block data of the given block height." + info.Path = g.serverBasePath + g.buildUrlPath() + info.Method = service.ApiProtocolMethod.HttpGet.String() - info.Parameters.Type = service.ApiParameterType.URL.String() - info.Parameters.Template = g.serverBasePath + g.urlWithoutParameters() + "/1" - return + info.Parameters.Type = service.ApiParameterType.URL.String() + info.Parameters.Template = g.serverBasePath + g.urlWithoutParameters() + "/1" + return } func (g *getBlockByHeight) urlWithoutParameters() string { - return "/get/block/by/height" + return "/get/block/by/height" } func (g *getBlockByHeight) buildUrlPath() string { - return g.urlWithoutParameters() + "/:" + URLParameterKeys.Height.String() + return g.urlWithoutParameters() + "/:" + URLParameterKeys.Height.String() } - diff --git a/service/system/blockchain/chainApi/httpJSON/actions/getBlockList.go b/service/system/blockchain/chainApi/httpJSON/actions/getBlockList.go index 86aaa05..34514d7 100644 --- a/service/system/blockchain/chainApi/httpJSON/actions/getBlockList.go +++ b/service/system/blockchain/chainApi/httpJSON/actions/getBlockList.go @@ -18,88 +18,88 @@ package actions import ( - "github.com/SealSC/SealABC/network/http" - "github.com/SealSC/SealABC/service" - "github.com/SealSC/SealABC/service/system/blockchain/chainTables" - "errors" - "github.com/gin-gonic/gin" - "strconv" + "errors" + "github.com/SealSC/SealABC/network/http" + "github.com/SealSC/SealABC/service" + "github.com/SealSC/SealABC/service/system/blockchain/chainTables" + "github.com/gin-gonic/gin" + "strconv" ) -type getBlockList struct{ - baseHandler +type getBlockList struct { + baseHandler } type getBlockListResult struct { - Blocks []chainTables.BlockListRow - CurrentHeight uint64 + Blocks []chainTables.BlockListRow + CurrentHeight uint64 } -func (g *getBlockList)getStartHeight(pageString string, countInPage uint64) (startHeight uint64, currentHeight uint64, err error) { - currentHeight = g.chain.CurrentHeight() - if pageString == "last" { - startHeight = 0 - return - } - - page, err := strconv.ParseUint(pageString, 10, 64) - if err != nil { - err = errors.New("parameter [page] is not valid") - return - } - - heightOffset := ((page + 1) * countInPage) - 1 - if heightOffset >= currentHeight { - startHeight = 0 - return - } - - startHeight = currentHeight - heightOffset - return +func (g *getBlockList) getStartHeight(pageString string, countInPage uint64) (startHeight uint64, currentHeight uint64, err error) { + currentHeight = g.chain.CurrentHeight() + if pageString == "last" { + startHeight = 0 + return + } + + page, err := strconv.ParseUint(pageString, 10, 64) + if err != nil { + err = errors.New("parameter [page] is not valid") + return + } + + heightOffset := ((page + 1) * countInPage) - 1 + if heightOffset >= currentHeight { + startHeight = 0 + return + } + + startHeight = currentHeight - heightOffset + return } -func (g *getBlockList)Handle(ctx *gin.Context) { - res := http.NewResponse(ctx) - pageString := ctx.Param(URLParameterKeys.Page.String()) +func (g *getBlockList) Handle(ctx *gin.Context) { + res := http.NewResponse(ctx) + pageString := ctx.Param(URLParameterKeys.Page.String()) - const countInPage = 20 + const countInPage = 20 - startHeight, currentHeight, err := g.getStartHeight(pageString, countInPage) - if err != nil { - res.BadRequest(err.Error()) - return - } + startHeight, currentHeight, err := g.getStartHeight(pageString, countInPage) + if err != nil { + res.BadRequest(err.Error()) + return + } - blkList, err := g.sqlStorage.GetBlockList(startHeight) - if err != nil { - res.InternalServerError(err.Error()) - return - } + blkList, err := g.sqlStorage.GetBlockList(startHeight) + if err != nil { + res.InternalServerError(err.Error()) + return + } - res.OK(getBlockListResult{ - Blocks: blkList, - CurrentHeight: currentHeight, - }) + res.OK(getBlockListResult{ + Blocks: blkList, + CurrentHeight: currentHeight, + }) } -func (g *getBlockList)RouteRegister(router gin.IRouter) { - router.GET(g.buildUrlPath(), g.Handle) +func (g *getBlockList) RouteRegister(router gin.IRouter) { + router.GET(g.buildUrlPath(), g.Handle) } -func (g *getBlockList)BasicInformation() (info http.HandlerBasicInformation) { - info.Description = "return block data list." - info.Path = g.serverBasePath + g.buildUrlPath() - info.Method = service.ApiProtocolMethod.HttpGet.String() +func (g *getBlockList) BasicInformation() (info http.HandlerBasicInformation) { + info.Description = "return block data list." + info.Path = g.serverBasePath + g.buildUrlPath() + info.Method = service.ApiProtocolMethod.HttpGet.String() - info.Parameters.Type = service.ApiParameterType.URL.String() - info.Parameters.Template = g.serverBasePath + g.urlWithoutParameters() + "/1" - return + info.Parameters.Type = service.ApiParameterType.URL.String() + info.Parameters.Template = g.serverBasePath + g.urlWithoutParameters() + "/1" + return } func (g *getBlockList) urlWithoutParameters() string { - return "/get/block/list/page/" + return "/get/block/list/page/" } func (g *getBlockList) buildUrlPath() string { - return g.urlWithoutParameters() + "/:" + URLParameterKeys.Page.String() + return g.urlWithoutParameters() + "/:" + URLParameterKeys.Page.String() } diff --git a/service/system/blockchain/chainApi/httpJSON/actions/getRequestByApplicationAndAction.go b/service/system/blockchain/chainApi/httpJSON/actions/getRequestByApplicationAndAction.go index 791669b..75364f5 100644 --- a/service/system/blockchain/chainApi/httpJSON/actions/getRequestByApplicationAndAction.go +++ b/service/system/blockchain/chainApi/httpJSON/actions/getRequestByApplicationAndAction.go @@ -24,11 +24,11 @@ import ( "strconv" ) -type getTransactionByApplicationAndAction struct{ +type getTransactionByApplicationAndAction struct { baseHandler } -func (g *getTransactionByApplicationAndAction)Handle(ctx *gin.Context) { +func (g *getTransactionByApplicationAndAction) Handle(ctx *gin.Context) { res := http.NewResponse(ctx) app := ctx.Param(URLParameterKeys.App.String()) act := ctx.Param(URLParameterKeys.Action.String()) @@ -49,11 +49,11 @@ func (g *getTransactionByApplicationAndAction)Handle(ctx *gin.Context) { res.OK(txList) } -func (g *getTransactionByApplicationAndAction)RouteRegister(router gin.IRouter) { +func (g *getTransactionByApplicationAndAction) RouteRegister(router gin.IRouter) { router.GET(g.buildUrlPath(), g.Handle) } -func (g *getTransactionByApplicationAndAction)BasicInformation() (info http.HandlerBasicInformation) { +func (g *getTransactionByApplicationAndAction) BasicInformation() (info http.HandlerBasicInformation) { info.Description = "return full block data of the given block hash." info.Path = g.serverBasePath + g.buildUrlPath() info.Method = service.ApiProtocolMethod.HttpGet.String() @@ -63,15 +63,13 @@ func (g *getTransactionByApplicationAndAction)BasicInformation() (info http.Hand return } -func (g *getTransactionByApplicationAndAction) urlWithoutParameters() string { +func (g *getTransactionByApplicationAndAction) urlWithoutParameters() string { return "/get/request/by/application/" } - func (g *getTransactionByApplicationAndAction) buildUrlPath() string { return g.urlWithoutParameters() + "/:" + URLParameterKeys.App.String() + "/:" + URLParameterKeys.Action.String() + "/:" + URLParameterKeys.Page.String() } - diff --git a/service/system/blockchain/chainApi/httpJSON/actions/getRequestByHash.go b/service/system/blockchain/chainApi/httpJSON/actions/getRequestByHash.go index 241e1c0..b753d4d 100644 --- a/service/system/blockchain/chainApi/httpJSON/actions/getRequestByHash.go +++ b/service/system/blockchain/chainApi/httpJSON/actions/getRequestByHash.go @@ -18,49 +18,46 @@ package actions import ( - "github.com/SealSC/SealABC/network/http" - "github.com/SealSC/SealABC/service" - "github.com/gin-gonic/gin" + "github.com/SealSC/SealABC/network/http" + "github.com/SealSC/SealABC/service" + "github.com/gin-gonic/gin" ) -type getTransactionByHash struct{ - baseHandler +type getTransactionByHash struct { + baseHandler } -func (g *getTransactionByHash)Handle(ctx *gin.Context) { - res := http.NewResponse(ctx) - hash := ctx.Param(URLParameterKeys.HexHash.String()) +func (g *getTransactionByHash) Handle(ctx *gin.Context) { + res := http.NewResponse(ctx) + hash := ctx.Param(URLParameterKeys.HexHash.String()) - tx, err := g.sqlStorage.GetRequestByHash(hash) - if err != nil { - res.InternalServerError(nil) - return - } + tx, err := g.sqlStorage.GetRequestByHash(hash) + if err != nil { + res.InternalServerError(nil) + return + } - res.OK(tx) + res.OK(tx) } -func (g *getTransactionByHash)RouteRegister(router gin.IRouter) { - router.GET(g.buildUrlPath(), g.Handle) +func (g *getTransactionByHash) RouteRegister(router gin.IRouter) { + router.GET(g.buildUrlPath(), g.Handle) } -func (g *getTransactionByHash)BasicInformation() (info http.HandlerBasicInformation) { - info.Description = "return full request data of the given request hash." - info.Path = g.serverBasePath + g.buildUrlPath() - info.Method = service.ApiProtocolMethod.HttpGet.String() +func (g *getTransactionByHash) BasicInformation() (info http.HandlerBasicInformation) { + info.Description = "return full request data of the given request hash." + info.Path = g.serverBasePath + g.buildUrlPath() + info.Method = service.ApiProtocolMethod.HttpGet.String() - info.Parameters.Type = service.ApiParameterType.URL.String() - info.Parameters.Template = g.serverBasePath + g.urlWithoutParameters() + "/1ae9d62bea40f591af7ab6e03e077d85adb33a66cd977e913763a303599c5440" - return + info.Parameters.Type = service.ApiParameterType.URL.String() + info.Parameters.Template = g.serverBasePath + g.urlWithoutParameters() + "/1ae9d62bea40f591af7ab6e03e077d85adb33a66cd977e913763a303599c5440" + return } -func (g *getTransactionByHash) urlWithoutParameters() string { - return "/get/request/by/hash" +func (g *getTransactionByHash) urlWithoutParameters() string { + return "/get/request/by/hash" } - func (g *getTransactionByHash) buildUrlPath() string { - return g.urlWithoutParameters() + "/:" + URLParameterKeys.HexHash.String() + return g.urlWithoutParameters() + "/:" + URLParameterKeys.HexHash.String() } - - diff --git a/service/system/blockchain/chainApi/httpJSON/actions/getRequestByHeight.go b/service/system/blockchain/chainApi/httpJSON/actions/getRequestByHeight.go index 23e9fd9..54ec33e 100644 --- a/service/system/blockchain/chainApi/httpJSON/actions/getRequestByHeight.go +++ b/service/system/blockchain/chainApi/httpJSON/actions/getRequestByHeight.go @@ -23,11 +23,11 @@ import ( "github.com/gin-gonic/gin" ) -type getTransactionByHeight struct{ +type getTransactionByHeight struct { baseHandler } -func (g *getTransactionByHeight)Handle(ctx *gin.Context) { +func (g *getTransactionByHeight) Handle(ctx *gin.Context) { res := http.NewResponse(ctx) height := ctx.Param(URLParameterKeys.Height.String()) @@ -40,11 +40,11 @@ func (g *getTransactionByHeight)Handle(ctx *gin.Context) { res.OK(txList) } -func (g *getTransactionByHeight)RouteRegister(router gin.IRouter) { +func (g *getTransactionByHeight) RouteRegister(router gin.IRouter) { router.GET(g.buildUrlPath(), g.Handle) } -func (g *getTransactionByHeight)BasicInformation() (info http.HandlerBasicInformation) { +func (g *getTransactionByHeight) BasicInformation() (info http.HandlerBasicInformation) { info.Description = "return requests list of the given block height." info.Path = g.serverBasePath + g.buildUrlPath() info.Method = service.ApiProtocolMethod.HttpGet.String() @@ -54,13 +54,10 @@ func (g *getTransactionByHeight)BasicInformation() (info http.HandlerBasicInform return } -func (g *getTransactionByHeight) urlWithoutParameters() string { +func (g *getTransactionByHeight) urlWithoutParameters() string { return "/get/request/by/height" } - func (g *getTransactionByHeight) buildUrlPath() string { return g.urlWithoutParameters() + "/:" + URLParameterKeys.Height.String() } - - diff --git a/service/system/blockchain/chainApi/httpJSON/actions/getRequestList.go b/service/system/blockchain/chainApi/httpJSON/actions/getRequestList.go index 443a45a..a9c8580 100644 --- a/service/system/blockchain/chainApi/httpJSON/actions/getRequestList.go +++ b/service/system/blockchain/chainApi/httpJSON/actions/getRequestList.go @@ -18,55 +18,53 @@ package actions import ( - "github.com/SealSC/SealABC/network/http" - "github.com/SealSC/SealABC/service" - "github.com/gin-gonic/gin" - "strconv" + "github.com/SealSC/SealABC/network/http" + "github.com/SealSC/SealABC/service" + "github.com/gin-gonic/gin" + "strconv" ) -type getTransactions struct{ - baseHandler +type getTransactions struct { + baseHandler } -func (g *getTransactions)Handle(ctx *gin.Context) { - res := http.NewResponse(ctx) - pageString := ctx.Param(URLParameterKeys.Page.String()) +func (g *getTransactions) Handle(ctx *gin.Context) { + res := http.NewResponse(ctx) + pageString := ctx.Param(URLParameterKeys.Page.String()) - page, err := strconv.ParseUint(pageString, 10, 64) - if err != nil { - res.BadRequest("parameter [page] is not a number") - return - } + page, err := strconv.ParseUint(pageString, 10, 64) + if err != nil { + res.BadRequest("parameter [page] is not a number") + return + } - ret, err := g.sqlStorage.GetRequestList(page) - if err != nil { - res.InternalServerError(err.Error()) - return - } + ret, err := g.sqlStorage.GetRequestList(page) + if err != nil { + res.InternalServerError(err.Error()) + return + } - res.OK(ret) + res.OK(ret) } -func (g *getTransactions)RouteRegister(router gin.IRouter) { - router.GET(g.buildUrlPath(), g.Handle) +func (g *getTransactions) RouteRegister(router gin.IRouter) { + router.GET(g.buildUrlPath(), g.Handle) } -func (g *getTransactions)BasicInformation() (info http.HandlerBasicInformation) { - info.Description = "return block data list." - info.Path = g.serverBasePath + g.buildUrlPath() - info.Method = service.ApiProtocolMethod.HttpGet.String() +func (g *getTransactions) BasicInformation() (info http.HandlerBasicInformation) { + info.Description = "return block data list." + info.Path = g.serverBasePath + g.buildUrlPath() + info.Method = service.ApiProtocolMethod.HttpGet.String() - info.Parameters.Type = service.ApiParameterType.URL.String() - info.Parameters.Template = g.serverBasePath + g.urlWithoutParameters() + "/1" - return + info.Parameters.Type = service.ApiParameterType.URL.String() + info.Parameters.Template = g.serverBasePath + g.urlWithoutParameters() + "/1" + return } func (g *getTransactions) urlWithoutParameters() string { - return "/get/request/list/page/" + return "/get/request/list/page/" } func (g *getTransactions) buildUrlPath() string { - return g.urlWithoutParameters() + "/:" + URLParameterKeys.Page.String() + return g.urlWithoutParameters() + "/:" + URLParameterKeys.Page.String() } - - diff --git a/service/system/blockchain/chainApi/httpJSON/actions/queryApplication.go b/service/system/blockchain/chainApi/httpJSON/actions/queryApplication.go index a0307a0..3bea9ef 100644 --- a/service/system/blockchain/chainApi/httpJSON/actions/queryApplication.go +++ b/service/system/blockchain/chainApi/httpJSON/actions/queryApplication.go @@ -18,62 +18,61 @@ package actions import ( - "github.com/SealSC/SealABC/metadata/blockchainRequest" - "github.com/SealSC/SealABC/network/http" - "github.com/SealSC/SealABC/service" - "github.com/gin-gonic/gin" + "github.com/SealSC/SealABC/metadata/blockchainRequest" + "github.com/SealSC/SealABC/network/http" + "github.com/SealSC/SealABC/service" + "github.com/gin-gonic/gin" ) -type queryApplication struct{ - baseHandler +type queryApplication struct { + baseHandler } -func (q *queryApplication)Handle(ctx *gin.Context) { - res := http.NewResponse(ctx) +func (q *queryApplication) Handle(ctx *gin.Context) { + res := http.NewResponse(ctx) - appName := ctx.Param(URLParameterKeys.App.String()) + appName := ctx.Param(URLParameterKeys.App.String()) - handler, exist := q.appQueryHandler[appName] - if !exist { - res.BadRequest("no such application: " + appName) - return - } + handler, exist := q.appQueryHandler[appName] + if !exist { + res.BadRequest("no such application: " + appName) + return + } - reqData, err := ctx.GetRawData() - if err != nil { - res.BadRequest(err.Error()) - return - } + reqData, err := ctx.GetRawData() + if err != nil { + res.BadRequest(err.Error()) + return + } - ret, err := handler(reqData) - if err != nil { - res.BadRequest(err.Error()) - return - } + ret, err := handler(reqData) + if err != nil { + res.BadRequest(err.Error()) + return + } - res.OK(ret) + res.OK(ret) } -func (q *queryApplication)RouteRegister(router gin.IRouter) { - router.POST(q.buildUrlPath(), q.Handle) +func (q *queryApplication) RouteRegister(router gin.IRouter) { + router.POST(q.buildUrlPath(), q.Handle) } -func (q *queryApplication)BasicInformation() (info http.HandlerBasicInformation) { +func (q *queryApplication) BasicInformation() (info http.HandlerBasicInformation) { - info.Description = "will execute application query operation that registered on the blockchain." - info.Path = q.serverBasePath + q.buildUrlPath() - info.Method = service.ApiProtocolMethod.HttpPost.String() + info.Description = "will execute application query operation that registered on the blockchain." + info.Path = q.serverBasePath + q.buildUrlPath() + info.Method = service.ApiProtocolMethod.HttpPost.String() - info.Parameters.Type = service.ApiParameterType.JSON.String() - info.Parameters.Template = blockchainRequest.Entity{} - return + info.Parameters.Type = service.ApiParameterType.JSON.String() + info.Parameters.Template = blockchainRequest.Entity{} + return } -func (q *queryApplication) urlWithoutParameters() string { - return "/query/application" +func (q *queryApplication) urlWithoutParameters() string { + return "/query/application" } func (q *queryApplication) buildUrlPath() string { - return q.urlWithoutParameters() + "/:" + URLParameterKeys.App.String() + return q.urlWithoutParameters() + "/:" + URLParameterKeys.App.String() } - diff --git a/service/system/blockchain/chainApi/httpJSON/server.go b/service/system/blockchain/chainApi/httpJSON/server.go index 7c6a886..e498bd8 100644 --- a/service/system/blockchain/chainApi/httpJSON/server.go +++ b/service/system/blockchain/chainApi/httpJSON/server.go @@ -18,42 +18,42 @@ package httpJSON import ( - "github.com/SealSC/SealABC/network/http" - "github.com/SealSC/SealABC/service/system/blockchain/chainApi/httpJSON/actions" - "github.com/SealSC/SealABC/service/system/blockchain/chainSQLStorage" - "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" - "github.com/SealSC/SealABC/service/system/blockchain/chainNetwork" + "github.com/SealSC/SealABC/network/http" + "github.com/SealSC/SealABC/service/system/blockchain/chainApi/httpJSON/actions" + "github.com/SealSC/SealABC/service/system/blockchain/chainNetwork" + "github.com/SealSC/SealABC/service/system/blockchain/chainSQLStorage" + "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" ) type ApiServer struct { - server http.Server - Actions *actions.ChainApiActions + server http.Server + Actions *actions.ChainApiActions } func (a ApiServer) Address() string { - return a.server.Config.Address + return a.server.Config.Address } func NewApiServer(cfg http.Config, - chain *chainStructure.Blockchain, - p2p *chainNetwork.P2PService, - sqlStorage *chainSQLStorage.Storage) *ApiServer { + chain *chainStructure.Blockchain, + p2p *chainNetwork.P2PService, + sqlStorage *chainSQLStorage.Storage) *ApiServer { - httpServer := http.Server { - Config: &cfg, - } + httpServer := http.Server{ + Config: &cfg, + } - httpServer.Config.AllowCORS = true + httpServer.Config.AllowCORS = true - newActions := actions.NewActions(cfg.BasePath, chain, p2p, sqlStorage) - httpServer.Config.RequestHandler = []http.IRequestHandler{newActions} + newActions := actions.NewActions(cfg.BasePath, chain, p2p, sqlStorage) + httpServer.Config.RequestHandler = []http.IRequestHandler{newActions} - _ = httpServer.Start() + _ = httpServer.Start() - as := ApiServer { - server: httpServer, - Actions: newActions, - } + as := ApiServer{ + server: httpServer, + Actions: newActions, + } - return &as + return &as } diff --git a/service/system/blockchain/chainNetwork/blockSync.go b/service/system/blockchain/chainNetwork/blockSync.go index 86b7b7b..3605031 100644 --- a/service/system/blockchain/chainNetwork/blockSync.go +++ b/service/system/blockchain/chainNetwork/blockSync.go @@ -18,62 +18,61 @@ package chainNetwork import ( - "sync" - "github.com/SealSC/SealABC/network" - "time" - "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/network" + "sync" + "time" ) var syncBlockWait sync.WaitGroup var Syncing = false func (p *P2PService) StartSync(nodes []network.Node, targetHeight uint64) { - if Syncing { - return - } + if Syncing { + return + } - p.syncLock.Lock() - Syncing = true + p.syncLock.Lock() + Syncing = true - defer func() { - if r := recover(); r != nil { - log.Log.Error("got a panic: ", r) - } + defer func() { + if r := recover(); r != nil { + log.Log.Error("got a panic: ", r) + } - Syncing = false - p.syncLock.Unlock() - }() + Syncing = false + p.syncLock.Unlock() + }() - seedsCnt := len(nodes) - for s := p.chain.CurrentHeight(); s < targetHeight; s++ { - var syncErr error = nil - seedIdx := 0 - for i := 0; i< seedsCnt; i++ { - seedIdx = (int(s) + 1) % seedsCnt - syncErr = p.syncBlockFrom(nodes[seedIdx], s + 1) + seedsCnt := len(nodes) + for s := p.chain.CurrentHeight(); s < targetHeight; s++ { + var syncErr error = nil + seedIdx := 0 + for i := 0; i < seedsCnt; i++ { + seedIdx = (int(s) + 1) % seedsCnt + syncErr = p.syncBlockFrom(nodes[seedIdx], s+1) - if syncErr == nil { - syncBlockWait.Add(1) - break - } - } + if syncErr == nil { + syncBlockWait.Add(1) + break + } + } - if syncErr != nil { - log.Log.Error("sync block ", s, " failed") - time.Sleep(time.Second) - continue - } + if syncErr != nil { + log.Log.Error("sync block ", s, " failed") + time.Sleep(time.Second) + continue + } - log.Log.Println("waiting for block ", s + 1, " from node ", nodes[seedIdx].ServeAddress) - syncBlockWait.Wait() - log.Log.Println("sync block ", s + 1, " over.") - } - return + log.Log.Println("waiting for block ", s+1, " from node ", nodes[seedIdx].ServeAddress) + syncBlockWait.Wait() + log.Log.Println("sync block ", s+1, " over.") + } + return } func (p *P2PService) syncBlockFrom(node network.Node, height uint64) (err error) { - reqMsg := newSyncBlockMessage(height) - p.NetworkService.SendTo(node, reqMsg) - return + reqMsg := newSyncBlockMessage(height) + p.NetworkService.SendTo(node, reqMsg) + return } - diff --git a/service/system/blockchain/chainNetwork/chainNetwork.go b/service/system/blockchain/chainNetwork/chainNetwork.go index 87490fe..e196779 100644 --- a/service/system/blockchain/chainNetwork/chainNetwork.go +++ b/service/system/blockchain/chainNetwork/chainNetwork.go @@ -18,71 +18,70 @@ package chainNetwork import ( - "github.com/SealSC/SealABC/network" - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" - "errors" - "sync" - "github.com/SealSC/SealABC/log" + "errors" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/network" + "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" + "sync" ) -type P2PService struct{ - syncLock sync.Mutex - chain *chainStructure.Blockchain - networkMessageHandler map[string] p2pMessageHandler +type P2PService struct { + syncLock sync.Mutex + chain *chainStructure.Blockchain + networkMessageHandler map[string]p2pMessageHandler - //export - NetworkService network.IService + //export + NetworkService network.IService } func startChainP2PNetwork(cfg network.Config, p2p *P2PService) (networkService network.IService, err error) { - networkService = &network.Service{} - err = networkService.Create(cfg) - if err != nil { - return - } + networkService = &network.Service{} + err = networkService.Create(cfg) + if err != nil { + return + } - if len(cfg.P2PSeeds) == 0 { - err = errors.New("no p2p seeds") - return - } + if len(cfg.P2PSeeds) == 0 { + err = errors.New("no p2p seeds") + return + } - var seedNodes []network.Node - for _, seed := range cfg.P2PSeeds { - newP2PNode := network.Node{} + var seedNodes []network.Node + for _, seed := range cfg.P2PSeeds { + newP2PNode := network.Node{} - newP2PNode.ServeAddress = seed - newP2PNode.Protocol = cfg.ServiceProtocol + newP2PNode.ServeAddress = seed + newP2PNode.Protocol = cfg.ServiceProtocol - seedNodes = append(seedNodes, newP2PNode) - } + seedNodes = append(seedNodes, newP2PNode) + } - err = networkService.Join(seedNodes, nil) + err = networkService.Join(seedNodes, nil) - networkService.RegisterMessageProcessor(messageFamily, p2p.handleP2PMessage) - return + networkService.RegisterMessageProcessor(messageFamily, p2p.handleP2PMessage) + return } func Load() { - enum.SimpleBuild(&MessageTypes) + enum.SimpleBuild(&MessageTypes) } -func NewNetwork(cfg network.Config, chain *chainStructure.Blockchain) (*P2PService) { - p2p := P2PService{} - p2p.networkMessageHandler = map[string] p2pMessageHandler { - MessageTypes.PushRequest.String(): p2p.handlePushRequest, - MessageTypes.SyncBlock.String(): p2p.handleSyncBlock, - MessageTypes.SyncBlockReply.String(): p2p.handleSyncBlockReply, - } +func NewNetwork(cfg network.Config, chain *chainStructure.Blockchain) *P2PService { + p2p := P2PService{} + p2p.networkMessageHandler = map[string]p2pMessageHandler{ + MessageTypes.PushRequest.String(): p2p.handlePushRequest, + MessageTypes.SyncBlock.String(): p2p.handleSyncBlock, + MessageTypes.SyncBlockReply.String(): p2p.handleSyncBlockReply, + } - ns, err := startChainP2PNetwork(cfg, &p2p) - if err != nil { - log.Log.Warn("blockchain service network started with an error: ", err.Error()) - } + ns, err := startChainP2PNetwork(cfg, &p2p) + if err != nil { + log.Log.Warn("blockchain service network started with an error: ", err.Error()) + } - p2p.chain = chain - p2p.NetworkService = ns + p2p.chain = chain + p2p.NetworkService = ns - return &p2p + return &p2p } - diff --git a/service/system/blockchain/chainNetwork/message.go b/service/system/blockchain/chainNetwork/message.go index fbbbfca..9cd0a8c 100644 --- a/service/system/blockchain/chainNetwork/message.go +++ b/service/system/blockchain/chainNetwork/message.go @@ -18,109 +18,109 @@ package chainNetwork import ( - "github.com/SealSC/SealABC/metadata/message" - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/metadata/block" - "encoding/json" - "errors" - "github.com/SealSC/SealABC/metadata/blockchainRequest" + "encoding/json" + "errors" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/metadata/block" + "github.com/SealSC/SealABC/metadata/blockchainRequest" + "github.com/SealSC/SealABC/metadata/message" ) const messageFamily = "seal-chain-message" const messageVersion = "0.1" -var MessageTypes struct{ - PushRequest enum.Element - SyncBlock enum.Element - SyncBlockReply enum.Element +var MessageTypes struct { + PushRequest enum.Element + SyncBlock enum.Element + SyncBlockReply enum.Element } type syncBlockReplyMessage struct { - Success bool - Block block.Entity + Success bool + Block block.Entity } type syncBlockMessage struct { - BlockHeight uint64 + BlockHeight uint64 } func getBlockFromSyncReplyMessage(msg message.Message) (blk *block.Entity, err error) { - replyMsg := syncBlockReplyMessage{} - err = json.Unmarshal(msg.Payload, &replyMsg) - if err != nil { - return - } - - if !replyMsg.Success { - err = errors.New("block not exits") - return - } - - blk = &replyMsg.Block - return + replyMsg := syncBlockReplyMessage{} + err = json.Unmarshal(msg.Payload, &replyMsg) + if err != nil { + return + } + + if !replyMsg.Success { + err = errors.New("block not exits") + return + } + + blk = &replyMsg.Block + return } func getHeightFromSyncMessage(msg message.Message) (height uint64, err error) { - syncBlkMsg := syncBlockMessage{} - err = json.Unmarshal(msg.Payload, &syncBlkMsg) - if err != nil { - return - } - - height = syncBlkMsg.BlockHeight - return + syncBlkMsg := syncBlockMessage{} + err = json.Unmarshal(msg.Payload, &syncBlkMsg) + if err != nil { + return + } + + height = syncBlkMsg.BlockHeight + return } func getBlockchainRequestFromPushRequestMessage(msg message.Message) (req blockchainRequest.Entity, err error) { - err = json.Unmarshal(msg.Payload, &req) - if err != nil { - return - } + err = json.Unmarshal(msg.Payload, &req) + if err != nil { + return + } - return + return } func newSyncBlockMessage(height uint64) (msg message.Message) { - syncMsg := syncBlockMessage{ - BlockHeight: height, - } + syncMsg := syncBlockMessage{ + BlockHeight: height, + } - payload, _ := json.Marshal(syncMsg) - msg = newMessage(MessageTypes.SyncBlock, payload) - return + payload, _ := json.Marshal(syncMsg) + msg = newMessage(MessageTypes.SyncBlock, payload) + return } func newSyncBlockReplyMessage(blk *block.Entity, height uint64) (msg message.Message) { - replyMsg := syncBlockReplyMessage{} + replyMsg := syncBlockReplyMessage{} - if blk == nil { - replyMsg.Success = false - replyMsg.Block.Header.Height = height - } else { - replyMsg.Success = true - replyMsg.Block = *blk - } + if blk == nil { + replyMsg.Success = false + replyMsg.Block.Header.Height = height + } else { + replyMsg.Success = true + replyMsg.Block = *blk + } - payload, _ := json.Marshal(replyMsg) - msg = newMessage(MessageTypes.SyncBlockReply, payload) + payload, _ := json.Marshal(replyMsg) + msg = newMessage(MessageTypes.SyncBlockReply, payload) - return + return } func NewPushRequest(req blockchainRequest.Entity) (msg message.Message, err error) { - payload, err := json.Marshal(req) - if err != nil { - return - } + payload, err := json.Marshal(req) + if err != nil { + return + } - msg = newMessage(MessageTypes.PushRequest, payload) - return + msg = newMessage(MessageTypes.PushRequest, payload) + return } -func newMessage(msgType enum.Element, payload []byte,) (msg message.Message) { - msg.Family = messageFamily - msg.Version = messageVersion - msg.Type = msgType.String() - msg.Payload = payload - return +func newMessage(msgType enum.Element, payload []byte) (msg message.Message) { + msg.Family = messageFamily + msg.Version = messageVersion + msg.Type = msgType.String() + msg.Payload = payload + return } diff --git a/service/system/blockchain/chainNetwork/messageHandler.go b/service/system/blockchain/chainNetwork/messageHandler.go index d2d5612..fa1a79f 100644 --- a/service/system/blockchain/chainNetwork/messageHandler.go +++ b/service/system/blockchain/chainNetwork/messageHandler.go @@ -18,88 +18,88 @@ package chainNetwork import ( - "github.com/SealSC/SealABC/network" - "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/metadata/blockchainRequest" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/metadata/blockchainRequest" + "github.com/SealSC/SealABC/network" ) type p2pMessageHandler func(msg network.Message) *network.Message -func (p *P2PService)handlePushRequest(msg network.Message) (_ *network.Message) { - req, err := getBlockchainRequestFromPushRequestMessage(msg.Message) - if err != nil { - log.Log.Error("invalid request from p2p network: ", err.Error()) - return - } - _, err = p.chain.Executor.PushRequest(req) - if err != nil { - log.Log.Error("push request from p2p network failed: ", err.Error()) - return - } - return +func (p *P2PService) handlePushRequest(msg network.Message) (_ *network.Message) { + req, err := getBlockchainRequestFromPushRequestMessage(msg.Message) + if err != nil { + log.Log.Error("invalid request from p2p network: ", err.Error()) + return + } + _, err = p.chain.Executor.PushRequest(req) + if err != nil { + log.Log.Error("push request from p2p network failed: ", err.Error()) + return + } + return } -func (p *P2PService)handleSyncBlock(msg network.Message) (reply *network.Message) { - height, err := getHeightFromSyncMessage(msg.Message) - if err != nil { - log.Log.Error(err.Error()) - replyMsg := newSyncBlockReplyMessage(nil, height) - reply = &network.Message{ - Message: replyMsg, - } +func (p *P2PService) handleSyncBlock(msg network.Message) (reply *network.Message) { + height, err := getHeightFromSyncMessage(msg.Message) + if err != nil { + log.Log.Error(err.Error()) + replyMsg := newSyncBlockReplyMessage(nil, height) + reply = &network.Message{ + Message: replyMsg, + } - return reply - } - blk, err := p.chain.GetBlockByHeight(height) - if err != nil { - log.Log.Error("get block@", height, " failed") - replyMsg := newSyncBlockReplyMessage(nil, height) - reply = &network.Message{ - Message: replyMsg, - } - } + return reply + } + blk, err := p.chain.GetBlockByHeight(height) + if err != nil { + log.Log.Error("get block@", height, " failed") + replyMsg := newSyncBlockReplyMessage(nil, height) + reply = &network.Message{ + Message: replyMsg, + } + } - log.Log.Warn("block@", height, " sync to remote: ", msg.From.ServeAddress) - replyMsg := newSyncBlockReplyMessage(&blk, height) - reply = &network.Message{ - Message: replyMsg, - } + log.Log.Warn("block@", height, " sync to remote: ", msg.From.ServeAddress) + replyMsg := newSyncBlockReplyMessage(&blk, height) + reply = &network.Message{ + Message: replyMsg, + } - return + return } -func (p *P2PService)handleSyncBlockReply(msg network.Message) (_ *network.Message) { - defer func() { - if r := recover(); r != nil { - log.Log.Error("got a panic: ", r) - } - }() +func (p *P2PService) handleSyncBlockReply(msg network.Message) (_ *network.Message) { + defer func() { + if r := recover(); r != nil { + log.Log.Error("got a panic: ", r) + } + }() - blk, err := getBlockFromSyncReplyMessage(msg.Message) - if err != nil { - log.Log.Error("get block failed: ", err.Error()) - } else { - p.chain.AddBlock(*blk) - } + blk, err := getBlockFromSyncReplyMessage(msg.Message) + if err != nil { + log.Log.Error("get block failed: ", err.Error()) + } else { + p.chain.AddBlock(*blk) + } - //todo: call block sync module's method, not call syncBlockWait directly - syncBlockWait.Done() - return + //todo: call block sync module's method, not call syncBlockWait directly + syncBlockWait.Done() + return } -func (p *P2PService)handleP2PMessage(msg network.Message) (reply *network.Message) { - if h, exists := p.networkMessageHandler[msg.Type]; exists { - return h(msg) - } - return +func (p *P2PService) handleP2PMessage(msg network.Message) (reply *network.Message) { + if h, exists := p.networkMessageHandler[msg.Type]; exists { + return h(msg) + } + return } func (p *P2PService) BroadcastRequest(req blockchainRequest.Entity) (err error) { - msg, err := NewPushRequest(req) - if err != nil { - return - } + msg, err := NewPushRequest(req) + if err != nil { + return + } - err = p.NetworkService.Broadcast(msg) - return + err = p.NetworkService.Broadcast(msg) + return } diff --git a/service/system/blockchain/chainSQLStorage/query.go b/service/system/blockchain/chainSQLStorage/query.go index 067e3ae..b60c289 100644 --- a/service/system/blockchain/chainSQLStorage/query.go +++ b/service/system/blockchain/chainSQLStorage/query.go @@ -18,212 +18,210 @@ package chainSQLStorage import ( - "github.com/SealSC/SealABC/metadata/httpJSONResult/rowsWithCount" - "github.com/SealSC/SealABC/service/system/blockchain/chainTables" - "errors" - "strings" + "errors" + "github.com/SealSC/SealABC/metadata/httpJSONResult/rowsWithCount" + "github.com/SealSC/SealABC/service/system/blockchain/chainTables" + "strings" ) const rowsPerPage = 20 func (s *Storage) GetBlockList(start uint64) (blocks []chainTables.BlockListRow, err error) { - result, err := s.Driver.Query(chainTables.BlockListRow{}, - "select * from `t_block_list` where `c_height`>=? order by `c_height` asc limit 0,?", - []interface{}{start, rowsPerPage}) + result, err := s.Driver.Query(chainTables.BlockListRow{}, + "select * from `t_block_list` where `c_height`>=? order by `c_height` asc limit 0,?", + []interface{}{start, rowsPerPage}) - if err != nil { - return - } + if err != nil { + return + } - for _, r := range result { - newBlk := r.(chainTables.BlockListRow) - newBlk.Payload = "" - blocks = append(blocks, newBlk) - } + for _, r := range result { + newBlk := r.(chainTables.BlockListRow) + newBlk.Payload = "" + blocks = append(blocks, newBlk) + } - return + return } func (s *Storage) GetBlock(height uint64) (blk chainTables.BlockListRow, err error) { - result, err := s.Driver.Query(chainTables.BlockListRow{}, - "select * from `t_block_list` where `c_height`=? ", - []interface{}{height}) + result, err := s.Driver.Query(chainTables.BlockListRow{}, + "select * from `t_block_list` where `c_height`=? ", + []interface{}{height}) - if len(result) != 1 { - err = errors.New("no such block") - return - } + if len(result) != 1 { + err = errors.New("no such block") + return + } - blk, _ = result[0].(chainTables.BlockListRow) - return + blk, _ = result[0].(chainTables.BlockListRow) + return } func (s *Storage) GetRequestList(page uint64) (ret rowsWithCount.Entity, err error) { - table := chainTables.Requests.Name() + table := chainTables.Requests.Name() - count, err := s.Driver.RowCount(table, "", nil) - if err != nil { - return - } + count, err := s.Driver.RowCount(table, "", nil) + if err != nil { + return + } - startPage := page * rowsPerPage + startPage := page * rowsPerPage - pSQL := "select * from " + - "`" + table + "`" + - " order by `c_id` desc limit ?,?" + pSQL := "select * from " + + "`" + table + "`" + + " order by `c_id` desc limit ?,?" - row := chainTables.RequestRow{} - rows, err := s.Driver.Query(row, pSQL, []interface{} { - startPage, - rowsPerPage, - }) + row := chainTables.RequestRow{} + rows, err := s.Driver.Query(row, pSQL, []interface{}{ + startPage, + rowsPerPage, + }) - if err != nil { - return - } + if err != nil { + return + } + list := rowsWithCount.Entity{ + Rows: rows, + Total: count, + } - - list := rowsWithCount.Entity { - Rows: rows, - Total: count, - } - - return list, err + return list, err } func (s *Storage) GetBlockByHash(hash string) (blk chainTables.BlockListRow, err error) { - rows, err := s.Driver.SimpleSelect ( - chainTables.BlockListRow{}, - chainTables.BlockList.Name(), - `c_hash`, - hash, - ) - - if err != nil { - return - } - - if len(rows) != 1 { - err = errors.New("no such block") - return - } - - blk = rows[0].(chainTables.BlockListRow) - return + rows, err := s.Driver.SimpleSelect( + chainTables.BlockListRow{}, + chainTables.BlockList.Name(), + `c_hash`, + hash, + ) + + if err != nil { + return + } + + if len(rows) != 1 { + err = errors.New("no such block") + return + } + + blk = rows[0].(chainTables.BlockListRow) + return } func (s *Storage) GetRequestByHash(hash string) (req chainTables.RequestRow, err error) { - table := chainTables.Requests.Name() - pSQL := "select * from `" + table + "` where `c_hash`=?" + table := chainTables.Requests.Name() + pSQL := "select * from `" + table + "` where `c_hash`=?" - rows, err := s.Driver.Query(chainTables.RequestRow{}, pSQL, []interface{}{hash}) - if err != nil { - return - } + rows, err := s.Driver.Query(chainTables.RequestRow{}, pSQL, []interface{}{hash}) + if err != nil { + return + } - if len(rows) == 0 { - err = errors.New("no such transaction") - return - } + if len(rows) == 0 { + err = errors.New("no such transaction") + return + } - req = rows[0].(chainTables.RequestRow) - return + req = rows[0].(chainTables.RequestRow) + return } func (s *Storage) GetRequestByHeight(height string) (ret rowsWithCount.Entity, err error) { - table := chainTables.Requests.Name() - pSQL := "select * from " + - "`" + table + "`" + - " where `c_height`=? order by `c_id` desc" + table := chainTables.Requests.Name() + pSQL := "select * from " + + "`" + table + "`" + + " where `c_height`=? order by `c_id` desc" - row := chainTables.RequestRow{} - rows, err := s.Driver.Query(row, pSQL, []interface{} {height}) + row := chainTables.RequestRow{} + rows, err := s.Driver.Query(row, pSQL, []interface{}{height}) - if err != nil { - return - } + if err != nil { + return + } - list := rowsWithCount.Entity { - Rows: rows, - Total: uint64(len(rows)), - } + list := rowsWithCount.Entity{ + Rows: rows, + Total: uint64(len(rows)), + } - return list, err + return list, err } func (s *Storage) GetRequestByApplicationAndAction(app string, act string, page uint64) (ret rowsWithCount.Entity, err error) { - table := chainTables.Requests.Name() + table := chainTables.Requests.Name() - condition := []string{" `c_application`=? "} + condition := []string{" `c_application`=? "} - if act != "*" { - condition = append(condition, " `c_action`=? ") - } + if act != "*" { + condition = append(condition, " `c_action`=? ") + } - conditionStr := " where " + strings.Join(condition, " and ") + conditionStr := " where " + strings.Join(condition, " and ") - sqlParam := []interface{} {app} - if act != "*" { - sqlParam = append(sqlParam, act) - } + sqlParam := []interface{}{app} + if act != "*" { + sqlParam = append(sqlParam, act) + } - count, err := s.Driver.RowCount(table, conditionStr, sqlParam) - if err != nil { - return - } + count, err := s.Driver.RowCount(table, conditionStr, sqlParam) + if err != nil { + return + } - pSQL := "select * from " + - "`" + table + "`" + - conditionStr + - " order by `c_id` desc limit ?,?" + pSQL := "select * from " + + "`" + table + "`" + + conditionStr + + " order by `c_id` desc limit ?,?" - start := page * rowsPerPage - sqlParam = append(sqlParam, start, rowsPerPage) + start := page * rowsPerPage + sqlParam = append(sqlParam, start, rowsPerPage) - row := chainTables.RequestRow{} - rows, err := s.Driver.Query(row, pSQL, sqlParam) + row := chainTables.RequestRow{} + rows, err := s.Driver.Query(row, pSQL, sqlParam) - if err != nil { - return - } + if err != nil { + return + } - list := rowsWithCount.Entity { - Rows: rows, - Total: count, - } + list := rowsWithCount.Entity{ + Rows: rows, + Total: count, + } - return list, err + return list, err } func (s *Storage) GetAddressList(page uint64) (ret rowsWithCount.Entity, err error) { - table := chainTables.AddressList.Name() + table := chainTables.AddressList.Name() - count, err := s.Driver.RowCount(table, "", nil) - if err != nil { - return - } + count, err := s.Driver.RowCount(table, "", nil) + if err != nil { + return + } - pSQL := "select * from " + - "`" + table + "`" + - " order by `c_time` desc limit ?,?" + pSQL := "select * from " + + "`" + table + "`" + + " order by `c_time` desc limit ?,?" - start := page * rowsPerPage + start := page * rowsPerPage - row := chainTables.AddressListRow{} - rows, err := s.Driver.Query(row, pSQL, []interface{}{ - start, rowsPerPage, - }) + row := chainTables.AddressListRow{} + rows, err := s.Driver.Query(row, pSQL, []interface{}{ + start, rowsPerPage, + }) - if err != nil { - return - } + if err != nil { + return + } - list := rowsWithCount.Entity { - Rows: rows, - Total: count, - } + list := rowsWithCount.Entity{ + Rows: rows, + Total: count, + } - return list, err + return list, err } diff --git a/service/system/blockchain/chainSQLStorage/storage.go b/service/system/blockchain/chainSQLStorage/storage.go index 12fd6ee..fc92c8e 100644 --- a/service/system/blockchain/chainSQLStorage/storage.go +++ b/service/system/blockchain/chainSQLStorage/storage.go @@ -18,14 +18,14 @@ package chainSQLStorage import ( - "github.com/SealSC/SealABC/service/system/blockchain/chainTables" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" + "github.com/SealSC/SealABC/service/system/blockchain/chainTables" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" ) type Storage struct { - Driver simpleSQLDatabase.IDriver + Driver simpleSQLDatabase.IDriver } func Load() { - chainTables.Load() + chainTables.Load() } diff --git a/service/system/blockchain/chainSQLStorage/store.go b/service/system/blockchain/chainSQLStorage/store.go index 65b116f..4d26379 100644 --- a/service/system/blockchain/chainSQLStorage/store.go +++ b/service/system/blockchain/chainSQLStorage/store.go @@ -18,64 +18,63 @@ package chainSQLStorage import ( - "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/metadata/applicationResult" - "github.com/SealSC/SealABC/metadata/block" - "github.com/SealSC/SealABC/metadata/blockchainRequest" - "github.com/SealSC/SealABC/service/system/blockchain/chainTables" - "encoding/hex" + "encoding/hex" + "github.com/SealSC/SealABC/log" + "github.com/SealSC/SealABC/metadata/applicationResult" + "github.com/SealSC/SealABC/metadata/block" + "github.com/SealSC/SealABC/metadata/blockchainRequest" + "github.com/SealSC/SealABC/service/system/blockchain/chainTables" ) -func (s *Storage) StoreBlock(blk block.Entity) (err error) { - rows := chainTables.BlockList.NewRows().(chainTables.BlockListRows) - rows.InsertBlock(blk) +func (s *Storage) StoreBlock(blk block.Entity) (err error) { + rows := chainTables.BlockList.NewRows().(chainTables.BlockListRows) + rows.InsertBlock(blk) - _, err = s.Driver.Insert(&rows, true) - if err != nil { - log.Log.Error("insert to sql database failed: ", err.Error()) - } - return + _, err = s.Driver.Insert(&rows, true) + if err != nil { + log.Log.Error("insert to sql database failed: ", err.Error()) + } + return } func (s *Storage) StoreTransaction(blk block.Entity, req blockchainRequest.Entity, result applicationResult.Entity) (err error) { - rows := chainTables.Requests.NewRows().(chainTables.RequestRows) - rows.InsertTransaction(blk, req, result) + rows := chainTables.Requests.NewRows().(chainTables.RequestRows) + rows.InsertTransaction(blk, req, result) - _, err = s.Driver.Insert(&rows, true) - if err != nil { - log.Log.Error("insert transaction to block transaction list failed: ", err.Error()) - } + _, err = s.Driver.Insert(&rows, true) + if err != nil { + log.Log.Error("insert transaction to block transaction list failed: ", err.Error()) + } - return + return } func (s *Storage) StoreAddress(blk block.Entity, req blockchainRequest.Entity) (err error) { - defer func() { - if r := recover(); r != nil { - log.Log.Error("got panic: ", r) - } + defer func() { + if r := recover(); r != nil { + log.Log.Error("got panic: ", r) + } - if err != nil { - log.Log.Error(err.Error()) - return - } - }() + if err != nil { + log.Log.Error(err.Error()) + return + } + }() - cnt, err := s.Driver.RowCount( - chainTables.AddressList.Name(), - "where `c_address`=?", - []interface{}{ - hex.EncodeToString(req.Seal.SignerPublicKey), - }) + cnt, err := s.Driver.RowCount( + chainTables.AddressList.Name(), + "where `c_address`=?", + []interface{}{ + hex.EncodeToString(req.Seal.SignerPublicKey), + }) + rows := chainTables.AddressList.NewRows().(chainTables.AddressListRows) + rows.UpdateAddress(blk, req) + if cnt == 0 { + _, err = s.Driver.Insert(&rows, true) + } else { + _, err = s.Driver.Replace(&rows) + } - rows := chainTables.AddressList.NewRows().(chainTables.AddressListRows) - rows.UpdateAddress(blk, req) - if cnt == 0 { - _, err = s.Driver.Insert(&rows, true) - } else { - _, err = s.Driver.Replace(&rows) - } - - return + return } diff --git a/service/system/blockchain/chainStructure/config.go b/service/system/blockchain/chainStructure/config.go index 24df827..91c154c 100644 --- a/service/system/blockchain/chainStructure/config.go +++ b/service/system/blockchain/chainStructure/config.go @@ -18,16 +18,16 @@ package chainStructure import ( - "github.com/SealSC/SealABC/crypto" - "github.com/SealSC/SealABC/crypto/signers/signerCommon" - "github.com/SealSC/SealABC/service/system/blockchain/chainSQLStorage" - "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" + "github.com/SealSC/SealABC/crypto" + "github.com/SealSC/SealABC/crypto/signers/signerCommon" + "github.com/SealSC/SealABC/service/system/blockchain/chainSQLStorage" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" ) type Config struct { - Signer signerCommon.ISigner - CryptoTools crypto.Tools - NewWhenGenesis bool - StorageDriver kvDatabase.IDriver - SQLStorage *chainSQLStorage.Storage + Signer signerCommon.ISigner + CryptoTools crypto.Tools + NewWhenGenesis bool + StorageDriver kvDatabase.IDriver + SQLStorage *chainSQLStorage.Storage } diff --git a/service/system/blockchain/chainTables/addressList.go b/service/system/blockchain/chainTables/addressList.go index 131a43a..2cd86ba 100644 --- a/service/system/blockchain/chainTables/addressList.go +++ b/service/system/blockchain/chainTables/addressList.go @@ -18,13 +18,13 @@ package chainTables import ( + "encoding/hex" + "fmt" "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/dataStructure/enum" "github.com/SealSC/SealABC/metadata/block" "github.com/SealSC/SealABC/metadata/blockchainRequest" "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "encoding/hex" - "fmt" "time" ) @@ -78,7 +78,7 @@ type AddressListRows struct { simpleSQLDatabase.BasicRows } -func (t *AddressListRows) UpdateAddress(blk block.Entity, req blockchainRequest.Entity) { +func (t *AddressListRows) UpdateAddress(blk block.Entity, req blockchainRequest.Entity) { newRow := AddressListRow{} newRow.FromRequest(blk.Header.Height, blk.Header.Timestamp, req) t.Rows = append(t.Rows, newRow) diff --git a/service/system/blockchain/chainTables/blockList.go b/service/system/blockchain/chainTables/blockList.go index d8166d5..868e9a7 100644 --- a/service/system/blockchain/chainTables/blockList.go +++ b/service/system/blockchain/chainTables/blockList.go @@ -18,86 +18,85 @@ package chainTables import ( - "github.com/SealSC/SealABC/common" - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/metadata/block" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "encoding/hex" - "encoding/json" - "fmt" - "time" + "encoding/hex" + "encoding/json" + "fmt" + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/metadata/block" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" + "time" ) type BlockListTable struct { - ID enum.Element `col:"c_id" ignoreInsert:"true"` - Height enum.Element `col:"c_height"` - Signer enum.Element `col:"c_signer"` - Hash enum.Element `col:"c_hash"` - Sig enum.Element `col:"c_signature"` - PrevHash enum.Element `col:"c_prev_hash"` - Time enum.Element `col:"c_time"` - TXRoot enum.Element `col:"c_tx_root" def:"-"` - TXCount enum.Element `col:"c_tx_count" def:"0"` - Payload enum.Element `col:"c_payload" def:"{}"` - - simpleSQLDatabase.BasicTable + ID enum.Element `col:"c_id" ignoreInsert:"true"` + Height enum.Element `col:"c_height"` + Signer enum.Element `col:"c_signer"` + Hash enum.Element `col:"c_hash"` + Sig enum.Element `col:"c_signature"` + PrevHash enum.Element `col:"c_prev_hash"` + Time enum.Element `col:"c_time"` + TXRoot enum.Element `col:"c_tx_root" def:"-"` + TXCount enum.Element `col:"c_tx_count" def:"0"` + Payload enum.Element `col:"c_payload" def:"{}"` + + simpleSQLDatabase.BasicTable } var BlockList BlockListTable func (b BlockListTable) Name() (name string) { - return "t_block_list" + return "t_block_list" } func (b BlockListTable) NewRows() interface{} { - return simpleSQLDatabase.NewRowsInstance(BlockListRows{}) + return simpleSQLDatabase.NewRowsInstance(BlockListRows{}) } func (b *BlockListTable) load() { - enum.SimpleBuild(b) - b.Instance = *b + enum.SimpleBuild(b) + b.Instance = *b } - type BlockListRow struct { - ID string - Height string - Signer string - Hash string - Sig string - PrevHash string - Time string - TXRoot string - TXCount string - Payload string + ID string + Height string + Signer string + Hash string + Sig string + PrevHash string + Time string + TXRoot string + TXCount string + Payload string } -func (b *BlockListRow) FromBlockEntity(blk block.Entity) { - b.Height = fmt.Sprintf("%d", blk.Header.Height) - b.Signer = hex.EncodeToString(blk.Seal.SignerPublicKey) - b.Hash = hex.EncodeToString(blk.Seal.Hash) - b.Sig = hex.EncodeToString(blk.Seal.Signature) - b.PrevHash = hex.EncodeToString(blk.Header.PrevBlock) +func (b *BlockListRow) FromBlockEntity(blk block.Entity) { + b.Height = fmt.Sprintf("%d", blk.Header.Height) + b.Signer = hex.EncodeToString(blk.Seal.SignerPublicKey) + b.Hash = hex.EncodeToString(blk.Seal.Hash) + b.Sig = hex.EncodeToString(blk.Seal.Signature) + b.PrevHash = hex.EncodeToString(blk.Header.PrevBlock) - timestamp := time.Unix(int64(blk.Header.Timestamp), 0) - b.Time = timestamp.Format(common.BASIC_TIME_FORMAT) - b.TXRoot = hex.EncodeToString(blk.Header.TransactionsRoot) - b.TXCount = fmt.Sprintf("%d", blk.Body.RequestsCount) + timestamp := time.Unix(int64(blk.Header.Timestamp), 0) + b.Time = timestamp.Format(common.BASIC_TIME_FORMAT) + b.TXRoot = hex.EncodeToString(blk.Header.TransactionsRoot) + b.TXCount = fmt.Sprintf("%d", blk.Body.RequestsCount) - payloadJson, _ := json.Marshal(blk.EntityData) - b.Payload = string(payloadJson) + payloadJson, _ := json.Marshal(blk.EntityData) + b.Payload = string(payloadJson) } type BlockListRows struct { - simpleSQLDatabase.BasicRows + simpleSQLDatabase.BasicRows } -func (b *BlockListRows) InsertBlock(blk block.Entity) { - newRow := BlockListRow{} - newRow.FromBlockEntity(blk) - b.Rows = append(b.Rows, newRow) +func (b *BlockListRows) InsertBlock(blk block.Entity) { + newRow := BlockListRow{} + newRow.FromBlockEntity(blk) + b.Rows = append(b.Rows, newRow) } func (b *BlockListRows) Table() simpleSQLDatabase.ITable { - return &BlockList + return &BlockList } diff --git a/service/system/blockchain/chainTables/tables.go b/service/system/blockchain/chainTables/tables.go index cdb3181..b90aa53 100644 --- a/service/system/blockchain/chainTables/tables.go +++ b/service/system/blockchain/chainTables/tables.go @@ -18,7 +18,7 @@ package chainTables func Load() { - BlockList.load() - Requests.load() - AddressList.load() + BlockList.load() + Requests.load() + AddressList.load() } diff --git a/service/system/blockchain/chainTables/transactions.go b/service/system/blockchain/chainTables/transactions.go index 84f2370..443f76d 100644 --- a/service/system/blockchain/chainTables/transactions.go +++ b/service/system/blockchain/chainTables/transactions.go @@ -18,97 +18,97 @@ package chainTables import ( - "github.com/SealSC/SealABC/common" - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/metadata/applicationResult" - "github.com/SealSC/SealABC/metadata/block" - "github.com/SealSC/SealABC/metadata/blockchainRequest" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "encoding/hex" - "encoding/json" - "fmt" - "time" + "encoding/hex" + "encoding/json" + "fmt" + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/metadata/applicationResult" + "github.com/SealSC/SealABC/metadata/block" + "github.com/SealSC/SealABC/metadata/blockchainRequest" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" + "time" ) type RequestsTable struct { - ID enum.Element `col:"c_id" ignoreInsert:"true"` - Height enum.Element `col:"c_height"` - Sender enum.Element `col:"c_sender"` - Hash enum.Element `col:"c_hash"` - Sig enum.Element `col:"c_signature"` - Application enum.Element `col:"c_application"` - Action enum.Element `col:"c_action"` - Payload enum.Element `col:"c_payload"` - Packed enum.Element `col:"c_packed"` - Result enum.Element `col:"c_result"` - Time enum.Element `col:"c_time"` - - simpleSQLDatabase.BasicTable + ID enum.Element `col:"c_id" ignoreInsert:"true"` + Height enum.Element `col:"c_height"` + Sender enum.Element `col:"c_sender"` + Hash enum.Element `col:"c_hash"` + Sig enum.Element `col:"c_signature"` + Application enum.Element `col:"c_application"` + Action enum.Element `col:"c_action"` + Payload enum.Element `col:"c_payload"` + Packed enum.Element `col:"c_packed"` + Result enum.Element `col:"c_result"` + Time enum.Element `col:"c_time"` + + simpleSQLDatabase.BasicTable } var Requests RequestsTable func (t RequestsTable) Name() (name string) { - return "t_block_requests" + return "t_block_requests" } func (t RequestsTable) NewRows() interface{} { - return simpleSQLDatabase.NewRowsInstance(RequestRows{}) + return simpleSQLDatabase.NewRowsInstance(RequestRows{}) } func (t *RequestsTable) load() { - enum.SimpleBuild(t) - t.Instance = *t + enum.SimpleBuild(t) + t.Instance = *t } type RequestRow struct { - ID string - Height string - Sender string - Hash string - Sig string - Application string - Action string - Payload string - Packed string - Result string - Time string + ID string + Height string + Sender string + Hash string + Sig string + Application string + Action string + Payload string + Packed string + Result string + Time string } func (t *RequestRow) FromRequest(height uint64, tm uint64, req blockchainRequest.Entity, result applicationResult.Entity) { - t.Height = fmt.Sprintf("%d", height) - t.Sender = hex.EncodeToString(req.Seal.SignerPublicKey) - t.Hash = hex.EncodeToString(req.Seal.Hash) - t.Sig = hex.EncodeToString(req.Seal.Signature) - t.Application = req.RequestApplication - t.Action = req.RequestAction - - reqJson, _ := json.Marshal(req.EntityData) - t.Payload = string(reqJson) - - if req.Packed { - t.Packed = "1" - } else { - t.Packed = "0" - } - - resultJson, _ := json.Marshal(result) - t.Result = string(resultJson) - - timestamp := time.Unix(int64(tm), 0) - t.Time = timestamp.Format(common.BASIC_TIME_FORMAT) + t.Height = fmt.Sprintf("%d", height) + t.Sender = hex.EncodeToString(req.Seal.SignerPublicKey) + t.Hash = hex.EncodeToString(req.Seal.Hash) + t.Sig = hex.EncodeToString(req.Seal.Signature) + t.Application = req.RequestApplication + t.Action = req.RequestAction + + reqJson, _ := json.Marshal(req.EntityData) + t.Payload = string(reqJson) + + if req.Packed { + t.Packed = "1" + } else { + t.Packed = "0" + } + + resultJson, _ := json.Marshal(result) + t.Result = string(resultJson) + + timestamp := time.Unix(int64(tm), 0) + t.Time = timestamp.Format(common.BASIC_TIME_FORMAT) } type RequestRows struct { - simpleSQLDatabase.BasicRows + simpleSQLDatabase.BasicRows } -func (t *RequestRows) InsertTransaction(blk block.Entity, req blockchainRequest.Entity, result applicationResult.Entity) { - newRow := RequestRow{} - newRow.FromRequest(blk.Header.Height, blk.Header.Timestamp, req, result) - t.Rows = append(t.Rows, newRow) +func (t *RequestRows) InsertTransaction(blk block.Entity, req blockchainRequest.Entity, result applicationResult.Entity) { + newRow := RequestRow{} + newRow.FromRequest(blk.Header.Height, blk.Header.Timestamp, req, result) + t.Rows = append(t.Rows, newRow) } func (t *RequestRows) Table() simpleSQLDatabase.ITable { - return &Requests + return &Requests } diff --git a/service/system/blockchain/config.go b/service/system/blockchain/config.go index 6f50585..37e26ea 100644 --- a/service/system/blockchain/config.go +++ b/service/system/blockchain/config.go @@ -18,20 +18,20 @@ package blockchain import ( - "github.com/SealSC/SealABC/network" - "github.com/SealSC/SealABC/service/system/blockchain/chainApi" - "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" + "github.com/SealSC/SealABC/network" + "github.com/SealSC/SealABC/service/system/blockchain/chainApi" + "github.com/SealSC/SealABC/service/system/blockchain/chainStructure" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" ) type Config struct { - ServiceName string + ServiceName string - Blockchain chainStructure.Config - Network network.Config - Api chainApi.Config + Blockchain chainStructure.Config + Network network.Config + Api chainApi.Config - EnableSQLDB bool - SQLStorage simpleSQLDatabase.IDriver - ExternalExecutors []chainStructure.IBlockchainExternalApplication + EnableSQLDB bool + SQLStorage simpleSQLDatabase.IDriver + ExternalExecutors []chainStructure.IBlockchainExternalApplication } diff --git a/service/system/config.go b/service/system/config.go index 4522229..a070da8 100644 --- a/service/system/config.go +++ b/service/system/config.go @@ -20,5 +20,5 @@ package system import "github.com/SealSC/SealABC/service/system/blockchain" type Config struct { - Chain blockchain.Config + Chain blockchain.Config } diff --git a/service/system/system.go b/service/system/system.go index 11e8fe1..f36741b 100644 --- a/service/system/system.go +++ b/service/system/system.go @@ -18,14 +18,14 @@ package system import ( - "github.com/SealSC/SealABC/service/system/blockchain" - "github.com/SealSC/SealABC/service" + "github.com/SealSC/SealABC/service" + "github.com/SealSC/SealABC/service/system/blockchain" ) func Load() { - blockchain.Load() + blockchain.Load() } func NewBlockchainService(cfg blockchain.Config) service.IService { - return blockchain.NewService(cfg) + return blockchain.NewService(cfg) } diff --git a/storage/db/db.go b/storage/db/db.go index ca8327b..5d16fa9 100644 --- a/storage/db/db.go +++ b/storage/db/db.go @@ -18,43 +18,44 @@ package db import ( - "github.com/SealSC/SealABC/storage/db/dbDrivers/levelDB" - "github.com/SealSC/SealABC/storage/db/dbDrivers/simpleMysql" - "github.com/SealSC/SealABC/storage/db/dbInterface" - "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" + "github.com/SealSC/SealABC/storage/db/dbDrivers/levelDB" + "github.com/SealSC/SealABC/storage/db/dbDrivers/simpleMysql" + "github.com/SealSC/SealABC/storage/db/dbInterface" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" ) type kvDriverLoader func(cfg interface{}) (engine kvDatabase.IDriver, err error) type simpleSQLDriverLoader func(cfg interface{}) (engine simpleSQLDatabase.IDriver, err error) + var kvDBDriverLoader = map[string]kvDriverLoader{ - dbInterface.LevelDB: levelDB.NewDriver, + dbInterface.LevelDB: levelDB.NewDriver, } -var simpleSQLDBDriverLoader = map[string] simpleSQLDriverLoader { - dbInterface.MySQL: simpleMysql.NewDriver, +var simpleSQLDBDriverLoader = map[string]simpleSQLDriverLoader{ + dbInterface.MySQL: simpleMysql.NewDriver, } -func Load() { - simpleMysql.Load() +func Load() { + simpleMysql.Load() } -func NewKVDatabaseDriver(name string, cfg interface{}) (driver kvDatabase.IDriver, err error){ - driverLoader, supported := kvDBDriverLoader[name] - if !supported { - return - } +func NewKVDatabaseDriver(name string, cfg interface{}) (driver kvDatabase.IDriver, err error) { + driverLoader, supported := kvDBDriverLoader[name] + if !supported { + return + } - driver, err = driverLoader(cfg) - return + driver, err = driverLoader(cfg) + return } -func NewSimpleSQLDatabaseDriver(name string, cfg interface{}) (driver simpleSQLDatabase.IDriver, err error) { - driverLoader, supported := simpleSQLDBDriverLoader[name] - if !supported { - return - } +func NewSimpleSQLDatabaseDriver(name string, cfg interface{}) (driver simpleSQLDatabase.IDriver, err error) { + driverLoader, supported := simpleSQLDBDriverLoader[name] + if !supported { + return + } - driver, err = driverLoader(cfg) - return + driver, err = driverLoader(cfg) + return } diff --git a/storage/db/dbDrivers/levelDB/batch.go b/storage/db/dbDrivers/levelDB/batch.go index d0b1ef7..699aa74 100644 --- a/storage/db/dbDrivers/levelDB/batch.go +++ b/storage/db/dbDrivers/levelDB/batch.go @@ -18,80 +18,79 @@ package levelDB import ( - "github.com/syndtr/goleveldb/leveldb" - "github.com/syndtr/goleveldb/leveldb/util" - "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/util" ) -func (l *levelDBDriver)batchRead(kList [][]byte, needData bool) (kvList []kvDatabase.KVItem, err error) { - hasErr := false - for _, k := range kList { - var v []byte - var exists bool - if needData { - v, err = l.db.Get(k, nil) - exists = err == nil - } else { - exists, err = l.db.Has(k, nil) - } - - kv := kvDatabase.KVItem { - Key: k, - Data: v, - Exists: exists, - } - - kvList = append(kvList, kv) - hasErr = hasErr && kv.Exists - } - - return +func (l *levelDBDriver) batchRead(kList [][]byte, needData bool) (kvList []kvDatabase.KVItem, err error) { + hasErr := false + for _, k := range kList { + var v []byte + var exists bool + if needData { + v, err = l.db.Get(k, nil) + exists = err == nil + } else { + exists, err = l.db.Has(k, nil) + } + + kv := kvDatabase.KVItem{ + Key: k, + Data: v, + Exists: exists, + } + + kvList = append(kvList, kv) + hasErr = hasErr && kv.Exists + } + + return } func (l *levelDBDriver) BatchPut(kvList []kvDatabase.KVItem) (err error) { - batch := new(leveldb.Batch) - for _, kv := range kvList { - batch.Put(kv.Key, kv.Data) - } - err = l.db.Write(batch, nil) - return + batch := new(leveldb.Batch) + for _, kv := range kvList { + batch.Put(kv.Key, kv.Data) + } + err = l.db.Write(batch, nil) + return } -func (l *levelDBDriver) BatchGet(kList [][]byte) (kvList []kvDatabase.KVItem, err error){ - return l.batchRead(kList, true) +func (l *levelDBDriver) BatchGet(kList [][]byte) (kvList []kvDatabase.KVItem, err error) { + return l.batchRead(kList, true) } -func (l *levelDBDriver) BatchDelete(kList [][]byte) (err error){ - batch := new(leveldb.Batch) - for _, k := range kList { - batch.Delete(k) - } - err = l.db.Write(batch, nil) - return +func (l *levelDBDriver) BatchDelete(kList [][]byte) (err error) { + batch := new(leveldb.Batch) + for _, k := range kList { + batch.Delete(k) + } + err = l.db.Write(batch, nil) + return } func (l *levelDBDriver) BatchCheck(kList [][]byte) (kvList []kvDatabase.KVItem, err error) { - return l.batchRead(kList, false) + return l.batchRead(kList, false) } func (l *levelDBDriver) Traversal(condition []byte) (kvList []kvDatabase.KVItem) { - iterator := l.db.NewIterator(util.BytesPrefix(condition), nil) - defer iterator.Release() + iterator := l.db.NewIterator(util.BytesPrefix(condition), nil) + defer iterator.Release() - for iterator.Next() { - newData := kvDatabase.KVItem{} + for iterator.Next() { + newData := kvDatabase.KVItem{} - k := iterator.Key() - v := iterator.Value() - newData.Key = make([]byte, len(k), len(k)) - newData.Data = make([]byte, len(v), len(v)) - copy(newData.Key, k) - copy(newData.Data, v) - newData.Exists = true + k := iterator.Key() + v := iterator.Value() + newData.Key = make([]byte, len(k), len(k)) + newData.Data = make([]byte, len(v), len(v)) + copy(newData.Key, k) + copy(newData.Data, v) + newData.Exists = true + kvList = append(kvList, newData) + } - kvList = append(kvList, newData) - } - - return -} \ No newline at end of file + return +} diff --git a/storage/db/dbDrivers/levelDB/driver.go b/storage/db/dbDrivers/levelDB/driver.go index 8f16371..87dda3a 100644 --- a/storage/db/dbDrivers/levelDB/driver.go +++ b/storage/db/dbDrivers/levelDB/driver.go @@ -18,56 +18,55 @@ package levelDB import ( - "github.com/syndtr/goleveldb/leveldb" - "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/filter" - "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/errors" + "github.com/syndtr/goleveldb/leveldb/filter" + "github.com/syndtr/goleveldb/leveldb/opt" ) type levelDBDriver struct { - db *leveldb.DB + db *leveldb.DB } type Config struct { - DBFilePath string - Options opt.Options + DBFilePath string + Options opt.Options } func (l *levelDBDriver) Stat() (state interface{}, err error) { - return l.db.GetProperty("leveldb.stats") + return l.db.GetProperty("leveldb.stats") } func (l *levelDBDriver) Close() { - if nil != l.db { - _ = l.db.Close() - } + if nil != l.db { + _ = l.db.Close() + } } - func NewDriver(cfg interface{}) (driver kvDatabase.IDriver, err error) { - dbCfg, ok := cfg.(Config) + dbCfg, ok := cfg.(Config) - if !ok { - err = errors.New("incompatible config settings") - return - } + if !ok { + err = errors.New("incompatible config settings") + return + } - db, err := leveldb.OpenFile(dbCfg.DBFilePath, &opt.Options{ - Filter: filter.NewBloomFilter(10), - }) + db, err := leveldb.OpenFile(dbCfg.DBFilePath, &opt.Options{ + Filter: filter.NewBloomFilter(10), + }) - if _, failed := err.(*errors.ErrCorrupted); failed { - db, err = leveldb.RecoverFile(dbCfg.DBFilePath, nil) - } + if _, failed := err.(*errors.ErrCorrupted); failed { + db, err = leveldb.RecoverFile(dbCfg.DBFilePath, nil) + } - if err != nil { - return - } + if err != nil { + return + } - l := &levelDBDriver{} - l.db = db + l := &levelDBDriver{} + l.db = db - driver = l - return -} \ No newline at end of file + driver = l + return +} diff --git a/storage/db/dbDrivers/levelDB/simple.go b/storage/db/dbDrivers/levelDB/simple.go index 5741da9..4dcd618 100644 --- a/storage/db/dbDrivers/levelDB/simple.go +++ b/storage/db/dbDrivers/levelDB/simple.go @@ -18,38 +18,38 @@ package levelDB import ( - "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" - "github.com/syndtr/goleveldb/leveldb" + "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" + "github.com/syndtr/goleveldb/leveldb" ) -func (l *levelDBDriver)Put(kv kvDatabase.KVItem) (err error) { - err = l.db.Put(kv.Key, kv.Data, nil) - return +func (l *levelDBDriver) Put(kv kvDatabase.KVItem) (err error) { + err = l.db.Put(kv.Key, kv.Data, nil) + return } -func (l *levelDBDriver)Get(k []byte) (kv kvDatabase.KVItem, err error) { - v, err := l.db.Get(k, nil) - notFound := err == leveldb.ErrNotFound - if err != nil && !notFound { - return - } - - kv.Key = k - kv.Exists = !notFound - if notFound { - return kv, nil - } - - kv.Data = v - return +func (l *levelDBDriver) Get(k []byte) (kv kvDatabase.KVItem, err error) { + v, err := l.db.Get(k, nil) + notFound := err == leveldb.ErrNotFound + if err != nil && !notFound { + return + } + + kv.Key = k + kv.Exists = !notFound + if notFound { + return kv, nil + } + + kv.Data = v + return } -func (l *levelDBDriver)Delete(k []byte) (err error) { - err = l.db.Delete(k, nil) - return +func (l *levelDBDriver) Delete(k []byte) (err error) { + err = l.db.Delete(k, nil) + return } -func (l *levelDBDriver)Check(k []byte) (exists bool, err error) { - exists, err = l.db.Has(k, nil) - return +func (l *levelDBDriver) Check(k []byte) (exists bool, err error) { + exists, err = l.db.Has(k, nil) + return } diff --git a/storage/db/dbDrivers/simpleMysql/driver.go b/storage/db/dbDrivers/simpleMysql/driver.go index 37b1149..55d4b53 100644 --- a/storage/db/dbDrivers/simpleMysql/driver.go +++ b/storage/db/dbDrivers/simpleMysql/driver.go @@ -18,259 +18,259 @@ package simpleMysql import ( - "github.com/SealSC/SealABC/dataStructure/enum" - "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" - "database/sql" - "errors" - _ "github.com/go-sql-driver/mysql" - "strings" + "database/sql" + "errors" + "github.com/SealSC/SealABC/dataStructure/enum" + "github.com/SealSC/SealABC/storage/db/dbInterface/simpleSQLDatabase" + _ "github.com/go-sql-driver/mysql" + "strings" ) -var Charsets struct{ - UTF8 enum.Element +var Charsets struct { + UTF8 enum.Element } type Config struct { - User string - Password string - DBName string - Charset string - MaxConnection int + User string + Password string + DBName string + Charset string + MaxConnection int } type simpleMySQLDriver struct { - db *sql.DB + db *sql.DB } -func (s *simpleMySQLDriver) exec(pSQL string, data []interface{}) (result sql.Result, err error) { - stmt, err := s.db.Prepare(pSQL) - if err != nil { - return - } +func (s *simpleMySQLDriver) exec(pSQL string, data []interface{}) (result sql.Result, err error) { + stmt, err := s.db.Prepare(pSQL) + if err != nil { + return + } - defer func() { - closeErr := stmt.Close() + defer func() { + closeErr := stmt.Close() - errText := "" - if err != nil { - errText = "execute error: " + err.Error() - } + errText := "" + if err != nil { + errText = "execute error: " + err.Error() + } - if closeErr != nil { - errText = " close error: " + closeErr.Error() - } + if closeErr != nil { + errText = " close error: " + closeErr.Error() + } - if errText != "" { - err = errors.New(errText) - } - }() + if errText != "" { + err = errors.New(errText) + } + }() - result, err = stmt.Exec(data...) - return + result, err = stmt.Exec(data...) + return } -func (s *simpleMySQLDriver) getInsertContentSQL(sqlPrefix string, rows simpleSQLDatabase.IRows) (pSQL string, data []interface{}) { - pSQL = sqlPrefix +func (s *simpleMySQLDriver) getInsertContentSQL(sqlPrefix string, rows simpleSQLDatabase.IRows) (pSQL string, data []interface{}) { + pSQL = sqlPrefix - rowCount := rows.Count() - table := rows.Table() + rowCount := rows.Count() + table := rows.Table() - columns := table.ColumnsForInsert() - tName := table.Name() + columns := table.ColumnsForInsert() + tName := table.Name() - qm := make([]string, len(columns)) - for i := 0; i < len(columns); i++ { - qm[i] = "?" - } - pSQL += " `" + tName + "` (`" + strings.Join(columns[:], "`,`") + "`)" + qm := make([]string, len(columns)) + for i := 0; i < len(columns); i++ { + qm[i] = "?" + } + pSQL += " `" + tName + "` (`" + strings.Join(columns[:], "`,`") + "`)" - var values []string - for i := 0; i < rowCount; i++ { - values = append(values, "("+strings.Join(qm[:], ",")+")") - } + var values []string + for i := 0; i < rowCount; i++ { + values = append(values, "("+strings.Join(qm[:], ",")+")") + } - pSQL += " values " + strings.Join(values, ",") - data = rows.DataForInsert() - return + pSQL += " values " + strings.Join(values, ",") + data = rows.DataForInsert() + return } func (s *simpleMySQLDriver) insert(sqlPrefix string, rows simpleSQLDatabase.IRows) (result sql.Result, err error) { - pSQL, data := s.getInsertContentSQL(sqlPrefix, rows) - result, err = s.exec(pSQL , data) + pSQL, data := s.getInsertContentSQL(sqlPrefix, rows) + result, err = s.exec(pSQL, data) - return + return } func (s *simpleMySQLDriver) Insert(rows simpleSQLDatabase.IRows, ignoreKey bool) (result sql.Result, err error) { - if rows.Count() == 0 { - return - } - - var pSQL string - if ignoreKey { - pSQL = "insert ignore into " - } else { - pSQL = "insert into " - } - - result, err = s.insert(pSQL , rows) - return + if rows.Count() == 0 { + return + } + + var pSQL string + if ignoreKey { + pSQL = "insert ignore into " + } else { + pSQL = "insert into " + } + + result, err = s.insert(pSQL, rows) + return } func (s *simpleMySQLDriver) Replace(rows simpleSQLDatabase.IRows) (result sql.Result, err error) { - if rows.Count() == 0 { - return - } + if rows.Count() == 0 { + return + } - pSQL := "replace into " - result, err = s.insert(pSQL , rows) - return + pSQL := "replace into " + result, err = s.insert(pSQL, rows) + return } func (s *simpleMySQLDriver) Update(rows simpleSQLDatabase.IRows, fileds []string, condition string, args []interface{}) (result sql.Result, err error) { - if rows.Count() == 0 { - return - } + if rows.Count() == 0 { + return + } - pSQL := "update `" + rows.Table().Name() + "` set " - var data []interface{} + pSQL := "update `" + rows.Table().Name() + "` set " + var data []interface{} - columnCount := len(fileds) + columnCount := len(fileds) - dataSegment := make([]string, columnCount) - uData := rows.Data(fileds) - columns := rows.Table().FieldsToColumns(fileds) + dataSegment := make([]string, columnCount) + uData := rows.Data(fileds) + columns := rows.Table().FieldsToColumns(fileds) - for i:=0; i Date: Mon, 18 Jul 2022 17:04:31 +0800 Subject: [PATCH 09/20] feat: add account interface --- dataStructure/state/state_object.go | 48 ++++++++++--------- dataStructure/state/state_test.go | 3 +- dataStructure/state/statedb.go | 25 +++++----- dataStructure/state/types.go | 27 +++++++++++ .../smartAssets/smartAssetsLedger/account.go | 45 +++++++++++++++++ .../smartAssetsLedger/account_tool.go | 23 +++++++++ .../smartAssets/smartAssetsLedger/ledger.go | 4 +- 7 files changed, 136 insertions(+), 39 deletions(-) create mode 100644 dataStructure/state/types.go create mode 100644 service/application/smartAssets/smartAssetsLedger/account.go create mode 100644 service/application/smartAssets/smartAssetsLedger/account_tool.go diff --git a/dataStructure/state/state_object.go b/dataStructure/state/state_object.go index b1bac72..98c8a64 100644 --- a/dataStructure/state/state_object.go +++ b/dataStructure/state/state_object.go @@ -14,8 +14,6 @@ import ( //todo: Hash var emptyCodeHash = crypto.Keccak256(nil) -type Code []byte - func (c Code) String() string { return string(c) } @@ -60,19 +58,12 @@ type stateObject struct { onDirty func(addr common.Address) // Callback method to mark a state object newly dirty } -type Account struct { - Nonce uint64 - Balance *big.Int - Root common.Hash - CodeHash []byte -} - func newObject(db *StateDB, address common.Address, data Account, onDirty func(addr common.Address)) *stateObject { - if data.Balance == nil { - data.Balance = new(big.Int) + if data.Balance() == nil { + data.SetBalance(new(big.Int)) } if data.CodeHash == nil { - data.CodeHash = emptyCodeHash + data.SetCodeHash(emptyCodeHash) } return &stateObject{ db: db, @@ -91,7 +82,7 @@ func (s *stateObject) EncodeRLP(w io.Writer) error { } func (s *stateObject) empty() bool { - return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash) + return s.data.Nonce() == 0 && s.data.Balance().Sign() == 0 && bytes.Equal(s.data.CodeHash(), emptyCodeHash) } func (s *stateObject) Address() common.Address { @@ -125,7 +116,7 @@ func (s *stateObject) SetCode(codeHash common.Hash, code []byte) { func (s *stateObject) setCode(codeHash common.Hash, code []byte) { s.code = code - s.data.CodeHash = codeHash[:] + s.data.SetCodeHash(codeHash[:]) s.dirtyCode = true if s.onDirty != nil { s.onDirty(s.Address()) @@ -138,7 +129,7 @@ func (s *stateObject) SetNonce(nonce uint64) { } func (s *stateObject) setNonce(nonce uint64) { - s.data.Nonce = nonce + s.data.SetNonce(nonce) if s.onDirty != nil { s.onDirty(s.Address()) s.onDirty = nil @@ -146,21 +137,21 @@ func (s *stateObject) setNonce(nonce uint64) { } func (s *stateObject) CodeHash() []byte { - return s.data.CodeHash + return s.data.CodeHash() } func (s *stateObject) Balance() *big.Int { - return s.data.Balance + return s.data.Balance() } func (s *stateObject) Nonce() uint64 { - return s.data.Nonce + return s.data.Nonce() } func (s *stateObject) getTrie(db Database) Trie { if s.trie == nil { var err error - s.trie, err = db.OpenStorageTrie(s.addrHash, s.data.Root) + s.trie, err = db.OpenStorageTrie(s.addrHash, s.data.Root()) if err != nil { s.trie, _ = db.OpenStorageTrie(s.addrHash, common.Hash{}) s.setError(fmt.Errorf("can't create storage trie: %v", err)) @@ -222,7 +213,7 @@ func (s *stateObject) updateTrie(db Database) Trie { func (s *stateObject) updateRoot(db Database) { s.updateTrie(db) - s.data.Root = s.trie.Hash() + s.data.SetRoot(s.trie.Hash()) } func (s *stateObject) CommitTrie(db Database, db2 kvDatabase.IDriver) error { @@ -232,7 +223,7 @@ func (s *stateObject) CommitTrie(db Database, db2 kvDatabase.IDriver) error { } root, err := s.trie.CommitTo(db2) if err == nil { - s.data.Root = root + s.data.SetRoot(root) } return err } @@ -276,7 +267,7 @@ func (s *stateObject) SetBalance(amount *big.Int) { } func (s *stateObject) setBalance(amount *big.Int) { - s.data.Balance = amount + s.data.SetBalance(amount) if s.onDirty != nil { s.onDirty(s.Address()) s.onDirty = nil @@ -286,7 +277,8 @@ func (s *stateObject) setBalance(amount *big.Int) { func (s *stateObject) ReturnGas(gas *big.Int) {} func (s *stateObject) deepCopy(db *StateDB, onDirty func(addr common.Address)) *stateObject { - stateObject := newObject(db, s.address, s.data, onDirty) + account := s.deepCopyAccount(db, s.data) + stateObject := newObject(db, s.address, account, onDirty) if s.trie != nil { stateObject.trie = db.db.CopyTrie(s.trie) } @@ -296,5 +288,15 @@ func (s *stateObject) deepCopy(db *StateDB, onDirty func(addr common.Address)) * stateObject.suicided = s.suicided stateObject.dirtyCode = s.dirtyCode stateObject.deleted = s.deleted + return stateObject } + +func (s *stateObject) deepCopyAccount(db *StateDB, data Account) Account { + account := db.accountTool.NewAccount() + account.SetRoot(data.Root()) + account.SetBalance(data.Balance()) + account.SetNonce(data.Nonce()) + account.SetCodeHash(data.CodeHash()) + return account +} diff --git a/dataStructure/state/state_test.go b/dataStructure/state/state_test.go index 1e3e05e..81a4bde 100644 --- a/dataStructure/state/state_test.go +++ b/dataStructure/state/state_test.go @@ -3,6 +3,7 @@ package state import ( "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/crypto/hashes" + ledger "github.com/SealSC/SealABC/service/application/smartAssets/smartAssetsLedger" "github.com/SealSC/SealABC/storage/db" "github.com/SealSC/SealABC/storage/db/dbDrivers/levelDB" "github.com/SealSC/SealABC/storage/db/dbInterface" @@ -15,7 +16,7 @@ func Test(t *testing.T) { driver, _ := db.NewKVDatabaseDriver(dbInterface.LevelDB, levelDB.Config{ DBFilePath: "/Users/bianning/Project/Seal/TestDemo/et/temp/nodes/n1-1/chain", }) - state, _ := New(common.Hash{}, NewDatabase(driver)) + state, _ := New(common.Hash{}, NewDatabase(driver), &ledger.AccountTool{}) stateobjaddr0 := common.BytesToAddress([]byte("so0")) stateobjaddr1 := common.BytesToAddress([]byte("so1")) diff --git a/dataStructure/state/statedb.go b/dataStructure/state/statedb.go index 5c9457f..de10479 100644 --- a/dataStructure/state/statedb.go +++ b/dataStructure/state/statedb.go @@ -26,9 +26,11 @@ type StateDB struct { txIndex int lock sync.Mutex + + accountTool AccountTool } -func New(root common.Hash, db Database) (*StateDB, error) { +func New(root common.Hash, db Database, accountTool AccountTool) (*StateDB, error) { tr, err := db.OpenTrie(root) if err != nil { return nil, err @@ -39,6 +41,7 @@ func New(root common.Hash, db Database) (*StateDB, error) { trie: tr, stateObjects: make(map[common.Address]*stateObject), stateObjectsDirty: make(map[common.Address]struct{}), + accountTool: accountTool, }, nil } @@ -196,7 +199,7 @@ func (s *StateDB) Suicide(addr common.Address) bool { return false } stateObject.markSuicided() - stateObject.data.Balance = new(big.Int) + stateObject.data.SetBalance(new(big.Int)) return true } @@ -229,13 +232,15 @@ func (s *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) s.setError(err) return nil } - var data Account - if err := rlp.DecodeBytes(enc, &data); err != nil { + + account, err := s.accountTool.DecodeAccount(enc) + if err != nil { log.Log.Error("Failed to decode state object", "addr", addr, "err", err) return nil } + // Insert into the live set. - obj := newObject(s, addr, data, s.MarkStateObjectDirty) + obj := newObject(s, addr, account, s.MarkStateObjectDirty) s.setStateObject(obj) return obj } @@ -258,19 +263,12 @@ func (s *StateDB) MarkStateObjectDirty(addr common.Address) { func (s *StateDB) createObject(addr common.Address) (newObj, prev *stateObject) { prev = s.getStateObject(addr) - newObj = newObject(s, addr, Account{}, s.MarkStateObjectDirty) + newObj = newObject(s, addr, s.accountTool.NewAccount(), s.MarkStateObjectDirty) newObj.setNonce(0) s.setStateObject(newObj) return newObj, prev } -func (s *StateDB) CreateAccount(addr common.Address) { - newObj, prev := s.createObject(addr) - if prev != nil { - newObj.setBalance(prev.data.Balance) - } -} - func (s *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) { so := s.getStateObject(addr) if so == nil { @@ -299,6 +297,7 @@ func (s *StateDB) Copy() *StateDB { trie: s.trie, stateObjects: make(map[common.Address]*stateObject, len(s.stateObjectsDirty)), stateObjectsDirty: make(map[common.Address]struct{}, len(s.stateObjectsDirty)), + accountTool: s.accountTool, } for addr := range s.stateObjectsDirty { state.stateObjects[addr] = s.stateObjects[addr].deepCopy(state, state.MarkStateObjectDirty) diff --git a/dataStructure/state/types.go b/dataStructure/state/types.go new file mode 100644 index 0000000..19ff6a3 --- /dev/null +++ b/dataStructure/state/types.go @@ -0,0 +1,27 @@ +package state + +import ( + "github.com/SealSC/SealABC/common" + "math/big" +) + +type Code []byte + +type Account interface { + Balance() *big.Int + SetBalance(*big.Int) + + CodeHash() []byte + SetCodeHash([]byte) + + Nonce() uint64 + SetNonce(uint64) + + Root() common.Hash + SetRoot(common.Hash) +} + +type AccountTool interface { + NewAccount() Account + DecodeAccount([]byte) (Account, error) +} diff --git a/service/application/smartAssets/smartAssetsLedger/account.go b/service/application/smartAssets/smartAssetsLedger/account.go new file mode 100644 index 0000000..b804e3c --- /dev/null +++ b/service/application/smartAssets/smartAssetsLedger/account.go @@ -0,0 +1,45 @@ +package smartAssetsLedger + +import ( + "github.com/SealSC/SealABC/common" + "math/big" +) + +type Account struct { + AccountNonce uint64 + AccountBalance *big.Int + AccountRoot common.Hash + AccountCodeHash []byte +} + +func (a *Account) Balance() *big.Int { + return a.AccountBalance +} + +func (a *Account) SetBalance(b *big.Int) { + a.AccountBalance = b +} + +func (a *Account) CodeHash() []byte { + return a.AccountCodeHash +} + +func (a *Account) SetCodeHash(hash []byte) { + a.AccountCodeHash = hash +} + +func (a *Account) Nonce() uint64 { + return a.AccountNonce +} + +func (a *Account) SetNonce(nonce uint64) { + a.AccountNonce = nonce +} + +func (a *Account) Root() common.Hash { + return a.AccountRoot +} + +func (a *Account) SetRoot(hash common.Hash) { + a.AccountRoot = hash +} diff --git a/service/application/smartAssets/smartAssetsLedger/account_tool.go b/service/application/smartAssets/smartAssetsLedger/account_tool.go new file mode 100644 index 0000000..81cd4db --- /dev/null +++ b/service/application/smartAssets/smartAssetsLedger/account_tool.go @@ -0,0 +1,23 @@ +package smartAssetsLedger + +import ( + "github.com/SealSC/SealABC/dataStructure/state" + "github.com/SealSC/SealABC/log" + "github.com/ethereum/go-ethereum/rlp" +) + +type AccountTool struct { +} + +func (a AccountTool) NewAccount() state.Account { + return &Account{} +} + +func (a AccountTool) DecodeAccount(enc []byte) (state.Account, error) { + var account Account + if err := rlp.DecodeBytes(enc, &account); err != nil { + log.Log.Error("Failed to decode state object", "err", err) + return nil, err + } + return &account, nil +} diff --git a/service/application/smartAssets/smartAssetsLedger/ledger.go b/service/application/smartAssets/smartAssetsLedger/ledger.go index 5e4b56d..88bcabd 100644 --- a/service/application/smartAssets/smartAssetsLedger/ledger.go +++ b/service/application/smartAssets/smartAssetsLedger/ledger.go @@ -74,7 +74,7 @@ func (l *Ledger) SetChain(chain chainStructure.IChainInterface) { if chain.GetLastBlock() != nil { stateRoot := common.BytesToHash(chain.GetLastBlock().Header.StateRoot) - stateDB, err := state.New(stateRoot, state.NewDatabase(l.Storage)) + stateDB, err := state.New(stateRoot, state.NewDatabase(l.Storage), &AccountTool{}) if err != nil { log.Log.Error("Failed to reset txpool state", "err", err) } @@ -99,7 +99,7 @@ func (l *Ledger) NewStateAndLoadGenesisAssets(owner []byte, assets BaseAssetsDat return errors.New("no owner for system assets") } - stateDB, err := state.New(common.Hash{}, state.NewDatabase(l.Storage)) + stateDB, err := state.New(common.Hash{}, state.NewDatabase(l.Storage), &AccountTool{}) if err != nil { return err } From 0a1cb1e139d2fbf7199ccd96bd0858209cfec94a Mon Sep 17 00:00:00 2001 From: bianning Date: Mon, 18 Jul 2022 19:59:12 +0800 Subject: [PATCH 10/20] refactor: change hash to cryptotools --- dataStructure/state/database.go | 6 +++-- dataStructure/state/state_object.go | 23 +++++++++++-------- dataStructure/state/state_test.go | 11 ++++++++- dataStructure/state/statedb.go | 19 +++++++++------ dataStructure/trie/hasher.go | 15 +++++++----- .../smartAssets/smartAssetsLedger/ledger.go | 4 ++-- 6 files changed, 51 insertions(+), 27 deletions(-) diff --git a/dataStructure/state/database.go b/dataStructure/state/database.go index ff2c57b..c5c9980 100644 --- a/dataStructure/state/database.go +++ b/dataStructure/state/database.go @@ -3,6 +3,7 @@ package state import ( "fmt" "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/crypto" "github.com/SealSC/SealABC/dataStructure/trie" "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" lru "github.com/hashicorp/golang-lru" @@ -17,7 +18,7 @@ const ( ) type Database interface { - OpenTrie(root common.Hash) (Trie, error) + OpenTrie(root common.Hash, cryptoTools crypto.Tools) (Trie, error) OpenStorageTrie(addrHash, root common.Hash) (Trie, error) ContractCode(addrHash, codeHash common.Hash) ([]byte, error) ContractCodeSize(addrHash, codeHash common.Hash) (int, error) @@ -47,10 +48,11 @@ type cachingDB struct { codeSizeCache *lru.Cache } -func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) { +func (db *cachingDB) OpenTrie(root common.Hash, cryptoTools crypto.Tools) (Trie, error) { db.mu.Lock() defer db.mu.Unlock() + trie.Load(cryptoTools) for i := len(db.pastTries) - 1; i >= 0; i-- { if db.pastTries[i].Hash() == root { return cachedTrie{db.pastTries[i].Copy(), db}, nil diff --git a/dataStructure/state/state_object.go b/dataStructure/state/state_object.go index 98c8a64..0724e3b 100644 --- a/dataStructure/state/state_object.go +++ b/dataStructure/state/state_object.go @@ -4,15 +4,16 @@ import ( "bytes" "fmt" "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/crypto" "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" - "github.com/ethereum/go-ethereum/crypto" + //"github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rlp" "io" "math/big" ) -//todo: Hash -var emptyCodeHash = crypto.Keccak256(nil) +var emptyCodeHash []byte func (c Code) String() string { return string(c) @@ -56,20 +57,24 @@ type stateObject struct { touched bool deleted bool onDirty func(addr common.Address) // Callback method to mark a state object newly dirty + + cryptoTools crypto.Tools } -func newObject(db *StateDB, address common.Address, data Account, onDirty func(addr common.Address)) *stateObject { +func newObject(db *StateDB, cryptoTools crypto.Tools, address common.Address, data Account, onDirty func(addr common.Address)) *stateObject { + emptyCodeHash = cryptoTools.HashCalculator.Sum(nil) + if data.Balance() == nil { data.SetBalance(new(big.Int)) } if data.CodeHash == nil { data.SetCodeHash(emptyCodeHash) } + return &stateObject{ - db: db, - address: address, - //todo: Hash - addrHash: common.Hash(crypto.Keccak256Hash(address[:])), + db: db, + address: address, + addrHash: common.BytesToHash(cryptoTools.HashCalculator.Sum(address[:])), data: data, cachedStorage: make(Storage), dirtyStorage: make(Storage), @@ -278,7 +283,7 @@ func (s *stateObject) ReturnGas(gas *big.Int) {} func (s *stateObject) deepCopy(db *StateDB, onDirty func(addr common.Address)) *stateObject { account := s.deepCopyAccount(db, s.data) - stateObject := newObject(db, s.address, account, onDirty) + stateObject := newObject(db, db.cryptoTools, s.address, account, onDirty) if s.trie != nil { stateObject.trie = db.db.CopyTrie(s.trie) } diff --git a/dataStructure/state/state_test.go b/dataStructure/state/state_test.go index 81a4bde..40cd203 100644 --- a/dataStructure/state/state_test.go +++ b/dataStructure/state/state_test.go @@ -2,7 +2,10 @@ package state import ( "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/crypto" "github.com/SealSC/SealABC/crypto/hashes" + "github.com/SealSC/SealABC/crypto/hashes/sha3" + "github.com/SealSC/SealABC/crypto/signers/ed25519" ledger "github.com/SealSC/SealABC/service/application/smartAssets/smartAssetsLedger" "github.com/SealSC/SealABC/storage/db" "github.com/SealSC/SealABC/storage/db/dbDrivers/levelDB" @@ -16,7 +19,13 @@ func Test(t *testing.T) { driver, _ := db.NewKVDatabaseDriver(dbInterface.LevelDB, levelDB.Config{ DBFilePath: "/Users/bianning/Project/Seal/TestDemo/et/temp/nodes/n1-1/chain", }) - state, _ := New(common.Hash{}, NewDatabase(driver), &ledger.AccountTool{}) + + cryptoTools := crypto.Tools{ + HashCalculator: sha3.Sha256, + SignerGenerator: ed25519.SignerGenerator, + } + + state, _ := New(common.Hash{}, NewDatabase(driver), cryptoTools, &ledger.AccountTool{}) stateobjaddr0 := common.BytesToAddress([]byte("so0")) stateobjaddr1 := common.BytesToAddress([]byte("so1")) diff --git a/dataStructure/state/statedb.go b/dataStructure/state/statedb.go index de10479..ae3dd53 100644 --- a/dataStructure/state/statedb.go +++ b/dataStructure/state/statedb.go @@ -3,10 +3,11 @@ package state import ( "fmt" "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/crypto" "github.com/SealSC/SealABC/dataStructure/trie" "github.com/SealSC/SealABC/log" "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rlp" "math/big" @@ -28,10 +29,12 @@ type StateDB struct { lock sync.Mutex accountTool AccountTool + + cryptoTools crypto.Tools } -func New(root common.Hash, db Database, accountTool AccountTool) (*StateDB, error) { - tr, err := db.OpenTrie(root) +func New(root common.Hash, db Database, cryptoTools crypto.Tools, accountTool AccountTool) (*StateDB, error) { + tr, err := db.OpenTrie(root, cryptoTools) if err != nil { return nil, err } @@ -41,6 +44,7 @@ func New(root common.Hash, db Database, accountTool AccountTool) (*StateDB, erro trie: tr, stateObjects: make(map[common.Address]*stateObject), stateObjectsDirty: make(map[common.Address]struct{}), + cryptoTools: cryptoTools, accountTool: accountTool, }, nil } @@ -56,7 +60,7 @@ func (s *StateDB) Error() error { } func (s *StateDB) Reset(root common.Hash) error { - tr, err := s.db.OpenTrie(root) + tr, err := s.db.OpenTrie(root, s.cryptoTools) if err != nil { return err } @@ -182,7 +186,7 @@ func (s *StateDB) SetNonce(addr common.Address, nonce uint64) { func (s *StateDB) SetCode(addr common.Address, code []byte) { stateObject := s.GetOrNewStateObject(addr) if stateObject != nil { - stateObject.SetCode(common.Hash(crypto.Keccak256Hash(code)), code) + stateObject.SetCode(common.BytesToHash(s.cryptoTools.HashCalculator.Sum(code)), code) } } @@ -240,7 +244,7 @@ func (s *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) } // Insert into the live set. - obj := newObject(s, addr, account, s.MarkStateObjectDirty) + obj := newObject(s, s.cryptoTools, addr, account, s.MarkStateObjectDirty) s.setStateObject(obj) return obj } @@ -263,7 +267,7 @@ func (s *StateDB) MarkStateObjectDirty(addr common.Address) { func (s *StateDB) createObject(addr common.Address) (newObj, prev *stateObject) { prev = s.getStateObject(addr) - newObj = newObject(s, addr, s.accountTool.NewAccount(), s.MarkStateObjectDirty) + newObj = newObject(s, s.cryptoTools, addr, s.accountTool.NewAccount(), s.MarkStateObjectDirty) newObj.setNonce(0) s.setStateObject(newObj) return newObj, prev @@ -297,6 +301,7 @@ func (s *StateDB) Copy() *StateDB { trie: s.trie, stateObjects: make(map[common.Address]*stateObject, len(s.stateObjectsDirty)), stateObjectsDirty: make(map[common.Address]struct{}, len(s.stateObjectsDirty)), + cryptoTools: s.cryptoTools, accountTool: s.accountTool, } for addr := range s.stateObjectsDirty { diff --git a/dataStructure/trie/hasher.go b/dataStructure/trie/hasher.go index 832c01b..1a6f736 100644 --- a/dataStructure/trie/hasher.go +++ b/dataStructure/trie/hasher.go @@ -3,7 +3,7 @@ package trie import ( "bytes" "github.com/SealSC/SealABC/common" - "github.com/SealSC/SealABC/crypto/hashes/sha3" + "github.com/SealSC/SealABC/crypto" "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" "github.com/ethereum/go-ethereum/rlp" "hash" @@ -17,11 +17,14 @@ type hasher struct { cacheGen, cacheLimit uint16 } -var hasherPool = sync.Pool{ - New: func() interface{} { - //todo: hash - return &hasher{tmp: new(bytes.Buffer), sha: sha3.Keccak256.OriginalHash()()} - }, +var hasherPool sync.Pool + +func Load(cryptoTools crypto.Tools) { + hasherPool = sync.Pool{ + New: func() interface{} { + return &hasher{tmp: new(bytes.Buffer), sha: cryptoTools.HashCalculator.OriginalHash()()} + }, + } } func newHasher(cacheGen, cacheLimit uint16) *hasher { diff --git a/service/application/smartAssets/smartAssetsLedger/ledger.go b/service/application/smartAssets/smartAssetsLedger/ledger.go index 88bcabd..20a44da 100644 --- a/service/application/smartAssets/smartAssetsLedger/ledger.go +++ b/service/application/smartAssets/smartAssetsLedger/ledger.go @@ -74,7 +74,7 @@ func (l *Ledger) SetChain(chain chainStructure.IChainInterface) { if chain.GetLastBlock() != nil { stateRoot := common.BytesToHash(chain.GetLastBlock().Header.StateRoot) - stateDB, err := state.New(stateRoot, state.NewDatabase(l.Storage), &AccountTool{}) + stateDB, err := state.New(stateRoot, state.NewDatabase(l.Storage), l.CryptoTools, &AccountTool{}) if err != nil { log.Log.Error("Failed to reset txpool state", "err", err) } @@ -99,7 +99,7 @@ func (l *Ledger) NewStateAndLoadGenesisAssets(owner []byte, assets BaseAssetsDat return errors.New("no owner for system assets") } - stateDB, err := state.New(common.Hash{}, state.NewDatabase(l.Storage), &AccountTool{}) + stateDB, err := state.New(common.Hash{}, state.NewDatabase(l.Storage), l.CryptoTools, &AccountTool{}) if err != nil { return err } From 29a67306561ac6aa717b101b163e5f83bb23c3a6 Mon Sep 17 00:00:00 2001 From: bianning Date: Tue, 19 Jul 2022 14:59:26 +0800 Subject: [PATCH 11/20] feat: add batch put --- dataStructure/state/database.go | 6 ++-- dataStructure/state/state_object.go | 6 ++-- dataStructure/state/state_test.go | 2 +- dataStructure/state/statedb.go | 20 +++--------- dataStructure/trie/hasher.go | 32 +++++++++---------- dataStructure/trie/secure_trie.go | 18 ++++------- dataStructure/trie/trie.go | 8 ++--- dataStructure/trie/types.go | 5 +++ .../smartAssetsInterface.go | 4 +-- .../smartAssets/smartAssetsLedger/ledger.go | 25 +++++++-------- storage/db/dbDrivers/levelDB/batch.go | 17 ++++++++++ .../db/dbInterface/kvDatabase/batch_writer.go | 6 ++++ storage/db/dbInterface/kvDatabase/driver.go | 3 ++ 13 files changed, 83 insertions(+), 69 deletions(-) create mode 100644 dataStructure/trie/types.go create mode 100644 storage/db/dbInterface/kvDatabase/batch_writer.go diff --git a/dataStructure/state/database.go b/dataStructure/state/database.go index c5c9980..d8515aa 100644 --- a/dataStructure/state/database.go +++ b/dataStructure/state/database.go @@ -30,7 +30,7 @@ type Trie interface { TryGet(key []byte) ([]byte, error) TryUpdate(key, value []byte) error TryDelete(key []byte) error - CommitTo(kvDatabase.IDriver) (common.Hash, error) + CommitTo(trie.BatchWriter) (common.Hash, error) Hash() common.Hash NodeIterator(startKey []byte) trie.NodeIterator GetKey([]byte) []byte @@ -116,8 +116,8 @@ type cachedTrie struct { db *cachingDB } -func (m cachedTrie) CommitTo(db kvDatabase.IDriver) (common.Hash, error) { - root, err := m.SecureTrie.CommitTo(db) +func (m cachedTrie) CommitTo(bw trie.BatchWriter) (common.Hash, error) { + root, err := m.SecureTrie.CommitTo(bw) if err == nil { m.db.pushTrie(m.SecureTrie) } diff --git a/dataStructure/state/state_object.go b/dataStructure/state/state_object.go index 0724e3b..1a742f3 100644 --- a/dataStructure/state/state_object.go +++ b/dataStructure/state/state_object.go @@ -5,7 +5,7 @@ import ( "fmt" "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/crypto" - "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" + "github.com/SealSC/SealABC/dataStructure/trie" //"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/rlp" @@ -221,12 +221,12 @@ func (s *stateObject) updateRoot(db Database) { s.data.SetRoot(s.trie.Hash()) } -func (s *stateObject) CommitTrie(db Database, db2 kvDatabase.IDriver) error { +func (s *stateObject) CommitTrie(db Database, bw trie.BatchWriter) error { s.updateTrie(db) if s.dbErr != nil { return s.dbErr } - root, err := s.trie.CommitTo(db2) + root, err := s.trie.CommitTo(bw) if err == nil { s.data.SetRoot(root) } diff --git a/dataStructure/state/state_test.go b/dataStructure/state/state_test.go index 40cd203..51e92e5 100644 --- a/dataStructure/state/state_test.go +++ b/dataStructure/state/state_test.go @@ -46,7 +46,7 @@ func Test(t *testing.T) { so0.deleted = false state.setStateObject(so0) - root, _ := state.CommitTo(driver, false) + root, _ := state.CommitTo(driver.NewBatch(), false) t.Log(root) diff --git a/dataStructure/state/statedb.go b/dataStructure/state/statedb.go index ae3dd53..cd9c207 100644 --- a/dataStructure/state/statedb.go +++ b/dataStructure/state/statedb.go @@ -6,8 +6,6 @@ import ( "github.com/SealSC/SealABC/crypto" "github.com/SealSC/SealABC/dataStructure/trie" "github.com/SealSC/SealABC/log" - "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" - "github.com/ethereum/go-ethereum/rlp" "math/big" @@ -346,8 +344,7 @@ func (s *StateDB) DeleteSuicides() { } } -func (s *StateDB) CommitTo(db kvDatabase.IDriver, deleteEmptyObjects bool) (root common.Hash, err error) { - var kvList []kvDatabase.KVItem +func (s *StateDB) CommitTo(bw trie.BatchWriter, deleteEmptyObjects bool) (root common.Hash, err error) { for addr, stateObject := range s.stateObjects { _, isDirty := s.stateObjectsDirty[addr] switch { @@ -355,13 +352,11 @@ func (s *StateDB) CommitTo(db kvDatabase.IDriver, deleteEmptyObjects bool) (root s.deleteStateObject(stateObject) case isDirty: if stateObject.code != nil && stateObject.dirtyCode { - kvList = append(kvList, kvDatabase.KVItem{ - Key: stateObject.CodeHash(), - Data: stateObject.code, - }) + bw.Put(stateObject.CodeHash(), stateObject.code) stateObject.dirtyCode = false } - if err := stateObject.CommitTrie(s.db, db); err != nil { + + if err := stateObject.CommitTrie(s.db, bw); err != nil { return common.Hash{}, err } s.updateStateObject(stateObject) @@ -370,12 +365,7 @@ func (s *StateDB) CommitTo(db kvDatabase.IDriver, deleteEmptyObjects bool) (root delete(s.stateObjectsDirty, addr) } - err = db.BatchPut(kvList) - if err != nil { - return common.Hash{}, err - } - - root, err = s.trie.CommitTo(db) + root, err = s.trie.CommitTo(bw) return root, err } diff --git a/dataStructure/trie/hasher.go b/dataStructure/trie/hasher.go index 1a6f736..fc4a569 100644 --- a/dataStructure/trie/hasher.go +++ b/dataStructure/trie/hasher.go @@ -4,7 +4,6 @@ import ( "bytes" "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/crypto" - "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" "github.com/ethereum/go-ethereum/rlp" "hash" @@ -39,10 +38,10 @@ func returnHasherToPool(h *hasher) { // hash collapses a node down into a hash node, also returning a copy of the // original node initialized with the computed hash to replace the original one. -func (h *hasher) hash(n node, db kvDatabase.IDriver, force bool) (node, node, error) { +func (h *hasher) hash(n node, bw BatchWriter, force bool) (node, node, error) { // If we're not storing the node, just hashing, use available cached data if hash, dirty := n.cache(); hash != nil { - if db == nil { + if bw == nil { return hash, n, nil } if n.canUnload(h.cacheGen, h.cacheLimit) { @@ -56,11 +55,11 @@ func (h *hasher) hash(n node, db kvDatabase.IDriver, force bool) (node, node, er } } // Trie not processed yet or needs storage, walk the children - collapsed, cached, err := h.hashChildren(n, db) + collapsed, cached, err := h.hashChildren(n, bw) if err != nil { return hashNode{}, n, err } - hashed, err := h.store(collapsed, db, force) + hashed, err := h.store(collapsed, bw, force) if err != nil { return hashNode{}, n, err } @@ -71,12 +70,12 @@ func (h *hasher) hash(n node, db kvDatabase.IDriver, force bool) (node, node, er switch cn := cached.(type) { case *shortNode: cn.flags.hash = cachedHash - if db != nil { + if bw != nil { cn.flags.dirty = false } case *fullNode: cn.flags.hash = cachedHash - if db != nil { + if bw != nil { cn.flags.dirty = false } } @@ -86,7 +85,7 @@ func (h *hasher) hash(n node, db kvDatabase.IDriver, force bool) (node, node, er // hashChildren replaces the children of a node with their hashes if the encoded // size of the child is larger than a hash, returning the collapsed node as well // as a replacement for the original node with the child hashes cached in. -func (h *hasher) hashChildren(original node, db kvDatabase.IDriver) (node, node, error) { +func (h *hasher) hashChildren(original node, bw BatchWriter) (node, node, error) { var err error switch n := original.(type) { @@ -97,7 +96,7 @@ func (h *hasher) hashChildren(original node, db kvDatabase.IDriver) (node, node, cached.Key = common.CopyBytes(n.Key) if _, ok := n.Val.(valueNode); !ok { - collapsed.Val, cached.Val, err = h.hash(n.Val, db, false) + collapsed.Val, cached.Val, err = h.hash(n.Val, bw, false) if err != nil { return original, original, err } @@ -113,7 +112,7 @@ func (h *hasher) hashChildren(original node, db kvDatabase.IDriver) (node, node, for i := 0; i < 16; i++ { if n.Children[i] != nil { - collapsed.Children[i], cached.Children[i], err = h.hash(n.Children[i], db, false) + collapsed.Children[i], cached.Children[i], err = h.hash(n.Children[i], bw, false) if err != nil { return original, original, err } @@ -133,7 +132,7 @@ func (h *hasher) hashChildren(original node, db kvDatabase.IDriver) (node, node, } } -func (h *hasher) store(n node, db kvDatabase.IDriver, force bool) (node, error) { +func (h *hasher) store(n node, bw BatchWriter, force bool) (node, error) { // Don't store hashes or empty nodes. if _, isHash := n.(hashNode); n == nil || isHash { return n, nil @@ -154,11 +153,12 @@ func (h *hasher) store(n node, db kvDatabase.IDriver, force bool) (node, error) h.sha.Write(h.tmp.Bytes()) hash = hashNode(h.sha.Sum(nil)) } - if db != nil { - return hash, db.Put(kvDatabase.KVItem{ - Key: hash, - Data: h.tmp.Bytes(), - }) + if bw != nil { + bw.Put( + hash, + h.tmp.Bytes(), + ) + return hash, nil } return hash, nil } diff --git a/dataStructure/trie/secure_trie.go b/dataStructure/trie/secure_trie.go index bf80b26..51b6ee9 100644 --- a/dataStructure/trie/secure_trie.go +++ b/dataStructure/trie/secure_trie.go @@ -78,10 +78,6 @@ func (t *SecureTrie) GetKey(shaKey []byte) []byte { return key.Data } -func (t *SecureTrie) Commit() (root common.Hash, err error) { - return t.CommitTo(t.trie.db) -} - func (t *SecureTrie) Hash() common.Hash { return t.trie.Hash() } @@ -99,19 +95,17 @@ func (t *SecureTrie) NodeIterator(start []byte) NodeIterator { return t.trie.NodeIterator(start) } -func (t *SecureTrie) CommitTo(db kvDatabase.IDriver) (root common.Hash, err error) { +func (t *SecureTrie) CommitTo(bw BatchWriter) (root common.Hash, err error) { if len(t.getSecKeyCache()) > 0 { for hk, key := range t.secKeyCache { - if err := db.Put(kvDatabase.KVItem{ - Key: t.secKey([]byte(hk)), - Data: key, - }); err != nil { - return common.Hash{}, err - } + bw.Put( + t.secKey([]byte(hk)), + key, + ) } t.secKeyCache = make(map[string][]byte) } - return t.trie.CommitTo(db) + return t.trie.CommitTo(bw) } func (t *SecureTrie) secKey(key []byte) []byte { diff --git a/dataStructure/trie/trie.go b/dataStructure/trie/trie.go index ee716e0..d1be3c6 100644 --- a/dataStructure/trie/trie.go +++ b/dataStructure/trie/trie.go @@ -307,13 +307,13 @@ func (t *Trie) resolve(n node, prefix []byte) (node, error) { return n, nil } -func (t *Trie) hashRoot(db kvDatabase.IDriver) (node, node, error) { +func (t *Trie) hashRoot(bw BatchWriter) (node, node, error) { if t.root == nil { return hashNode(emptyRoot.Bytes()), nil, nil } h := newHasher(t.cacheGen, t.cacheLimit) defer returnHasherToPool(h) - return h.hash(t.root, db, true) + return h.hash(t.root, bw, true) } func (t *Trie) SetCacheLimit(l uint16) { @@ -343,8 +343,8 @@ func mustDecodeNode(hash, buf []byte, cacheGen uint16) node { return n } -func (t *Trie) CommitTo(db kvDatabase.IDriver) (root common.Hash, err error) { - hash, cached, err := t.hashRoot(db) +func (t *Trie) CommitTo(bw BatchWriter) (root common.Hash, err error) { + hash, cached, err := t.hashRoot(bw) if err != nil { return common.Hash{}, err } diff --git a/dataStructure/trie/types.go b/dataStructure/trie/types.go new file mode 100644 index 0000000..f43cedf --- /dev/null +++ b/dataStructure/trie/types.go @@ -0,0 +1,5 @@ +package trie + +type BatchWriter interface { + Put(key, value []byte) +} diff --git a/service/application/smartAssets/smartAssetsInterface/smartAssetsInterface.go b/service/application/smartAssets/smartAssetsInterface/smartAssetsInterface.go index 0cb3ce4..5ad1d4d 100644 --- a/service/application/smartAssets/smartAssetsInterface/smartAssetsInterface.go +++ b/service/application/smartAssets/smartAssetsInterface/smartAssetsInterface.go @@ -92,9 +92,9 @@ func (s *SmartAssetsApplication) Execute( return } - _, err = s.ledger.Execute(txList, blk) + _, root, err := s.ledger.Execute(txList, blk) - result.Data, _ = s.ledger.StateDB.CommitTo(s.ledger.Storage, true) + result.Data = root if err == nil && s.sqlStorage != nil { for _, tx := range txList.Transactions { diff --git a/service/application/smartAssets/smartAssetsLedger/ledger.go b/service/application/smartAssets/smartAssetsLedger/ledger.go index 20a44da..fad4340 100644 --- a/service/application/smartAssets/smartAssetsLedger/ledger.go +++ b/service/application/smartAssets/smartAssetsLedger/ledger.go @@ -372,18 +372,15 @@ func (l *Ledger) removeTransactionsFromPool(txList []Transaction) { } } -func (l *Ledger) Execute(txList TransactionList, blk block.Entity) (result []byte, err error) { +func (l *Ledger) Execute(txList TransactionList, blk block.Entity) (result []byte, root common.Hash, err error) { l.poolLock.Lock() defer l.poolLock.Unlock() - var kvList []kvDatabase.KVItem + batch := l.Storage.NewBatch() + for _, tx := range txList.Transactions { txData, _ := structSerializer.ToMFBytes(tx) - kvList = append(kvList, kvDatabase.KVItem{ - Key: BuildKey(StoragePrefixes.Transaction, tx.DataSeal.Hash), - Data: txData, - Exists: true, - }) + batch.Put(BuildKey(StoragePrefixes.Transaction, tx.DataSeal.Hash), txData) switch tx.Type { case TxType.Transfer.String(): @@ -400,22 +397,24 @@ func (l *Ledger) Execute(txList TransactionList, blk block.Entity) (result []byt } default: for _, s := range tx.TransactionResult.NewState { - kvList = append(kvList, kvDatabase.KVItem{ - Key: s.Key, - Data: s.NewVal, - Exists: true, - }) + batch.Put(s.Key, s.NewVal) } } } - err = l.Storage.BatchPut(kvList) + root, err = l.StateDB.CommitTo(batch, true) + if err != nil { + return + } + + err = l.Storage.BatchWrite(batch) if err != nil { return } l.removeTransactionsFromPool(txList.Transactions) + return } diff --git a/storage/db/dbDrivers/levelDB/batch.go b/storage/db/dbDrivers/levelDB/batch.go index 699aa74..a0ee19d 100644 --- a/storage/db/dbDrivers/levelDB/batch.go +++ b/storage/db/dbDrivers/levelDB/batch.go @@ -18,6 +18,7 @@ package levelDB import ( + "errors" "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/util" @@ -70,6 +71,22 @@ func (l *levelDBDriver) BatchDelete(kList [][]byte) (err error) { return } +func (l *levelDBDriver) NewBatch() kvDatabase.Batch { + return new(leveldb.Batch) +} + +func (l *levelDBDriver) BatchWrite(b kvDatabase.Batch) (err error) { + switch batch := b.(type) { + case *leveldb.Batch: + err = l.db.Write(batch, nil) + return err + default: + err = errors.New("batch write error") + } + + return +} + func (l *levelDBDriver) BatchCheck(kList [][]byte) (kvList []kvDatabase.KVItem, err error) { return l.batchRead(kList, false) } diff --git a/storage/db/dbInterface/kvDatabase/batch_writer.go b/storage/db/dbInterface/kvDatabase/batch_writer.go new file mode 100644 index 0000000..ccb013d --- /dev/null +++ b/storage/db/dbInterface/kvDatabase/batch_writer.go @@ -0,0 +1,6 @@ +package kvDatabase + +type Batch interface { + Put(key []byte, value []byte) + //Write() error +} diff --git a/storage/db/dbInterface/kvDatabase/driver.go b/storage/db/dbInterface/kvDatabase/driver.go index 6047e45..42b2be6 100644 --- a/storage/db/dbInterface/kvDatabase/driver.go +++ b/storage/db/dbInterface/kvDatabase/driver.go @@ -30,6 +30,9 @@ type IDriver interface { BatchDelete(kList [][]byte) (err error) BatchCheck(kList [][]byte) (kvList []KVItem, err error) + NewBatch() Batch + BatchWrite(Batch) (err error) + Traversal(condition []byte) (kvList []KVItem) Stat() (state interface{}, err error) From 875d35460f8dbf5de1137145616749a71addacf7 Mon Sep 17 00:00:00 2001 From: bianning Date: Tue, 19 Jul 2022 18:23:50 +0800 Subject: [PATCH 12/20] feat: add block verify to chained-consensus --- consensus/hotStuff/basicHotStuff/asReplica.go | 2 +- .../hotStuff/chainedHotStuff/asReplica.go | 13 ++++ consensus/service.go | 2 +- engine/engineService/consensusProcessor.go | 50 ++++++++------ .../engineService/mountedServiceExecutor.go | 4 +- .../smartAssets/smartAssetsLedger/ledger.go | 68 ------------------- service/service.go | 4 +- .../system/blockchain/chainStructure/chain.go | 3 +- .../serviceInterface/serviceInterface.go | 25 +++++-- 9 files changed, 71 insertions(+), 100 deletions(-) diff --git a/consensus/hotStuff/basicHotStuff/asReplica.go b/consensus/hotStuff/basicHotStuff/asReplica.go index dbaace8..1d5450e 100644 --- a/consensus/hotStuff/basicHotStuff/asReplica.go +++ b/consensus/hotStuff/basicHotStuff/asReplica.go @@ -31,7 +31,7 @@ func (b *BasicHotStuff) VerifyProposal(bs *hotStuff.BasicService, consensusData return } - validCustomerData, err := customerData.Verify() + validCustomerData, err := customerData.Verify(bs.GetLastConsensusCustomerData()) if !validCustomerData { log.Log.Error("customer data verify failed: ", err) return diff --git a/consensus/hotStuff/chainedHotStuff/asReplica.go b/consensus/hotStuff/chainedHotStuff/asReplica.go index 8b6fc13..a2d260e 100644 --- a/consensus/hotStuff/chainedHotStuff/asReplica.go +++ b/consensus/hotStuff/chainedHotStuff/asReplica.go @@ -24,6 +24,19 @@ func (c *ChainedHotStuff) VerifyProposal(bs *hotStuff.BasicService, consensusDat return } + //verify block + customerData, err := bs.ExternalProcessor.CustomerDataFromConsensus(consensusData.Payload.CustomerData) + if err != nil { + log.Log.Error("get customer data interface from message failed.") + return + } + + validCustomerData, err := customerData.Verify(bs.GetLastConsensusCustomerData()) + if !validCustomerData { + log.Log.Error("customer data verify failed: ", err) + return + } + validView := true if bs.LockedQC != nil { validView = consensusData.ViewNumber > bs.LockedQC.ViewNumber diff --git a/consensus/service.go b/consensus/service.go index abca19d..c06d238 100644 --- a/consensus/service.go +++ b/consensus/service.go @@ -35,7 +35,7 @@ type event struct { } type ICustomerData interface { - Verify() (passed bool, err error) + Verify([]byte) (passed bool, err error) Bytes() ([]byte, error) } diff --git a/engine/engineService/consensusProcessor.go b/engine/engineService/consensusProcessor.go index ecb0585..47f7361 100644 --- a/engine/engineService/consensusProcessor.go +++ b/engine/engineService/consensusProcessor.go @@ -32,7 +32,7 @@ type requestList struct { Requests [][]byte } -func (r *requestList) Verify() (passed bool, err error) { +func (r *requestList) Verify(lastReqData []byte) (passed bool, err error) { passed = true for _, req := range r.Requests { srvReq := serviceRequest.Entity{} @@ -40,7 +40,13 @@ func (r *requestList) Verify() (passed bool, err error) { if err != nil { continue } - _, err = preExecuteServiceRequest(srvReq) + + var srvReqs []interface{} + if len(lastReqData) != 0 { + srvReqs = byteToReqs(lastReqData) + } + + _, err = preExecuteServiceRequest(srvReq, srvReqs) //todo: handle the result of pre-execute if err != nil { passed = false @@ -92,24 +98,7 @@ func (e *consensusProcessor) EventProcessor(event enum.Element, customerData []b } func (e *consensusProcessor) CustomerDataToConsensus(lastCustomerData []byte) (data consensus.ICustomerData, _ error) { - lastReqList := requestList{} - err := json.Unmarshal(lastCustomerData, &lastReqList) - - var srvReqs []interface{} - if !reflect.DeepEqual(lastReqList, requestList{}) { - srvReqs = make([]interface{}, len(lastReqList.Requests)) - for i, req := range lastReqList.Requests { - srvReq := serviceRequest.Entity{} - err = json.Unmarshal(req, &srvReq) - if err != nil { - log.Log.Error("deserialize consensus data failed: ", err.Error()) - continue - } - - srvReqs[i] = srvReq - } - } - + srvReqs := byteToReqs(lastCustomerData) allValidRequests := getAllRequestsNeedConsensus(srvReqs) data = &requestList{ allValidRequests, @@ -134,4 +123,25 @@ func (e *consensusProcessor) NewDataBasedOnConsensus(data consensus.ICustomerDat return } +func byteToReqs(data []byte) []interface{} { + lastReqList := requestList{} + err := json.Unmarshal(data, &lastReqList) + + var srvReqs []interface{} + if !reflect.DeepEqual(lastReqList, requestList{}) { + srvReqs = make([]interface{}, len(lastReqList.Requests)) + for i, req := range lastReqList.Requests { + srvReq := serviceRequest.Entity{} + err = json.Unmarshal(req, &srvReq) + if err != nil { + log.Log.Error("deserialize consensus data failed: ", err.Error()) + continue + } + + srvReqs[i] = srvReq + } + } + return srvReqs +} + var ConsensusProcessor consensusProcessor diff --git a/engine/engineService/mountedServiceExecutor.go b/engine/engineService/mountedServiceExecutor.go index 70df4f8..aa25438 100644 --- a/engine/engineService/mountedServiceExecutor.go +++ b/engine/engineService/mountedServiceExecutor.go @@ -50,7 +50,7 @@ func getService(name string) (s service.IService, err error) { return } -func preExecuteServiceRequest(req serviceRequest.Entity) (result []byte, err error) { +func preExecuteServiceRequest(req serviceRequest.Entity, lastReq []interface{}) (result []byte, err error) { serviceLock.Lock() defer serviceLock.Unlock() @@ -59,7 +59,7 @@ func preExecuteServiceRequest(req serviceRequest.Entity) (result []byte, err err return } - return s.PreExecute(req) + return s.PreExecute(req, lastReq) } func executeServiceRequest(req serviceRequest.Entity) (result []byte, err error) { diff --git a/service/application/smartAssets/smartAssetsLedger/ledger.go b/service/application/smartAssets/smartAssetsLedger/ledger.go index fad4340..444b5c4 100644 --- a/service/application/smartAssets/smartAssetsLedger/ledger.go +++ b/service/application/smartAssets/smartAssetsLedger/ledger.go @@ -165,74 +165,6 @@ func (l *Ledger) NewStateAndLoadGenesisAssets(owner []byte, assets BaseAssetsDat return } -//func (l *Ledger) LoadGenesisAssets(owner []byte, assets BaseAssetsData) error { -// _, exists, err := l.getSystemAssets() -// if err != nil { -// return err -// } -// -// if exists { -// return nil -// } -// -// //if not exists, create -// supply := assets.Supply -// assets.Supply = "0" -// -// if len(owner) == 0 { -// return errors.New("no owner for system assets") -// } -// -// signer, err := l.CryptoTools.SignerGenerator.NewSigner(nil) -// if err != nil { -// return err -// } -// -// pk := signer.PrivateKeyBytes() -// metaBytes, _ := structSerializer.ToMFBytes(assets) -// metaSeal := seal.Entity{} -// err = metaSeal.Sign(metaBytes, l.CryptoTools, pk) -// if err != nil { -// return err -// } -// -// assets.Supply = supply -// issuedBytes, _ := structSerializer.ToMFBytes(assets) -// issuedSeal := seal.Entity{} -// err = issuedSeal.Sign(issuedBytes, l.CryptoTools, pk) -// if err != nil { -// return err -// } -// -// sysAssets := BaseAssets{ -// BaseAssetsData: assets, -// IssuedSeal: issuedSeal, -// MetaSeal: metaSeal, -// } -// -// err = l.storeSystemAssets(sysAssets) -// if err != nil { -// return err -// } -// -// balance, valid := big.NewInt(0).SetString(assets.Supply, 10) -// if !valid { -// return errors.New("invalid assets supply") -// } -// -// if balance.Sign() <= 0 { -// return errors.New("supply is zero or negative") -// } -// -// err = l.Storage.Put(kvDatabase.KVItem{ -// Key: BuildKey(StoragePrefixes.Balance, owner), -// Data: balance.Bytes(), -// Exists: false, -// }) -// -// return err -//} - func (l *Ledger) AddTx(req blockchainRequest.Entity) error { tx := Transaction{} err := json.Unmarshal(req.Data, &tx) diff --git a/service/service.go b/service/service.go index d570822..a33276d 100644 --- a/service/service.go +++ b/service/service.go @@ -76,7 +76,7 @@ type IService interface { RequestsForConsensus(lastReqs []interface{}) (req [][]byte, cnt uint32) //receive and verify request from consensus network (on the other word, this request comes from consensus leader) - PreExecute(req interface{}) (result []byte, err error) + PreExecute(req interface{}, lastReqs []interface{}) (result []byte, err error) //receive and execute confirmed request of this round of consensus Execute(req interface{}) (result []byte, err error) @@ -104,7 +104,7 @@ func (b BlankService) RequestsForConsensus(lastReqs []interface{}) (req [][]byte return } -func (b BlankService) PreExecute(req interface{}) (result []byte, err error) { +func (b BlankService) PreExecute(req interface{}, lastReqs []interface{}) (result []byte, err error) { return } diff --git a/service/system/blockchain/chainStructure/chain.go b/service/system/blockchain/chainStructure/chain.go index 39630c2..d8cdb84 100644 --- a/service/system/blockchain/chainStructure/chain.go +++ b/service/system/blockchain/chainStructure/chain.go @@ -28,7 +28,8 @@ type Blockchain struct { Config Config Executor applicationExecutor - lastBlock *block.Entity + lastBlock *block.Entity + SQLStorage *chainSQLStorage.Storage currentHeight uint64 operateLock sync.RWMutex diff --git a/service/system/blockchain/serviceInterface/serviceInterface.go b/service/system/blockchain/serviceInterface/serviceInterface.go index 2592936..7c13d54 100644 --- a/service/system/blockchain/serviceInterface/serviceInterface.go +++ b/service/system/blockchain/serviceInterface/serviceInterface.go @@ -127,7 +127,7 @@ func (b *BlockchainService) RequestsForConsensus(lastReqs []interface{}) (req [] return } -func (b *BlockchainService) verifyBlock(blk block.Entity) (err error) { +func (b *BlockchainService) verifyBlock(blk block.Entity, lastReqs []interface{}) (err error) { //verify block _, err = blk.Verify(b.chain.Config.CryptoTools) if err != nil { @@ -140,7 +140,22 @@ func (b *BlockchainService) verifyBlock(blk block.Entity) (err error) { return } - lastBlk := b.chain.GetLastBlock() + var lastBlk *block.Entity + for _, lastReq := range lastReqs { + blk, err := b.getNewBlockRequestFromConsensus(lastReq) + if err != nil { + continue + } + if lastBlk == nil { + lastBlk = &blk + } else if blk.Header.Height > lastBlk.Header.Height { + lastBlk = &blk + } + } + if lastBlk == nil { + lastBlk = b.chain.GetLastBlock() + } + if lastBlk == nil { return } @@ -161,13 +176,13 @@ func (b *BlockchainService) verifyBlock(blk block.Entity) (err error) { } //handle the new block received from consensus -func (b *BlockchainService) PreExecute(data interface{}) (result []byte, err error) { +func (b *BlockchainService) PreExecute(data interface{}, lastReqs []interface{}) (result []byte, err error) { blk, err := b.getNewBlockRequestFromConsensus(data) if err != nil { return } - err = b.verifyBlock(blk) + err = b.verifyBlock(blk, lastReqs) if err != nil { return } @@ -200,7 +215,7 @@ func (b *BlockchainService) Execute(data interface{}) (result []byte, err error) return } - err = b.verifyBlock(blk) + err = b.verifyBlock(blk, nil) if err != nil { return } From 121b614fee5fcdfb548bacd254a966ee0df1212c Mon Sep 17 00:00:00 2001 From: bianning Date: Wed, 20 Jul 2022 10:04:19 +0800 Subject: [PATCH 13/20] feat: verify remote root --- dataStructure/state/statedb.go | 7 +- metadata/block/entity.go | 2 +- metadata/seal/entity.go | 1 + .../smartAssetsInterface.go | 10 +-- .../smartAssets/smartAssetsLedger/ledger.go | 84 +++++++++++++------ .../blockchain/chainStructure/blockBuilder.go | 12 ++- .../blockchain/chainStructure/operator.go | 7 -- 7 files changed, 76 insertions(+), 47 deletions(-) diff --git a/dataStructure/state/statedb.go b/dataStructure/state/statedb.go index cd9c207..68e3418 100644 --- a/dataStructure/state/statedb.go +++ b/dataStructure/state/statedb.go @@ -83,7 +83,8 @@ func (s *StateDB) Empty(addr common.Address) bool { func (s *StateDB) GetBalance(addr common.Address) *big.Int { stateObject := s.getStateObject(addr) if stateObject != nil { - return stateObject.Balance() + + return new(big.Int).Set(stateObject.Balance()) } return common.Big0 } @@ -321,8 +322,8 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) { } } -func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { - s.Finalise(deleteEmptyObjects) +func (s *StateDB) IntermediateRoot() common.Hash { + s.Finalise(true) return s.trie.Hash() } diff --git a/metadata/block/entity.go b/metadata/block/entity.go index f482e32..f7a4e8f 100644 --- a/metadata/block/entity.go +++ b/metadata/block/entity.go @@ -27,7 +27,7 @@ type Header struct { Height uint64 PrevBlock []byte TransactionsRoot []byte - StateRoot []byte + StateRoot map[string][]byte Timestamp uint64 } diff --git a/metadata/seal/entity.go b/metadata/seal/entity.go index c1724c8..b24b420 100644 --- a/metadata/seal/entity.go +++ b/metadata/seal/entity.go @@ -28,6 +28,7 @@ import ( type Entity struct { Hash []byte + Root []byte Signature []byte SignerPublicKey []byte SignerAlgorithm string diff --git a/service/application/smartAssets/smartAssetsInterface/smartAssetsInterface.go b/service/application/smartAssets/smartAssetsInterface/smartAssetsInterface.go index 5ad1d4d..77ac29f 100644 --- a/service/application/smartAssets/smartAssetsInterface/smartAssetsInterface.go +++ b/service/application/smartAssets/smartAssetsInterface/smartAssetsInterface.go @@ -92,9 +92,7 @@ func (s *SmartAssetsApplication) Execute( return } - _, root, err := s.ledger.Execute(txList, blk) - - result.Data = root + _, _, err = s.ledger.Execute(txList, blk) if err == nil && s.sqlStorage != nil { for _, tx := range txList.Transactions { @@ -106,8 +104,7 @@ func (s *SmartAssetsApplication) Execute( } func (s *SmartAssetsApplication) RequestsForBlock(blk block.Entity) (reqList []blockchainRequest.Entity, cnt uint32) { - txList, cnt, txRoot := s.ledger.GetTransactionsFromPool(blk) - + txList, cnt, txRoot, stateRoot := s.ledger.GetTransactionsFromPool(blk) if cnt == 0 { return } @@ -125,6 +122,7 @@ func (s *SmartAssetsApplication) RequestsForBlock(blk block.Entity) (reqList []b PackedCount: cnt, Seal: seal.Entity{ Hash: txRoot, //use merkle tree root as seal hash for packed actions + Root: stateRoot, Signature: nil, SignerPublicKey: nil, SignerAlgorithm: "", @@ -196,7 +194,7 @@ func NewApplicationInterface( ) (app chainStructure.IBlockchainExternalApplication, err error) { sa := SmartAssetsApplication{} - sa.ledger = smartAssetsLedger.NewLedger(tools, kvDriver) + sa.ledger = smartAssetsLedger.NewLedger(tools, kvDriver, sa.Name()) if sqlDriver != nil { sa.sqlStorage = smartAssetsSQLStorage.NewStorage(sqlDriver) diff --git a/service/application/smartAssets/smartAssetsLedger/ledger.go b/service/application/smartAssets/smartAssetsLedger/ledger.go index 444b5c4..8fedf68 100644 --- a/service/application/smartAssets/smartAssetsLedger/ledger.go +++ b/service/application/smartAssets/smartAssetsLedger/ledger.go @@ -59,6 +59,8 @@ type Ledger struct { storageForEVM contractStorage StateDB *state.StateDB + + applicationName string } func Load() { @@ -73,7 +75,12 @@ func (l *Ledger) SetChain(chain chainStructure.IChainInterface) { l.chain = chain if chain.GetLastBlock() != nil { - stateRoot := common.BytesToHash(chain.GetLastBlock().Header.StateRoot) + root, exist := chain.GetLastBlock().Header.StateRoot[l.applicationName] + if !exist { + log.Log.Error("Failed to reset txpool state") + return + } + stateRoot := common.BytesToHash(root) stateDB, err := state.New(stateRoot, state.NewDatabase(l.Storage), l.CryptoTools, &AccountTool{}) if err != nil { log.Log.Error("Failed to reset txpool state", "err", err) @@ -244,7 +251,7 @@ func (l Ledger) txResultCheck(orgResult TransactionResult, execResult Transactio return nil } -func (l Ledger) PreExecute(txList TransactionList, blk block.Entity) (result []byte, err error) { +func (l Ledger) PreExecute(txList TransactionList, blk block.Entity) (root []byte, err error) { l.poolLock.Lock() defer l.poolLock.Unlock() @@ -263,6 +270,8 @@ func (l Ledger) PreExecute(txList TransactionList, blk block.Entity) (result []b }, } + stateDB := l.StateDB.Copy() + for _, tx := range txList.Transactions { hash := string(tx.DataSeal.Hash) if _, exists := txHash[hash]; !exists { @@ -285,11 +294,22 @@ func (l Ledger) PreExecute(txList TransactionList, blk block.Entity) (result []b checkErr := l.txResultCheck(tx.TransactionResult, txForCheck.TransactionResult, tx.getHash()) if checkErr != nil { err = checkErr + log.Log.Printf("tx err: %v", err) break } + + switch tx.Type { + case TxType.Transfer.String(): + l.setTransferState(tx.TransactionResult.NewState, stateDB) + } } } + root = stateDB.IntermediateRoot().Bytes() + stateRoot := blk.Header.StateRoot[l.applicationName] + if !bytes.Equal(root, stateRoot) { + err = fmt.Errorf("invalid merkle root (remote: %x local: %x)", stateRoot, root) + } return } @@ -316,17 +336,7 @@ func (l *Ledger) Execute(txList TransactionList, blk block.Entity) (result []byt switch tx.Type { case TxType.Transfer.String(): - for i, s := range tx.TransactionResult.NewState { - balance := big.NewInt(0) - balance.SetBytes(s.NewVal) - - address := common.BytesToAddress(s.Key) - - l.StateDB.SetBalance(address, balance) - if i == 0 { //From - l.StateDB.SetNonce(address, l.StateDB.GetNonce(address)+1) - } - } + l.setTransferState(tx.TransactionResult.NewState, l.StateDB) default: for _, s := range tx.TransactionResult.NewState { batch.Put(s.Key, s.NewVal) @@ -350,7 +360,21 @@ func (l *Ledger) Execute(txList TransactionList, blk block.Entity) (result []byt return } -func (l Ledger) setTxNewState(err error, newState []StateData, tx *Transaction) { +func (l *Ledger) setTransferState(s []StateData, state *state.StateDB) { + for i, s := range s { + balance := big.NewInt(0) + balance.SetBytes(s.NewVal) + + address := common.BytesToAddress(s.Key) + + state.SetBalance(address, balance) + if i == 0 { //From + state.SetNonce(address, state.GetNonce(address)+1) + } + } +} + +func (l *Ledger) setTxNewState(err error, newState []StateData, tx *Transaction) { errEl := err.(enum.ErrorElement) if errEl != Errors.Success { @@ -362,12 +386,11 @@ func (l Ledger) setTxNewState(err error, newState []StateData, tx *Transaction) } } -func (l Ledger) GetTransactionsFromPool(blk block.Entity) (txList TransactionList, count uint32, txRoot []byte) { +func (l *Ledger) GetTransactionsFromPool(blk block.Entity) (txList TransactionList, count uint32, txRoot []byte, stateRoot []byte) { l.poolLock.Lock() defer l.poolLock.Unlock() txs := l.txPool.Pending() - count = uint32(len(txs)) if count == 0 { return @@ -387,6 +410,7 @@ func (l Ledger) GetTransactionsFromPool(blk block.Entity) (txList TransactionLis }, } + stateDB := l.StateDB.Copy() mt := merkleTree.Tree{} for idx, tx := range txs { @@ -400,13 +424,18 @@ func (l Ledger) GetTransactionsFromPool(blk block.Entity) (txList TransactionLis tx.TransactionResult.ReturnData = resultCache[CachedContractReturnData].Data tx.TransactionResult.NewAddress = resultCache[CachedContractCreationAddress].address + + switch tx.Type { + case TxType.Transfer.String(): + l.setTransferState(tx.TransactionResult.NewState, stateDB) + } } txList.Transactions = append(txList.Transactions, *tx) } txRoot, _ = mt.Calculate() - + stateRoot = stateDB.IntermediateRoot().Bytes() return } @@ -418,17 +447,18 @@ func (l *Ledger) DoQuery(req QueryRequest) (interface{}, error) { return nil, Errors.InvalidQuery } -func NewLedger(tools crypto.Tools, driver kvDatabase.IDriver) *Ledger { +func NewLedger(tools crypto.Tools, driver kvDatabase.IDriver, applicationName string) *Ledger { l := &Ledger{ - txPool: NewTxPool(), - txPoolLimit: 1000, - clientTxCount: map[string]int{}, - clientTxLimit: 4, - operateLock: sync.RWMutex{}, - poolLock: sync.Mutex{}, - genesisAssets: BaseAssets{}, - CryptoTools: tools, - Storage: driver, + txPool: NewTxPool(), + txPoolLimit: 1000, + clientTxCount: map[string]int{}, + clientTxLimit: 4, + operateLock: sync.RWMutex{}, + poolLock: sync.Mutex{}, + genesisAssets: BaseAssets{}, + CryptoTools: tools, + Storage: driver, + applicationName: applicationName, } l.storageForEVM.basedLedger = l diff --git a/service/system/blockchain/chainStructure/blockBuilder.go b/service/system/blockchain/chainStructure/blockBuilder.go index 98c3fe4..8d4e4ac 100644 --- a/service/system/blockchain/chainStructure/blockBuilder.go +++ b/service/system/blockchain/chainStructure/blockBuilder.go @@ -30,6 +30,7 @@ func (b *Blockchain) buildBasicBlock(requests []blockchainRequest.Entity) (newBl newBlock.Header.Version = "1" newBlock.Body.RequestsCount = len(requests) + newBlock.Header.StateRoot = make(map[string][]byte) for _, req := range requests { if req.Packed { @@ -62,7 +63,6 @@ func (b *Blockchain) NewBlankBlock() (newBlock block.Entity) { //set block prev hash newBlock.Header.PrevBlock = append([]byte{}, b.lastBlock.Seal.Hash...) - newBlock.Header.StateRoot = b.lastBlock.Header.StateRoot } //set block hash @@ -80,17 +80,23 @@ func (b *Blockchain) NewBlock(requests []blockchainRequest.Entity, blankBlock bl newBlock = b.buildBasicBlock(requests) newBlock.Header.Timestamp = blankBlock.Header.Timestamp newBlock.BlankSeal = blankBlock.BlankSeal - newBlock.Header.StateRoot = blankBlock.Header.StateRoot - + //set block height if lastBlock != nil { newBlock.Header.Height = lastBlock.Header.Height + 1 newBlock.Header.PrevBlock = append([]byte{}, lastBlock.Seal.Hash...) + newBlock.Header.StateRoot = lastBlock.Header.StateRoot + } else if b.lastBlock != nil { newBlock.Header.Height = b.lastBlock.Header.Height + 1 //set block prev hash newBlock.Header.PrevBlock = append([]byte{}, b.lastBlock.Seal.Hash...) + newBlock.Header.StateRoot = b.lastBlock.Header.StateRoot + } + + for _, req := range requests { + newBlock.Header.StateRoot[req.RequestApplication] = req.Seal.Root } //set block hash diff --git a/service/system/blockchain/chainStructure/operator.go b/service/system/blockchain/chainStructure/operator.go index 07e01cf..8df5481 100644 --- a/service/system/blockchain/chainStructure/operator.go +++ b/service/system/blockchain/chainStructure/operator.go @@ -22,7 +22,6 @@ import ( "encoding/hex" "encoding/json" "errors" - "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/log" "github.com/SealSC/SealABC/metadata/block" "github.com/SealSC/SealABC/metadata/blockchainRequest" @@ -35,12 +34,6 @@ const lastBlockKey = "lastBlockKey" func (b *Blockchain) executeRequest(blk *block.Entity) (err error) { for idx, req := range blk.Body.Requests { appRet, exeErr := b.Executor.ExecuteRequest(req, *blk, uint32(idx)) - - switch appRet.Data.(type) { - case common.Hash: - blk.Header.StateRoot = (appRet.Data).(common.Hash).Bytes() - } - if exeErr != nil { err = exeErr break From a882eb42842f843ec9d29fb9557cef55e3320839 Mon Sep 17 00:00:00 2001 From: bianning Date: Wed, 20 Jul 2022 14:16:33 +0800 Subject: [PATCH 14/20] refactor: change address to common.Address --- account/account.go | 9 +++++---- account/store.go | 3 ++- common/types.go | 3 +++ .../smartAssets/smartAssetsLedger/assets.go | 8 ++++---- .../smartAssetsLedger/evmAdapter.go | 5 +++-- .../smartAssets/smartAssetsLedger/ledger.go | 2 +- .../operationForContractCreation.go | 3 ++- .../smartAssetsLedger/operationForQuery.go | 5 +++-- .../smartAssetsLedger/operationForTransfer.go | 19 ++++++++++--------- .../smartAssets/smartAssetsLedger/storage.go | 5 +++-- .../smartAssetsLedger/transaction.go | 10 +++++----- .../smartAssets/smartAssetsLedger/txpool.go | 13 +++++-------- .../smartAssetsSQLTables/contract.go | 4 ++-- .../smartAssetsSQLTables/contractCall.go | 4 ++-- .../smartAssetsSQLTables/transaction.go | 4 ++-- .../smartAssetsSQLTables/transfer.go | 4 ++-- 16 files changed, 54 insertions(+), 47 deletions(-) diff --git a/account/account.go b/account/account.go index aee6781..a17019c 100644 --- a/account/account.go +++ b/account/account.go @@ -18,6 +18,7 @@ package account import ( + "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/crypto/ciphers/cipherCommon" "github.com/SealSC/SealABC/crypto/signers" "github.com/SealSC/SealABC/crypto/signers/signerCommon" @@ -37,7 +38,7 @@ type StoreConfig struct { } type Encrypted struct { - Address string + Address common.Address Data cipherCommon.EncryptedData Config StoreConfig } @@ -48,7 +49,7 @@ type accountDataForEncrypt struct { } type SealAccount struct { - Address string + Address common.Address SingerType string Signer signerCommon.ISigner } @@ -60,7 +61,7 @@ func NewAccount(privateKey []byte, sg signers.ISignerGenerator) (sa SealAccount, return } - sa.Address = signer.PublicKeyString() + sa.Address = common.BytesToAddress(signer.PublicKeyBytes()) sa.SingerType = signer.Type() sa.Signer = signer return @@ -72,7 +73,7 @@ func NewAccountForVerify(publicKey []byte, sg signers.ISignerGenerator) (sa Seal return } - sa.Address = signer.PublicKeyString() + sa.Address = common.BytesToAddress(signer.PublicKeyBytes()) sa.SingerType = signer.Type() sa.Signer = signer diff --git a/account/store.go b/account/store.go index 71639a7..3cb4f33 100644 --- a/account/store.go +++ b/account/store.go @@ -18,6 +18,7 @@ package account import ( + "bytes" "encoding/json" "errors" "github.com/SealSC/SealABC/crypto/ciphers" @@ -108,7 +109,7 @@ func (s *SealAccount) FromStore(filename string, password string) (sa SealAccoun return } - if signer.PublicKeyString() != encAccount.Address { + if !bytes.Equal(signer.PublicKeyBytes(), encAccount.Address.Bytes()) { err = errors.New("address not equal") return } diff --git a/common/types.go b/common/types.go index ece94d1..adf31f9 100644 --- a/common/types.go +++ b/common/types.go @@ -55,3 +55,6 @@ func (a *Address) SetBytes(b []byte) { } copy(a[AddressLength-len(b):], b) } + +func (a *Address) Bytes() []byte { return a[:] } +func (a *Address) String() string { return string(a.Bytes()) } diff --git a/service/application/smartAssets/smartAssetsLedger/assets.go b/service/application/smartAssets/smartAssetsLedger/assets.go index d6e6aea..7163a03 100644 --- a/service/application/smartAssets/smartAssetsLedger/assets.go +++ b/service/application/smartAssets/smartAssetsLedger/assets.go @@ -45,13 +45,13 @@ func (b *BaseAssets) getHash() []byte { return b.MetaSeal.Hash } -func (l *Ledger) BalanceOf(address []byte) (balance *big.Int, err error) { - balance = l.StateDB.GetBalance(common.BytesToAddress(address)) +func (l *Ledger) BalanceOf(address common.Address) (balance *big.Int, err error) { + balance = l.StateDB.GetBalance(address) return } -func (l *Ledger) NonceOf(address []byte) (nonce uint64) { - nonce = l.StateDB.GetNonce(common.BytesToAddress(address)) +func (l *Ledger) NonceOf(address common.Address) (nonce uint64) { + nonce = l.StateDB.GetNonce(address) return } diff --git a/service/application/smartAssets/smartAssetsLedger/evmAdapter.go b/service/application/smartAssets/smartAssetsLedger/evmAdapter.go index 7eb930c..132ae06 100644 --- a/service/application/smartAssets/smartAssetsLedger/evmAdapter.go +++ b/service/application/smartAssets/smartAssetsLedger/evmAdapter.go @@ -20,6 +20,7 @@ package smartAssetsLedger import ( "bytes" "fmt" + c "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/metadata/block" "github.com/SealSC/SealEVM" "github.com/SealSC/SealEVM/common" @@ -58,7 +59,7 @@ func (l Ledger) newEVM(tx Transaction, callback SealEVM.EVMResultCallback, contractAddress = l.storageForEVM.CreateAddress(caller, evmTransaction) contractCode = tx.Data } else { - contractAddress = common.BytesDataToEVMIntHash(tx.To) + contractAddress = common.BytesDataToEVMIntHash(tx.To.Bytes()) codeData, err := l.storageForEVM.GetCode(contractAddress) if err != nil { return nil, nil, Errors.ContractNotFound.NewErrorWithNewMessage(err.Error()) @@ -116,7 +117,7 @@ func (l Ledger) processEVMBalanceCache(cache storage.BalanceCache, resultCache t if resultCache[string(addr)] != nil { localBalance = resultCache[string(addr)].val } else { - localBalance, err = l.BalanceOf(addr) + localBalance, err = l.BalanceOf(c.BytesToAddress(addr)) if err != nil { continue } diff --git a/service/application/smartAssets/smartAssetsLedger/ledger.go b/service/application/smartAssets/smartAssetsLedger/ledger.go index 8fedf68..7c23546 100644 --- a/service/application/smartAssets/smartAssetsLedger/ledger.go +++ b/service/application/smartAssets/smartAssetsLedger/ledger.go @@ -183,7 +183,7 @@ func (l *Ledger) AddTx(req blockchainRequest.Entity) error { return errors.New("transaction type is not equal to block request action") } - if !bytes.Equal(tx.From, tx.DataSeal.SignerPublicKey) { + if !bytes.Equal(tx.From.Bytes(), tx.DataSeal.SignerPublicKey) { return errors.New("invalid sender") } diff --git a/service/application/smartAssets/smartAssetsLedger/operationForContractCreation.go b/service/application/smartAssets/smartAssetsLedger/operationForContractCreation.go index 41afa58..ec4b5c9 100644 --- a/service/application/smartAssets/smartAssetsLedger/operationForContractCreation.go +++ b/service/application/smartAssets/smartAssetsLedger/operationForContractCreation.go @@ -18,6 +18,7 @@ package smartAssetsLedger import ( + "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/metadata/block" "github.com/SealSC/SealEVM/evmInt256" "github.com/SealSC/SealEVM/opcodes" @@ -62,7 +63,7 @@ func (l *Ledger) preContractCreation(tx Transaction, cache txResultCache, blk bl return nil, nil, Errors.ContractCreationFailed.NewErrorWithNewMessage(err.Error()) } - cache[CachedContractCreationAddress].address = contract.Namespace.Bytes() + cache[CachedContractCreationAddress].address = common.BytesToAddress(contract.Namespace.Bytes()) cache[CachedContractReturnData].Data = ret.ResultData return newState, cache, Errors.Success } diff --git a/service/application/smartAssets/smartAssetsLedger/operationForQuery.go b/service/application/smartAssets/smartAssetsLedger/operationForQuery.go index 97551f8..fd3c0d8 100644 --- a/service/application/smartAssets/smartAssetsLedger/operationForQuery.go +++ b/service/application/smartAssets/smartAssetsLedger/operationForQuery.go @@ -20,6 +20,7 @@ package smartAssetsLedger import ( "encoding/hex" "encoding/json" + "github.com/SealSC/SealABC/common" ) func (l *Ledger) queryBaseAssets(_ QueryRequest) (interface{}, error) { @@ -37,7 +38,7 @@ func (l *Ledger) queryBalance(req QueryRequest) (interface{}, error) { return nil, Errors.InvalidParameter.NewErrorWithNewMessage(err.Error()) } - balance, err := l.BalanceOf(addr) + balance, err := l.BalanceOf(common.BytesToAddress(addr)) if err != nil { return nil, Errors.DBError.NewErrorWithNewMessage(err.Error()) } @@ -56,7 +57,7 @@ func (l *Ledger) queryNonce(req QueryRequest) (interface{}, error) { return nil, Errors.InvalidParameter.NewErrorWithNewMessage(err.Error()) } - nonce := l.NonceOf(addr) + nonce := l.NonceOf(common.BytesToAddress(addr)) return nonce, nil } diff --git a/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go b/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go index 7ac6aeb..b2c39fb 100644 --- a/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go +++ b/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go @@ -18,21 +18,22 @@ package smartAssetsLedger import ( + "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/metadata/block" "math/big" ) var bigZero = big.NewInt(0) -func (l *Ledger) getBalance(addr []byte, cache txResultCache) (*big.Int, error) { - addrStr := string(addr) - if cache[addrStr] != nil { - return cache[addrStr].val, nil +func (l *Ledger) getBalance(addr common.Address, cache txResultCache) (*big.Int, error) { + addStr := addr.String() + if cache[addStr] != nil { + return cache[addStr].val, nil } balance, err := l.BalanceOf(addr) if err == nil { - cache[addrStr] = &txResultCacheData{ + cache[addStr] = &txResultCacheData{ val: balance, } } @@ -85,18 +86,18 @@ func (l *Ledger) preTransfer(tx Transaction, cache txResultCache, _ block.Entity fromBalance.Sub(fromBalance, amount) toBalance.Add(toBalance, amount) - cache[string(tx.From)].val = fromBalance - cache[string(tx.To)].val = toBalance + cache[tx.From.String()].val = fromBalance + cache[tx.To.String()].val = toBalance statusToChange := []StateData{ { - Key: tx.From, + Key: tx.From.Bytes(), NewVal: fromBalance.Bytes(), OrgVal: orgFromBalance, }, { - Key: tx.To, + Key: tx.To.Bytes(), NewVal: toBalance.Bytes(), OrgVal: orgToBalance, }, diff --git a/service/application/smartAssets/smartAssetsLedger/storage.go b/service/application/smartAssets/smartAssetsLedger/storage.go index 6710499..7de3ea0 100644 --- a/service/application/smartAssets/smartAssetsLedger/storage.go +++ b/service/application/smartAssets/smartAssetsLedger/storage.go @@ -19,6 +19,7 @@ package smartAssetsLedger import ( "errors" + "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" "github.com/SealSC/SealABC/dataStructure/enum" "github.com/SealSC/SealEVM/environment" @@ -81,7 +82,7 @@ type contractStorage struct { } func (c *contractStorage) GetBalance(address *evmInt256.Int) (*evmInt256.Int, error) { - balance, err := c.basedLedger.BalanceOf(address.Bytes()) + balance, err := c.basedLedger.BalanceOf(common.BytesToAddress(address.Bytes())) var ret *evmInt256.Int if err == nil { @@ -91,7 +92,7 @@ func (c *contractStorage) GetBalance(address *evmInt256.Int) (*evmInt256.Int, er } func (c *contractStorage) CanTransfer(from, to, val *evmInt256.Int) bool { - balance, err := c.basedLedger.BalanceOf(from.Bytes()) + balance, err := c.basedLedger.BalanceOf(common.BytesToAddress(from.Bytes())) if err != nil { return false } diff --git a/service/application/smartAssets/smartAssetsLedger/transaction.go b/service/application/smartAssets/smartAssetsLedger/transaction.go index 5a5fb8a..9083f38 100644 --- a/service/application/smartAssets/smartAssetsLedger/transaction.go +++ b/service/application/smartAssets/smartAssetsLedger/transaction.go @@ -58,8 +58,8 @@ func GetTxTypeCodeForName(name string) int { type TransactionData struct { Nonce uint64 Type string - From []byte - To []byte + From common.Address + To common.Address Value string Data []byte Memo string @@ -76,7 +76,7 @@ type TransactionResult struct { Success bool ErrorCode int64 SequenceNumber uint32 - NewAddress []byte + NewAddress common.Address ReturnData []byte NewState []StateData } @@ -111,7 +111,7 @@ func (t *Transaction) getCommonHash() common.Hash { } func (t *Transaction) verify(hashCalc hashes.IHashCalculator) (passed bool, err error) { - if !bytes.Equal(t.From, t.DataSeal.SignerPublicKey) { + if !bytes.Equal(t.From.Bytes(), t.DataSeal.SignerPublicKey) { return false, errors.New("invalid sender") } @@ -134,7 +134,7 @@ func (t *Transaction) verify(hashCalc hashes.IHashCalculator) (passed bool, err type txResultCacheData struct { val *big.Int gasLeft uint64 - address []byte + address common.Address Data []byte } diff --git a/service/application/smartAssets/smartAssetsLedger/txpool.go b/service/application/smartAssets/smartAssetsLedger/txpool.go index 0daa72f..b6c9886 100644 --- a/service/application/smartAssets/smartAssetsLedger/txpool.go +++ b/service/application/smartAssets/smartAssetsLedger/txpool.go @@ -66,7 +66,7 @@ func (pool *TxPool) addTx(tx *Transaction) error { } if !replaced { - pool.promoteExecutables(common.BytesToAddress(tx.From)) + pool.promoteExecutables(tx.From) } return nil @@ -80,8 +80,7 @@ func (pool *TxPool) add(tx *Transaction) (bool, error) { return false, err } - from := common.BytesToAddress(tx.From) - if list := pool.pending[from]; list != nil && list.Overlaps(tx) { + if list := pool.pending[tx.From]; list != nil && list.Overlaps(tx) { old := list.Add(tx) if old != nil { @@ -105,8 +104,7 @@ func (pool *TxPool) validateTx(tx *Transaction) error { return ErrNegativeValue } - from := common.BytesToAddress(tx.From) - if pool.currentState.GetNonce(from) > tx.Nonce { + if pool.currentState.GetNonce(tx.From) > tx.Nonce { return ErrNonceTooLow } @@ -158,8 +156,7 @@ func (pool *TxPool) removeTx(hash common.Hash) { if !ok { return } - addr := common.BytesToAddress(tx.From) - + addr := tx.From delete(pool.all, hash) if pending := pool.pending[addr]; pending != nil { @@ -188,7 +185,7 @@ func (pool *TxPool) removeTx(hash common.Hash) { } func (pool *TxPool) enqueueTx(hash common.Hash, tx *Transaction) (bool, error) { - from := common.BytesToAddress(tx.From) + from := tx.From if pool.queue[from] == nil { pool.queue[from] = newTxList(false) } diff --git a/service/application/smartAssets/smartAssetsSQLTables/contract.go b/service/application/smartAssets/smartAssetsSQLTables/contract.go index 5c75c85..1ecf972 100644 --- a/service/application/smartAssets/smartAssetsSQLTables/contract.go +++ b/service/application/smartAssets/smartAssetsSQLTables/contract.go @@ -81,9 +81,9 @@ func (t *ContractRows) Insert(tx smartAssetsLedger.Transaction, blk block.Entity Height: fmt.Sprintf("%d", blk.Header.Height), TxHash: hex.EncodeToString(tx.DataSeal.Hash), SequenceNumber: fmt.Sprintf("%d", tx.SequenceNumber), - Creator: hex.EncodeToString(tx.From), + Creator: hex.EncodeToString(tx.From.Bytes()), CreationData: hex.EncodeToString(tx.Data), - ContractAddress: hex.EncodeToString(tx.TransactionResult.NewAddress), + ContractAddress: hex.EncodeToString(tx.TransactionResult.NewAddress.Bytes()), ContractData: hex.EncodeToString(tx.TransactionResult.ReturnData), Memo: tx.Memo, Time: timestamp.Format(common.BASIC_TIME_FORMAT), diff --git a/service/application/smartAssets/smartAssetsSQLTables/contractCall.go b/service/application/smartAssets/smartAssetsSQLTables/contractCall.go index 0a97466..cc512dd 100644 --- a/service/application/smartAssets/smartAssetsSQLTables/contractCall.go +++ b/service/application/smartAssets/smartAssetsSQLTables/contractCall.go @@ -83,8 +83,8 @@ func (t *ContractCallRows) Insert(tx smartAssetsLedger.Transaction, blk block.En Height: fmt.Sprintf("%d", blk.Header.Height), TxHash: hex.EncodeToString(tx.DataSeal.Hash), SequenceNumber: fmt.Sprintf("%d", tx.SequenceNumber), - Caller: hex.EncodeToString(tx.From), - ContractAddress: hex.EncodeToString(tx.To), + Caller: hex.EncodeToString(tx.From.Bytes()), + ContractAddress: hex.EncodeToString(tx.To.Bytes()), Data: hex.EncodeToString(tx.Data), Result: string(result), Value: tx.Value, diff --git a/service/application/smartAssets/smartAssetsSQLTables/transaction.go b/service/application/smartAssets/smartAssetsSQLTables/transaction.go index d6756e4..3c41175 100644 --- a/service/application/smartAssets/smartAssetsSQLTables/transaction.go +++ b/service/application/smartAssets/smartAssetsSQLTables/transaction.go @@ -92,8 +92,8 @@ func (t *TransactionRows) Insert(tx smartAssetsLedger.Transaction, blk block.Ent Height: fmt.Sprintf("%d", blk.Header.Height), TxHash: hex.EncodeToString(tx.DataSeal.Hash), Type: tx.Type, - From: hex.EncodeToString(tx.From), - To: hex.EncodeToString(tx.To), + From: hex.EncodeToString(tx.From.Bytes()), + To: hex.EncodeToString(tx.To.Bytes()), Value: tx.Value, Data: hex.EncodeToString(tx.Data), Memo: tx.Memo, diff --git a/service/application/smartAssets/smartAssetsSQLTables/transfer.go b/service/application/smartAssets/smartAssetsSQLTables/transfer.go index b977cf1..f082c6c 100644 --- a/service/application/smartAssets/smartAssetsSQLTables/transfer.go +++ b/service/application/smartAssets/smartAssetsSQLTables/transfer.go @@ -79,8 +79,8 @@ func (t *TransferRows) Insert(tx smartAssetsLedger.Transaction, blk block.Entity Height: fmt.Sprintf("%d", blk.Header.Height), TxHash: hex.EncodeToString(tx.DataSeal.Hash), SequenceNumber: fmt.Sprintf("%d", tx.SequenceNumber), - From: hex.EncodeToString(tx.From), - To: hex.EncodeToString(tx.To), + From: hex.EncodeToString(tx.From.Bytes()), + To: hex.EncodeToString(tx.To.Bytes()), Value: tx.Value, Memo: tx.Memo, Time: timestamp.Format(common.BASIC_TIME_FORMAT), From b816c2d24f8b04f0ea666c88722f99d755352e5c Mon Sep 17 00:00:00 2001 From: bianning Date: Wed, 20 Jul 2022 20:23:24 +0800 Subject: [PATCH 15/20] revert: revert []byte --- common/types.go | 2 +- .../smartAssets/smartAssetsLedger/assets.go | 8 ++++---- .../smartAssetsLedger/evmAdapter.go | 5 ++--- .../smartAssets/smartAssetsLedger/ledger.go | 2 +- .../operationForContractCreation.go | 3 +-- .../smartAssetsLedger/operationForQuery.go | 5 ++--- .../smartAssetsLedger/operationForTransfer.go | 19 +++++++++---------- .../smartAssets/smartAssetsLedger/storage.go | 5 ++--- .../smartAssetsLedger/transaction.go | 10 +++++----- .../smartAssets/smartAssetsLedger/txpool.go | 13 ++++++++----- .../smartAssetsSQLTables/contract.go | 4 ++-- .../smartAssetsSQLTables/contractCall.go | 4 ++-- .../smartAssetsSQLTables/transaction.go | 4 ++-- .../smartAssetsSQLTables/transfer.go | 4 ++-- 14 files changed, 43 insertions(+), 45 deletions(-) diff --git a/common/types.go b/common/types.go index adf31f9..b9fe223 100644 --- a/common/types.go +++ b/common/types.go @@ -57,4 +57,4 @@ func (a *Address) SetBytes(b []byte) { } func (a *Address) Bytes() []byte { return a[:] } -func (a *Address) String() string { return string(a.Bytes()) } +func (a *Address) String() string { return hex.EncodeToString(a.Bytes()) } diff --git a/service/application/smartAssets/smartAssetsLedger/assets.go b/service/application/smartAssets/smartAssetsLedger/assets.go index 7163a03..d6e6aea 100644 --- a/service/application/smartAssets/smartAssetsLedger/assets.go +++ b/service/application/smartAssets/smartAssetsLedger/assets.go @@ -45,13 +45,13 @@ func (b *BaseAssets) getHash() []byte { return b.MetaSeal.Hash } -func (l *Ledger) BalanceOf(address common.Address) (balance *big.Int, err error) { - balance = l.StateDB.GetBalance(address) +func (l *Ledger) BalanceOf(address []byte) (balance *big.Int, err error) { + balance = l.StateDB.GetBalance(common.BytesToAddress(address)) return } -func (l *Ledger) NonceOf(address common.Address) (nonce uint64) { - nonce = l.StateDB.GetNonce(address) +func (l *Ledger) NonceOf(address []byte) (nonce uint64) { + nonce = l.StateDB.GetNonce(common.BytesToAddress(address)) return } diff --git a/service/application/smartAssets/smartAssetsLedger/evmAdapter.go b/service/application/smartAssets/smartAssetsLedger/evmAdapter.go index 132ae06..7eb930c 100644 --- a/service/application/smartAssets/smartAssetsLedger/evmAdapter.go +++ b/service/application/smartAssets/smartAssetsLedger/evmAdapter.go @@ -20,7 +20,6 @@ package smartAssetsLedger import ( "bytes" "fmt" - c "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/metadata/block" "github.com/SealSC/SealEVM" "github.com/SealSC/SealEVM/common" @@ -59,7 +58,7 @@ func (l Ledger) newEVM(tx Transaction, callback SealEVM.EVMResultCallback, contractAddress = l.storageForEVM.CreateAddress(caller, evmTransaction) contractCode = tx.Data } else { - contractAddress = common.BytesDataToEVMIntHash(tx.To.Bytes()) + contractAddress = common.BytesDataToEVMIntHash(tx.To) codeData, err := l.storageForEVM.GetCode(contractAddress) if err != nil { return nil, nil, Errors.ContractNotFound.NewErrorWithNewMessage(err.Error()) @@ -117,7 +116,7 @@ func (l Ledger) processEVMBalanceCache(cache storage.BalanceCache, resultCache t if resultCache[string(addr)] != nil { localBalance = resultCache[string(addr)].val } else { - localBalance, err = l.BalanceOf(c.BytesToAddress(addr)) + localBalance, err = l.BalanceOf(addr) if err != nil { continue } diff --git a/service/application/smartAssets/smartAssetsLedger/ledger.go b/service/application/smartAssets/smartAssetsLedger/ledger.go index 7c23546..8fedf68 100644 --- a/service/application/smartAssets/smartAssetsLedger/ledger.go +++ b/service/application/smartAssets/smartAssetsLedger/ledger.go @@ -183,7 +183,7 @@ func (l *Ledger) AddTx(req blockchainRequest.Entity) error { return errors.New("transaction type is not equal to block request action") } - if !bytes.Equal(tx.From.Bytes(), tx.DataSeal.SignerPublicKey) { + if !bytes.Equal(tx.From, tx.DataSeal.SignerPublicKey) { return errors.New("invalid sender") } diff --git a/service/application/smartAssets/smartAssetsLedger/operationForContractCreation.go b/service/application/smartAssets/smartAssetsLedger/operationForContractCreation.go index ec4b5c9..41afa58 100644 --- a/service/application/smartAssets/smartAssetsLedger/operationForContractCreation.go +++ b/service/application/smartAssets/smartAssetsLedger/operationForContractCreation.go @@ -18,7 +18,6 @@ package smartAssetsLedger import ( - "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/metadata/block" "github.com/SealSC/SealEVM/evmInt256" "github.com/SealSC/SealEVM/opcodes" @@ -63,7 +62,7 @@ func (l *Ledger) preContractCreation(tx Transaction, cache txResultCache, blk bl return nil, nil, Errors.ContractCreationFailed.NewErrorWithNewMessage(err.Error()) } - cache[CachedContractCreationAddress].address = common.BytesToAddress(contract.Namespace.Bytes()) + cache[CachedContractCreationAddress].address = contract.Namespace.Bytes() cache[CachedContractReturnData].Data = ret.ResultData return newState, cache, Errors.Success } diff --git a/service/application/smartAssets/smartAssetsLedger/operationForQuery.go b/service/application/smartAssets/smartAssetsLedger/operationForQuery.go index fd3c0d8..97551f8 100644 --- a/service/application/smartAssets/smartAssetsLedger/operationForQuery.go +++ b/service/application/smartAssets/smartAssetsLedger/operationForQuery.go @@ -20,7 +20,6 @@ package smartAssetsLedger import ( "encoding/hex" "encoding/json" - "github.com/SealSC/SealABC/common" ) func (l *Ledger) queryBaseAssets(_ QueryRequest) (interface{}, error) { @@ -38,7 +37,7 @@ func (l *Ledger) queryBalance(req QueryRequest) (interface{}, error) { return nil, Errors.InvalidParameter.NewErrorWithNewMessage(err.Error()) } - balance, err := l.BalanceOf(common.BytesToAddress(addr)) + balance, err := l.BalanceOf(addr) if err != nil { return nil, Errors.DBError.NewErrorWithNewMessage(err.Error()) } @@ -57,7 +56,7 @@ func (l *Ledger) queryNonce(req QueryRequest) (interface{}, error) { return nil, Errors.InvalidParameter.NewErrorWithNewMessage(err.Error()) } - nonce := l.NonceOf(common.BytesToAddress(addr)) + nonce := l.NonceOf(addr) return nonce, nil } diff --git a/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go b/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go index b2c39fb..7ac6aeb 100644 --- a/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go +++ b/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go @@ -18,22 +18,21 @@ package smartAssetsLedger import ( - "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/metadata/block" "math/big" ) var bigZero = big.NewInt(0) -func (l *Ledger) getBalance(addr common.Address, cache txResultCache) (*big.Int, error) { - addStr := addr.String() - if cache[addStr] != nil { - return cache[addStr].val, nil +func (l *Ledger) getBalance(addr []byte, cache txResultCache) (*big.Int, error) { + addrStr := string(addr) + if cache[addrStr] != nil { + return cache[addrStr].val, nil } balance, err := l.BalanceOf(addr) if err == nil { - cache[addStr] = &txResultCacheData{ + cache[addrStr] = &txResultCacheData{ val: balance, } } @@ -86,18 +85,18 @@ func (l *Ledger) preTransfer(tx Transaction, cache txResultCache, _ block.Entity fromBalance.Sub(fromBalance, amount) toBalance.Add(toBalance, amount) - cache[tx.From.String()].val = fromBalance - cache[tx.To.String()].val = toBalance + cache[string(tx.From)].val = fromBalance + cache[string(tx.To)].val = toBalance statusToChange := []StateData{ { - Key: tx.From.Bytes(), + Key: tx.From, NewVal: fromBalance.Bytes(), OrgVal: orgFromBalance, }, { - Key: tx.To.Bytes(), + Key: tx.To, NewVal: toBalance.Bytes(), OrgVal: orgToBalance, }, diff --git a/service/application/smartAssets/smartAssetsLedger/storage.go b/service/application/smartAssets/smartAssetsLedger/storage.go index 7de3ea0..6710499 100644 --- a/service/application/smartAssets/smartAssetsLedger/storage.go +++ b/service/application/smartAssets/smartAssetsLedger/storage.go @@ -19,7 +19,6 @@ package smartAssetsLedger import ( "errors" - "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" "github.com/SealSC/SealABC/dataStructure/enum" "github.com/SealSC/SealEVM/environment" @@ -82,7 +81,7 @@ type contractStorage struct { } func (c *contractStorage) GetBalance(address *evmInt256.Int) (*evmInt256.Int, error) { - balance, err := c.basedLedger.BalanceOf(common.BytesToAddress(address.Bytes())) + balance, err := c.basedLedger.BalanceOf(address.Bytes()) var ret *evmInt256.Int if err == nil { @@ -92,7 +91,7 @@ func (c *contractStorage) GetBalance(address *evmInt256.Int) (*evmInt256.Int, er } func (c *contractStorage) CanTransfer(from, to, val *evmInt256.Int) bool { - balance, err := c.basedLedger.BalanceOf(common.BytesToAddress(from.Bytes())) + balance, err := c.basedLedger.BalanceOf(from.Bytes()) if err != nil { return false } diff --git a/service/application/smartAssets/smartAssetsLedger/transaction.go b/service/application/smartAssets/smartAssetsLedger/transaction.go index 9083f38..5a5fb8a 100644 --- a/service/application/smartAssets/smartAssetsLedger/transaction.go +++ b/service/application/smartAssets/smartAssetsLedger/transaction.go @@ -58,8 +58,8 @@ func GetTxTypeCodeForName(name string) int { type TransactionData struct { Nonce uint64 Type string - From common.Address - To common.Address + From []byte + To []byte Value string Data []byte Memo string @@ -76,7 +76,7 @@ type TransactionResult struct { Success bool ErrorCode int64 SequenceNumber uint32 - NewAddress common.Address + NewAddress []byte ReturnData []byte NewState []StateData } @@ -111,7 +111,7 @@ func (t *Transaction) getCommonHash() common.Hash { } func (t *Transaction) verify(hashCalc hashes.IHashCalculator) (passed bool, err error) { - if !bytes.Equal(t.From.Bytes(), t.DataSeal.SignerPublicKey) { + if !bytes.Equal(t.From, t.DataSeal.SignerPublicKey) { return false, errors.New("invalid sender") } @@ -134,7 +134,7 @@ func (t *Transaction) verify(hashCalc hashes.IHashCalculator) (passed bool, err type txResultCacheData struct { val *big.Int gasLeft uint64 - address common.Address + address []byte Data []byte } diff --git a/service/application/smartAssets/smartAssetsLedger/txpool.go b/service/application/smartAssets/smartAssetsLedger/txpool.go index b6c9886..0daa72f 100644 --- a/service/application/smartAssets/smartAssetsLedger/txpool.go +++ b/service/application/smartAssets/smartAssetsLedger/txpool.go @@ -66,7 +66,7 @@ func (pool *TxPool) addTx(tx *Transaction) error { } if !replaced { - pool.promoteExecutables(tx.From) + pool.promoteExecutables(common.BytesToAddress(tx.From)) } return nil @@ -80,7 +80,8 @@ func (pool *TxPool) add(tx *Transaction) (bool, error) { return false, err } - if list := pool.pending[tx.From]; list != nil && list.Overlaps(tx) { + from := common.BytesToAddress(tx.From) + if list := pool.pending[from]; list != nil && list.Overlaps(tx) { old := list.Add(tx) if old != nil { @@ -104,7 +105,8 @@ func (pool *TxPool) validateTx(tx *Transaction) error { return ErrNegativeValue } - if pool.currentState.GetNonce(tx.From) > tx.Nonce { + from := common.BytesToAddress(tx.From) + if pool.currentState.GetNonce(from) > tx.Nonce { return ErrNonceTooLow } @@ -156,7 +158,8 @@ func (pool *TxPool) removeTx(hash common.Hash) { if !ok { return } - addr := tx.From + addr := common.BytesToAddress(tx.From) + delete(pool.all, hash) if pending := pool.pending[addr]; pending != nil { @@ -185,7 +188,7 @@ func (pool *TxPool) removeTx(hash common.Hash) { } func (pool *TxPool) enqueueTx(hash common.Hash, tx *Transaction) (bool, error) { - from := tx.From + from := common.BytesToAddress(tx.From) if pool.queue[from] == nil { pool.queue[from] = newTxList(false) } diff --git a/service/application/smartAssets/smartAssetsSQLTables/contract.go b/service/application/smartAssets/smartAssetsSQLTables/contract.go index 1ecf972..5c75c85 100644 --- a/service/application/smartAssets/smartAssetsSQLTables/contract.go +++ b/service/application/smartAssets/smartAssetsSQLTables/contract.go @@ -81,9 +81,9 @@ func (t *ContractRows) Insert(tx smartAssetsLedger.Transaction, blk block.Entity Height: fmt.Sprintf("%d", blk.Header.Height), TxHash: hex.EncodeToString(tx.DataSeal.Hash), SequenceNumber: fmt.Sprintf("%d", tx.SequenceNumber), - Creator: hex.EncodeToString(tx.From.Bytes()), + Creator: hex.EncodeToString(tx.From), CreationData: hex.EncodeToString(tx.Data), - ContractAddress: hex.EncodeToString(tx.TransactionResult.NewAddress.Bytes()), + ContractAddress: hex.EncodeToString(tx.TransactionResult.NewAddress), ContractData: hex.EncodeToString(tx.TransactionResult.ReturnData), Memo: tx.Memo, Time: timestamp.Format(common.BASIC_TIME_FORMAT), diff --git a/service/application/smartAssets/smartAssetsSQLTables/contractCall.go b/service/application/smartAssets/smartAssetsSQLTables/contractCall.go index cc512dd..0a97466 100644 --- a/service/application/smartAssets/smartAssetsSQLTables/contractCall.go +++ b/service/application/smartAssets/smartAssetsSQLTables/contractCall.go @@ -83,8 +83,8 @@ func (t *ContractCallRows) Insert(tx smartAssetsLedger.Transaction, blk block.En Height: fmt.Sprintf("%d", blk.Header.Height), TxHash: hex.EncodeToString(tx.DataSeal.Hash), SequenceNumber: fmt.Sprintf("%d", tx.SequenceNumber), - Caller: hex.EncodeToString(tx.From.Bytes()), - ContractAddress: hex.EncodeToString(tx.To.Bytes()), + Caller: hex.EncodeToString(tx.From), + ContractAddress: hex.EncodeToString(tx.To), Data: hex.EncodeToString(tx.Data), Result: string(result), Value: tx.Value, diff --git a/service/application/smartAssets/smartAssetsSQLTables/transaction.go b/service/application/smartAssets/smartAssetsSQLTables/transaction.go index 3c41175..d6756e4 100644 --- a/service/application/smartAssets/smartAssetsSQLTables/transaction.go +++ b/service/application/smartAssets/smartAssetsSQLTables/transaction.go @@ -92,8 +92,8 @@ func (t *TransactionRows) Insert(tx smartAssetsLedger.Transaction, blk block.Ent Height: fmt.Sprintf("%d", blk.Header.Height), TxHash: hex.EncodeToString(tx.DataSeal.Hash), Type: tx.Type, - From: hex.EncodeToString(tx.From.Bytes()), - To: hex.EncodeToString(tx.To.Bytes()), + From: hex.EncodeToString(tx.From), + To: hex.EncodeToString(tx.To), Value: tx.Value, Data: hex.EncodeToString(tx.Data), Memo: tx.Memo, diff --git a/service/application/smartAssets/smartAssetsSQLTables/transfer.go b/service/application/smartAssets/smartAssetsSQLTables/transfer.go index f082c6c..b977cf1 100644 --- a/service/application/smartAssets/smartAssetsSQLTables/transfer.go +++ b/service/application/smartAssets/smartAssetsSQLTables/transfer.go @@ -79,8 +79,8 @@ func (t *TransferRows) Insert(tx smartAssetsLedger.Transaction, blk block.Entity Height: fmt.Sprintf("%d", blk.Header.Height), TxHash: hex.EncodeToString(tx.DataSeal.Hash), SequenceNumber: fmt.Sprintf("%d", tx.SequenceNumber), - From: hex.EncodeToString(tx.From.Bytes()), - To: hex.EncodeToString(tx.To.Bytes()), + From: hex.EncodeToString(tx.From), + To: hex.EncodeToString(tx.To), Value: tx.Value, Memo: tx.Memo, Time: timestamp.Format(common.BASIC_TIME_FORMAT), From 02a3ad2fb04b4cc249133b98a7d28aca920ec7e4 Mon Sep 17 00:00:00 2001 From: bianning Date: Thu, 21 Jul 2022 20:16:58 +0800 Subject: [PATCH 16/20] update go.mod --- go.mod | 13 ++-------- go.sum | 82 +++++++++++++++------------------------------------------- 2 files changed, 23 insertions(+), 72 deletions(-) diff --git a/go.mod b/go.mod index ae36583..8062e04 100644 --- a/go.mod +++ b/go.mod @@ -4,24 +4,15 @@ go 1.16 require ( github.com/SealSC/SealEVM v0.0.0-20211210074038-1e2e076787df - github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847 // indirect - github.com/aws/aws-sdk-go v1.25.48 // indirect github.com/btcsuite/btcd v0.22.0-beta github.com/cbergoon/merkletree v0.2.0 - github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813 // indirect - github.com/ethereum/go-ethereum v1.10.13 // indirect + github.com/ethereum/go-ethereum v1.10.13 github.com/gin-gonic/gin v1.7.0 github.com/go-sql-driver/mysql v1.5.0 - github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222 // indirect - github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521 // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d github.com/sirupsen/logrus v1.7.0 - github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 // indirect - github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - github.com/urfave/cli v1.22.1 // indirect github.com/urfave/cli/v2 v2.3.0 - github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 // indirect golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b - golang.org/x/mobile v0.0.0-20200801112145-973feb4309de // indirect golang.org/x/sys v0.0.0-20211209171907-798191bca915 // indirect ) diff --git a/go.sum b/go.sum index 4d31b61..e466dc9 100644 --- a/go.sum +++ b/go.sum @@ -35,12 +35,10 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/SealSC/SealEVM v0.0.0-20201222102010-7455bc1355ac h1:BCJCtgwLgR42Y3R4jyxqLauimdx2skcKJxVFm3TLL0A= -github.com/SealSC/SealEVM v0.0.0-20201222102010-7455bc1355ac/go.mod h1:X8PnQGfXfYnYvQyO3mUBBKlMgAaXGWP/p67ez/+zr40= github.com/SealSC/SealEVM v0.0.0-20211210074038-1e2e076787df h1:+FZ8x6gUFS9BES5uAesIGg7pjuVKQa0XZEjz6OOHtTM= github.com/SealSC/SealEVM v0.0.0-20211210074038-1e2e076787df/go.mod h1:Ajd7Cqv2vC2TejqwJk0TBiXAWUEozMQ129wEi+t6JS8= +github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= @@ -49,8 +47,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= -github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= -github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= @@ -64,10 +60,9 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= -github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M= github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= +github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo= github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= @@ -91,7 +86,6 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= @@ -117,19 +111,14 @@ github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= -github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= -github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ethereum/go-ethereum v1.9.25 h1:mMiw/zOOtCLdGLWfcekua0qPrJTe7FVIiHJ4IKNTfR0= -github.com/ethereum/go-ethereum v1.9.25/go.mod h1:vMkFiYLHI4tgPw4k2j4MHKoovchFE8plZ0M9VMk4/oM= github.com/ethereum/go-ethereum v1.10.9/go.mod h1:CaTMQrv51WaAlD2eULQ3f03KiahDRO28fleQcKjWrrg= +github.com/ethereum/go-ethereum v1.10.13 h1:DEYFP9zk+Gruf3ae1JOJVhNmxK28ee+sMELPLgYTXpA= github.com/ethereum/go-ethereum v1.10.13/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw= -github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -151,6 +140,7 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= @@ -167,6 +157,7 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -188,14 +179,12 @@ github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:x github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3 h1:ur2rms48b3Ep1dxh7aUV2FZEQ8jEVO2F6ILKx8ofkAg= -github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -204,9 +193,9 @@ github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -220,26 +209,21 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= -github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= @@ -254,7 +238,6 @@ github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= @@ -265,7 +248,6 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= @@ -298,31 +280,28 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -331,8 +310,6 @@ github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -348,7 +325,6 @@ github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= -github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= @@ -369,20 +345,17 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -396,8 +369,6 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= -github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= -github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -405,29 +376,26 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= -github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4= github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= +github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= -github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -447,9 +415,9 @@ golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b h1:QAqMVf3pSa6eeTsuklijukjXBlj7Es2QQplab+/RbQ4= golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -457,7 +425,6 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= @@ -475,18 +442,15 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -501,13 +465,13 @@ golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -550,12 +514,9 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201221093633-bc327ba9c2f0 h1:n+DPcgTwkgWzIFpLmoimYR2K2b0Ga5+Os4kayIN0vGo= -golang.org/x/sys v0.0.0-20201221093633-bc327ba9c2f0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -564,17 +525,17 @@ golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211209171907-798191bca915 h1:P+8mCzuEpyszAT6T42q0sxU+eveBAF/cJ2Kp0x6/8+0= golang.org/x/sys v0.0.0-20211209171907-798191bca915/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -606,7 +567,6 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -674,8 +634,8 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= From 117019cec19d1e42db754432affbe9e55dba8f62 Mon Sep 17 00:00:00 2001 From: bianning Date: Thu, 21 Jul 2022 20:18:00 +0800 Subject: [PATCH 17/20] feat: encode account --- dataStructure/state/state_object.go | 6 +++--- dataStructure/state/statedb.go | 5 ++--- dataStructure/state/types.go | 2 ++ .../smartAssets/smartAssetsLedger/account.go | 20 +++++++++++++------ .../smartAssetsLedger/account_tool.go | 4 ++-- 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/dataStructure/state/state_object.go b/dataStructure/state/state_object.go index 1a742f3..9635512 100644 --- a/dataStructure/state/state_object.go +++ b/dataStructure/state/state_object.go @@ -9,7 +9,6 @@ import ( //"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/rlp" - "io" "math/big" ) @@ -82,8 +81,8 @@ func newObject(db *StateDB, cryptoTools crypto.Tools, address common.Address, da } } -func (s *stateObject) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, s.data) +func (s *stateObject) EncodeData() ([]byte, error) { + return s.data.Encode() } func (s *stateObject) empty() bool { @@ -211,6 +210,7 @@ func (s *stateObject) updateTrie(db Database) Trie { continue } v, _ := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00")) + //v, _ := structSerializer.ToMFBytes(bytes.TrimLeft(value[:], "\x00")) s.setError(tr.TryUpdate(key[:], v)) } return tr diff --git a/dataStructure/state/statedb.go b/dataStructure/state/statedb.go index 68e3418..6b25141 100644 --- a/dataStructure/state/statedb.go +++ b/dataStructure/state/statedb.go @@ -6,8 +6,6 @@ import ( "github.com/SealSC/SealABC/crypto" "github.com/SealSC/SealABC/dataStructure/trie" "github.com/SealSC/SealABC/log" - "github.com/ethereum/go-ethereum/rlp" - "math/big" "sync" ) @@ -209,7 +207,8 @@ func (s *StateDB) Suicide(addr common.Address) bool { func (s *StateDB) updateStateObject(stateObject *stateObject) { addr := stateObject.Address() - data, err := rlp.EncodeToBytes(stateObject) + data, err := stateObject.EncodeData() + if err != nil { panic(fmt.Errorf("can't encode object at %x: %v", addr[:], err)) } diff --git a/dataStructure/state/types.go b/dataStructure/state/types.go index 19ff6a3..088e6b6 100644 --- a/dataStructure/state/types.go +++ b/dataStructure/state/types.go @@ -19,6 +19,8 @@ type Account interface { Root() common.Hash SetRoot(common.Hash) + + Encode() ([]byte, error) } type AccountTool interface { diff --git a/service/application/smartAssets/smartAssetsLedger/account.go b/service/application/smartAssets/smartAssetsLedger/account.go index b804e3c..83ef8dd 100644 --- a/service/application/smartAssets/smartAssetsLedger/account.go +++ b/service/application/smartAssets/smartAssetsLedger/account.go @@ -2,22 +2,25 @@ package smartAssetsLedger import ( "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" "math/big" ) type Account struct { AccountNonce uint64 - AccountBalance *big.Int - AccountRoot common.Hash + AccountBalance string + AccountRoot []byte AccountCodeHash []byte } func (a *Account) Balance() *big.Int { - return a.AccountBalance + b := new(big.Int) + b.SetString(a.AccountBalance, 10) + return b } func (a *Account) SetBalance(b *big.Int) { - a.AccountBalance = b + a.AccountBalance = b.String() } func (a *Account) CodeHash() []byte { @@ -37,9 +40,14 @@ func (a *Account) SetNonce(nonce uint64) { } func (a *Account) Root() common.Hash { - return a.AccountRoot + return common.BytesToHash(a.AccountRoot) } func (a *Account) SetRoot(hash common.Hash) { - a.AccountRoot = hash + a.AccountRoot = hash.Bytes() +} + +func (a *Account) Encode() (data []byte, err error) { + data, err = structSerializer.ToMFBytes(*a) + return } diff --git a/service/application/smartAssets/smartAssetsLedger/account_tool.go b/service/application/smartAssets/smartAssetsLedger/account_tool.go index 81cd4db..2e79e5a 100644 --- a/service/application/smartAssets/smartAssetsLedger/account_tool.go +++ b/service/application/smartAssets/smartAssetsLedger/account_tool.go @@ -1,9 +1,9 @@ package smartAssetsLedger import ( + "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" "github.com/SealSC/SealABC/dataStructure/state" "github.com/SealSC/SealABC/log" - "github.com/ethereum/go-ethereum/rlp" ) type AccountTool struct { @@ -15,7 +15,7 @@ func (a AccountTool) NewAccount() state.Account { func (a AccountTool) DecodeAccount(enc []byte) (state.Account, error) { var account Account - if err := rlp.DecodeBytes(enc, &account); err != nil { + if err := structSerializer.FromMFBytes(enc, &account); err != nil { log.Log.Error("Failed to decode state object", "err", err) return nil, err } From e50b3ba8c470c50483ecd1ab13d7480c80d5bef1 Mon Sep 17 00:00:00 2001 From: bianning Date: Tue, 26 Jul 2022 14:46:31 +0800 Subject: [PATCH 18/20] feat: encode node with structSerializer --- dataStructure/state/state_object.go | 13 +-- dataStructure/trie/hasher.go | 21 ++-- dataStructure/trie/node.go | 170 +++++++++++----------------- dataStructure/trie/node_string.go | 29 +++++ dataStructure/trie/trie.go | 6 +- dataStructure/trie/types.go | 7 ++ 6 files changed, 119 insertions(+), 127 deletions(-) create mode 100644 dataStructure/trie/node_string.go diff --git a/dataStructure/state/state_object.go b/dataStructure/state/state_object.go index 9635512..8cce2e6 100644 --- a/dataStructure/state/state_object.go +++ b/dataStructure/state/state_object.go @@ -8,7 +8,6 @@ import ( "github.com/SealSC/SealABC/dataStructure/trie" //"github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" "math/big" ) @@ -174,12 +173,9 @@ func (s *stateObject) GetState(db Database, key common.Hash) common.Hash { s.setError(err) return common.Hash{} } + if len(enc) > 0 { - _, content, _, err := rlp.Split(enc) - if err != nil { - s.setError(err) - } - value.SetBytes(content) + value.SetBytes(enc) } if (value != common.Hash{}) { s.cachedStorage[key] = value @@ -209,9 +205,8 @@ func (s *stateObject) updateTrie(db Database) Trie { s.setError(tr.TryDelete(key[:])) continue } - v, _ := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00")) - //v, _ := structSerializer.ToMFBytes(bytes.TrimLeft(value[:], "\x00")) - s.setError(tr.TryUpdate(key[:], v)) + + s.setError(tr.TryUpdate(key[:], value.Bytes())) } return tr } diff --git a/dataStructure/trie/hasher.go b/dataStructure/trie/hasher.go index fc4a569..ca37f39 100644 --- a/dataStructure/trie/hasher.go +++ b/dataStructure/trie/hasher.go @@ -1,17 +1,13 @@ package trie import ( - "bytes" "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/crypto" - "github.com/ethereum/go-ethereum/rlp" "hash" - "sync" ) type hasher struct { - tmp *bytes.Buffer sha hash.Hash cacheGen, cacheLimit uint16 } @@ -21,7 +17,7 @@ var hasherPool sync.Pool func Load(cryptoTools crypto.Tools) { hasherPool = sync.Pool{ New: func() interface{} { - return &hasher{tmp: new(bytes.Buffer), sha: cryptoTools.HashCalculator.OriginalHash()()} + return &hasher{sha: cryptoTools.HashCalculator.OriginalHash()()} }, } } @@ -137,26 +133,23 @@ func (h *hasher) store(n node, bw BatchWriter, force bool) (node, error) { if _, isHash := n.(hashNode); n == nil || isHash { return n, nil } - // Generate the RLP encoding of the node - h.tmp.Reset() - if err := rlp.Encode(h.tmp, n); err != nil { + + data, err := encodeNode(n) + if err != nil { panic("encode error: " + err.Error()) } - if h.tmp.Len() < 32 && !force { - return n, nil // Nodes smaller than 32 bytes are stored inside their parent - } - // Larger nodes are replaced by their hash and stored in the database. hash, _ := n.cache() if hash == nil { h.sha.Reset() - h.sha.Write(h.tmp.Bytes()) + h.sha.Write(data) hash = hashNode(h.sha.Sum(nil)) } + if bw != nil { bw.Put( hash, - h.tmp.Bytes(), + data, ) return hash, nil } diff --git a/dataStructure/trie/node.go b/dataStructure/trie/node.go index 439ef4a..0278bfd 100644 --- a/dataStructure/trie/node.go +++ b/dataStructure/trie/node.go @@ -2,9 +2,7 @@ package trie import ( "fmt" - "github.com/SealSC/SealABC/common" - "github.com/ethereum/go-ethereum/rlp" - "io" + "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" "strings" ) @@ -14,6 +12,7 @@ type node interface { fString(string) string cache() (hashNode, bool) canUnload(cacheGen, cacheLimit uint16) bool + encodeToPN() persistenceNode } type ( @@ -40,38 +39,38 @@ func (n *shortNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirt func (n hashNode) cache() (hashNode, bool) { return nil, true } func (n valueNode) cache() (hashNode, bool) { return nil, true } -// Pretty printing. -func (n *fullNode) String() string { return n.fString("") } -func (n *shortNode) String() string { return n.fString("") } -func (n hashNode) String() string { return n.fString("") } -func (n valueNode) String() string { return n.fString("") } +func (n *fullNode) copy() *fullNode { cn := *n; return &cn } +func (n *shortNode) copy() *shortNode { cn := *n; return &cn } -func (n *fullNode) fString(ind string) string { - resp := fmt.Sprintf("[\n%s ", ind) +func (n *fullNode) encodeToPN() (pn persistenceNode) { + pn.NodeType = NodeTypeFull + nodes := make([]persistenceNode, len(n.Children)) for i, node := range n.Children { if node == nil { - resp += fmt.Sprintf("%s: ", indices[i]) - } else { - resp += fmt.Sprintf("%s: %v", indices[i], node.fString(ind+" ")) + continue } + nodes[i] = node.encodeToPN() } - return resp + fmt.Sprintf("\n%s] ", ind) + + pn.Nodes = nodes + return } -func (n *shortNode) fString(ind string) string { - return fmt.Sprintf("{%x: %v} ", n.Key, n.Val.fString(ind+" ")) +func (n *shortNode) encodeToPN() (pn persistenceNode) { + pn.NodeType = NodeTypeShort + node := n.Val.encodeToPN() + pn.Key = compactToHex(n.Key) + pn.Nodes = []persistenceNode{node} + return } -func (n hashNode) fString(ind string) string { - return fmt.Sprintf("<%x> ", []byte(n)) +func (n hashNode) encodeToPN() (pn persistenceNode) { + pn.NodeType = NodeTypeHash + pn.Data = n + return } -func (n valueNode) fString(ind string) string { - return fmt.Sprintf("%x ", []byte(n)) -} - -func (n *fullNode) copy() *fullNode { cn := *n; return &cn } -func (n *shortNode) copy() *shortNode { cn := *n; return &cn } - -func (n *fullNode) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, n.Children) +func (n valueNode) encodeToPN() (pn persistenceNode) { + pn.NodeType = NodeTypeValue + pn.Data = n + return } type nodeFlag struct { @@ -84,90 +83,55 @@ func (n *nodeFlag) canUnload(cacheGen, cacheLimit uint16) bool { return !n.dirty && cacheGen-n.gen >= cacheLimit } -func decodeNode(hash, buf []byte, cacheGen uint16) (node, error) { - if len(buf) == 0 { - return nil, io.ErrUnexpectedEOF - } - elems, _, err := rlp.SplitList(buf) - if err != nil { - return nil, fmt.Errorf("decode error: %v", err) - } - switch c, _ := rlp.CountValues(elems); c { - case 2: - n, err := decodeShort(hash, buf, elems, cacheGen) - return n, wrapError(err, "short") - case 17: - n, err := decodeFull(hash, buf, elems, cacheGen) - return n, wrapError(err, "full") - default: - return nil, fmt.Errorf("invalid number of list elements: %v", c) - } +type persistenceNode struct { + NodeType string + Nodes []persistenceNode + Key []byte + Data []byte } -func decodeShort(hash, buf, elems []byte, cachegen uint16) (node, error) { - kBuf, rest, err := rlp.SplitString(elems) - if err != nil { - return nil, err - } - flag := nodeFlag{hash: hash, gen: cachegen} - key := compactToHex(kBuf) - if hasTerm(key) { - // value node - val, _, err := rlp.SplitString(rest) - if err != nil { - return nil, fmt.Errorf("invalid value node: %v", err) +func pnToNode(hash []byte, pn persistenceNode, cacheGen uint16) (n node) { + switch pn.NodeType { + case NodeTypeFull: + child := &fullNode{flags: nodeFlag{hash: hash, gen: cacheGen}} + nodes := [17]node{} + for i, node := range pn.Nodes { + nodes[i] = pnToNode(hash, node, cacheGen) } - return &shortNode{key, append(valueNode{}, val...), flag}, nil - } - r, _, err := decodeRef(rest, cachegen) - if err != nil { - return nil, wrapError(err, "val") + child.Children = nodes + n = child + case NodeTypeShort: + node := &shortNode{} + node.flags = nodeFlag{hash: hash, gen: cacheGen} + node.Key = pn.Key + child := pn.Nodes[0] + node.Val = pnToNode(hash, child, cacheGen) + n = node + case NodeTypeHash: + if len(pn.Data) == 0 { + return nil + } + return hashNode(pn.Data) + case NodeTypeValue: + if len(pn.Data) == 0 { + return nil + } + return valueNode(pn.Data) } - return &shortNode{key, r, flag}, nil + return } -func decodeFull(hash, buf, elems []byte, cachegen uint16) (*fullNode, error) { - n := &fullNode{flags: nodeFlag{hash: hash, gen: cachegen}} - for i := 0; i < 16; i++ { - cld, rest, err := decodeRef(elems, cachegen) - if err != nil { - return n, wrapError(err, fmt.Sprintf("[%d]", i)) - } - n.Children[i], elems = cld, rest - } - val, _, err := rlp.SplitString(elems) - if err != nil { - return n, err - } - if len(val) > 0 { - n.Children[16] = append(valueNode{}, val...) - } - return n, nil +func encodeNode(n node) ([]byte, error) { + pn := n.encodeToPN() + return structSerializer.ToMFBytes(pn) } -func decodeRef(buf []byte, cachegen uint16) (node, []byte, error) { - kind, val, rest, err := rlp.Split(buf) - if err != nil { - return nil, buf, err - } - switch { - case kind == rlp.List: - // 'embedded' node reference. The encoding must be smaller - // than a hash in order to be valid. - if size := len(buf) - len(rest); size > common.HashLength { - err := fmt.Errorf("oversized embedded node (size is %d bytes, want size < %d)", size, common.HashLength) - return nil, buf, err - } - n, err := decodeNode(nil, buf, cachegen) - return n, rest, err - case kind == rlp.String && len(val) == 0: - // empty node - return nil, rest, nil - case kind == rlp.String && len(val) == 32: - return append(hashNode{}, val...), rest, nil - default: - return nil, nil, fmt.Errorf("invalid RLP string size %d (want 0 or 32)", len(val)) - } +func decodeNode(hash, buf []byte, cacheGen uint16) (node, error) { + pn := persistenceNode{} + err := structSerializer.FromMFBytes(buf, &pn) + n := pnToNode(hash, pn, cacheGen) + + return n, err } type decodeError struct { diff --git a/dataStructure/trie/node_string.go b/dataStructure/trie/node_string.go new file mode 100644 index 0000000..7cb4636 --- /dev/null +++ b/dataStructure/trie/node_string.go @@ -0,0 +1,29 @@ +package trie + +import "fmt" + +func (n *fullNode) String() string { return n.fString("") } +func (n *shortNode) String() string { return n.fString("") } +func (n hashNode) String() string { return n.fString("") } +func (n valueNode) String() string { return n.fString("") } + +func (n *fullNode) fString(ind string) string { + resp := fmt.Sprintf("[\n%s ", ind) + for i, node := range n.Children { + if node == nil { + resp += fmt.Sprintf("%s: ", indices[i]) + } else { + resp += fmt.Sprintf("%s: %v", indices[i], node.fString(ind+" ")) + } + } + return resp + fmt.Sprintf("\n%s] ", ind) +} +func (n *shortNode) fString(ind string) string { + return fmt.Sprintf("{%x: %v} ", n.Key, n.Val.fString(ind+" ")) +} +func (n hashNode) fString(ind string) string { + return fmt.Sprintf("<%x> ", []byte(n)) +} +func (n valueNode) fString(ind string) string { + return fmt.Sprintf("%x ", []byte(n)) +} diff --git a/dataStructure/trie/trie.go b/dataStructure/trie/trie.go index d1be3c6..75f7081 100644 --- a/dataStructure/trie/trie.go +++ b/dataStructure/trie/trie.go @@ -76,12 +76,15 @@ func (t *Trie) tryGet(origNode node, key []byte, pos int) (value []byte, newnode // key not found in trie return nil, n, false, nil } + value, newnode, didResolve, err = t.tryGet(n.Val, key, pos+len(n.Key)) + if err == nil && didResolve { n = n.copy() n.Val = newnode n.flags.gen = t.cacheGen } + return value, n, didResolve, err case *fullNode: value, newnode, didResolve, err = t.tryGet(n.Children[key[pos]], key, pos+1) @@ -184,7 +187,8 @@ func (t *Trie) insert(n node, prefix, key []byte, value node) (bool, node, error return true, nn, nil default: - panic(fmt.Sprintf("%T: invalid node: %v", n, n)) + log.Log.Errorf("%T: invalid node: %v", n, n) + return false, nil, nil } } diff --git a/dataStructure/trie/types.go b/dataStructure/trie/types.go index f43cedf..8df933b 100644 --- a/dataStructure/trie/types.go +++ b/dataStructure/trie/types.go @@ -1,5 +1,12 @@ package trie +const ( + NodeTypeFull = "Full" + NodeTypeShort = "Short" + NodeTypeHash = "Hash" + NodeTypeValue = "Value" +) + type BatchWriter interface { Put(key, value []byte) } From 86f3024bc66db09fcd11ddb7257eadcd5db5e429 Mon Sep 17 00:00:00 2001 From: bianning Date: Tue, 26 Jul 2022 18:08:23 +0800 Subject: [PATCH 19/20] feat: add StateType --- .../smartAssets/smartAssetsLedger/ledger.go | 5 +++-- .../smartAssetsLedger/operationForTransfer.go | 13 ++----------- .../smartAssets/smartAssetsLedger/transaction.go | 8 ++++++++ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/service/application/smartAssets/smartAssetsLedger/ledger.go b/service/application/smartAssets/smartAssetsLedger/ledger.go index 8fedf68..cea8e65 100644 --- a/service/application/smartAssets/smartAssetsLedger/ledger.go +++ b/service/application/smartAssets/smartAssetsLedger/ledger.go @@ -65,6 +65,7 @@ type Ledger struct { func Load() { enum.SimpleBuild(&StoragePrefixes) + enum.SimpleBuild(&StateType) enum.SimpleBuild(&TxType) enum.SimpleBuild(&QueryTypes) enum.SimpleBuild(&QueryParameterFields) @@ -361,14 +362,14 @@ func (l *Ledger) Execute(txList TransactionList, blk block.Entity) (result []byt } func (l *Ledger) setTransferState(s []StateData, state *state.StateDB) { - for i, s := range s { + for _, s := range s { balance := big.NewInt(0) balance.SetBytes(s.NewVal) address := common.BytesToAddress(s.Key) state.SetBalance(address, balance) - if i == 0 { //From + if s.Type == StateType.TransferFrom.String() { state.SetNonce(address, state.GetNonce(address)+1) } } diff --git a/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go b/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go index 7ac6aeb..fd80b30 100644 --- a/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go +++ b/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go @@ -90,27 +90,18 @@ func (l *Ledger) preTransfer(tx Transaction, cache txResultCache, _ block.Entity statusToChange := []StateData{ { + Type: StateType.TransferFrom.String(), Key: tx.From, NewVal: fromBalance.Bytes(), OrgVal: orgFromBalance, }, { + Type: StateType.TransferTo.String(), Key: tx.To, NewVal: toBalance.Bytes(), OrgVal: orgToBalance, }, - //{ - // Key: BuildKey(StoragePrefixes.Balance, tx.From), - // NewVal: fromBalance.Bytes(), - // OrgVal: orgFromBalance, - //}, - // - //{ - // Key: BuildKey(StoragePrefixes.Balance, tx.To), - // NewVal: toBalance.Bytes(), - // OrgVal: orgToBalance, - //}, } return statusToChange, cache, Errors.Success diff --git a/service/application/smartAssets/smartAssetsLedger/transaction.go b/service/application/smartAssets/smartAssetsLedger/transaction.go index 5a5fb8a..1a8279f 100644 --- a/service/application/smartAssets/smartAssetsLedger/transaction.go +++ b/service/application/smartAssets/smartAssetsLedger/transaction.go @@ -40,6 +40,13 @@ var TxType struct { ContractCall enum.Element } +var StateType struct { + TransferFrom enum.Element + TransferTo enum.Element + ContractCode enum.Element + ContractHash enum.Element +} + func GetTxTypeCodeForName(name string) int { switch name { case TxType.Transfer.String(): @@ -67,6 +74,7 @@ type TransactionData struct { } type StateData struct { + Type string Key []byte NewVal []byte OrgVal []byte From b2543ab160aeb8f0da5e8a4e7b7c951c2ea2fe35 Mon Sep 17 00:00:00 2001 From: bianning Date: Tue, 2 Aug 2022 18:45:01 +0800 Subject: [PATCH 20/20] feat: change contractStorage to state --- dataStructure/state/state_object.go | 7 +- dataStructure/state/state_test.go | 2 +- dataStructure/state/statedb.go | 8 +- .../smartAssets/smartAssetsLedger/assets.go | 12 -- .../smartAssetsLedger/evmAdapter.go | 24 ++- .../smartAssets/smartAssetsLedger/ledger.go | 174 +++++++++++++----- .../smartAssetsLedger/ledger_for_state.go | 49 +++++ .../operationForContractCreation.go | 20 +- .../smartAssetsLedger/operationForTransfer.go | 4 +- .../smartAssets/smartAssetsLedger/storage.go | 54 +----- .../smartAssetsLedger/transaction.go | 7 +- .../smartAssets/smartAssetsLedger/txpool.go | 28 ++- .../blockchain/chainStructure/operator.go | 2 +- 13 files changed, 235 insertions(+), 156 deletions(-) create mode 100644 service/application/smartAssets/smartAssetsLedger/ledger_for_state.go diff --git a/dataStructure/state/state_object.go b/dataStructure/state/state_object.go index 8cce2e6..dfa4fca 100644 --- a/dataStructure/state/state_object.go +++ b/dataStructure/state/state_object.go @@ -123,7 +123,6 @@ func (s *stateObject) setCode(codeHash common.Hash, code []byte) { s.dirtyCode = true if s.onDirty != nil { s.onDirty(s.Address()) - s.onDirty = nil } } @@ -135,7 +134,6 @@ func (s *stateObject) setNonce(nonce uint64) { s.data.SetNonce(nonce) if s.onDirty != nil { s.onDirty(s.Address()) - s.onDirty = nil } } @@ -193,7 +191,6 @@ func (s *stateObject) setState(key, value common.Hash) { if s.onDirty != nil { s.onDirty(s.Address()) - s.onDirty = nil } } @@ -232,14 +229,13 @@ func (s *stateObject) markSuicided() { s.suicided = true if s.onDirty != nil { s.onDirty(s.Address()) - s.onDirty = nil + } } func (s *stateObject) touch() { if s.onDirty != nil { s.onDirty(s.Address()) - s.onDirty = nil } s.touched = true } @@ -270,7 +266,6 @@ func (s *stateObject) setBalance(amount *big.Int) { s.data.SetBalance(amount) if s.onDirty != nil { s.onDirty(s.Address()) - s.onDirty = nil } } diff --git a/dataStructure/state/state_test.go b/dataStructure/state/state_test.go index 51e92e5..a40e613 100644 --- a/dataStructure/state/state_test.go +++ b/dataStructure/state/state_test.go @@ -46,7 +46,7 @@ func Test(t *testing.T) { so0.deleted = false state.setStateObject(so0) - root, _ := state.CommitTo(driver.NewBatch(), false) + root, _ := state.Commit(driver.NewBatch(), false) t.Log(root) diff --git a/dataStructure/state/statedb.go b/dataStructure/state/statedb.go index 6b25141..bba6a3c 100644 --- a/dataStructure/state/statedb.go +++ b/dataStructure/state/statedb.go @@ -127,10 +127,10 @@ func (s *StateDB) GetCodeHash(addr common.Address) common.Hash { return common.BytesToHash(stateObject.CodeHash()) } -func (s *StateDB) GetState(a common.Address, b common.Hash) common.Hash { - stateObject := s.getStateObject(a) +func (s *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash { + stateObject := s.getStateObject(addr) if stateObject != nil { - return stateObject.GetState(s.db, b) + return stateObject.GetState(s.db, hash) } return common.Hash{} } @@ -344,7 +344,7 @@ func (s *StateDB) DeleteSuicides() { } } -func (s *StateDB) CommitTo(bw trie.BatchWriter, deleteEmptyObjects bool) (root common.Hash, err error) { +func (s *StateDB) Commit(bw trie.BatchWriter, deleteEmptyObjects bool) (root common.Hash, err error) { for addr, stateObject := range s.stateObjects { _, isDirty := s.stateObjectsDirty[addr] switch { diff --git a/service/application/smartAssets/smartAssetsLedger/assets.go b/service/application/smartAssets/smartAssetsLedger/assets.go index d6e6aea..3f647d8 100644 --- a/service/application/smartAssets/smartAssetsLedger/assets.go +++ b/service/application/smartAssets/smartAssetsLedger/assets.go @@ -19,10 +19,8 @@ package smartAssetsLedger import ( "encoding/json" - "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/metadata/seal" "github.com/SealSC/SealABC/storage/db/dbInterface/kvDatabase" - "math/big" ) type BaseAssetsData struct { @@ -45,16 +43,6 @@ func (b *BaseAssets) getHash() []byte { return b.MetaSeal.Hash } -func (l *Ledger) BalanceOf(address []byte) (balance *big.Int, err error) { - balance = l.StateDB.GetBalance(common.BytesToAddress(address)) - return -} - -func (l *Ledger) NonceOf(address []byte) (nonce uint64) { - nonce = l.StateDB.GetNonce(common.BytesToAddress(address)) - return -} - func (l *Ledger) getSystemAssets() (assets *BaseAssets, exits bool, err error) { key := BuildKey(StoragePrefixes.SystemAssets, nil) diff --git a/service/application/smartAssets/smartAssetsLedger/evmAdapter.go b/service/application/smartAssets/smartAssetsLedger/evmAdapter.go index 7eb930c..a28846f 100644 --- a/service/application/smartAssets/smartAssetsLedger/evmAdapter.go +++ b/service/application/smartAssets/smartAssetsLedger/evmAdapter.go @@ -39,7 +39,7 @@ func constTransactionGasLimit() *evmInt256.Int { return evmInt256.New(100000000) } -func (l Ledger) newEVM(tx Transaction, callback SealEVM.EVMResultCallback, +func (l *Ledger) newEVM(tx Transaction, callback SealEVM.EVMResultCallback, blk block.Entity, blockGasLimit *evmInt256.Int) (*SealEVM.EVM, *environment.Contract, error) { evmTransaction := environment.Transaction{ @@ -54,6 +54,7 @@ func (l Ledger) newEVM(tx Transaction, callback SealEVM.EVMResultCallback, caller := common.BytesDataToEVMIntHash(tx.DataSeal.SignerPublicKey) var contractAddress *evmInt256.Int var contractCode []byte + if len(tx.To) == 0 { contractAddress = l.storageForEVM.CreateAddress(caller, evmTransaction) contractCode = tx.Data @@ -98,7 +99,7 @@ func (l Ledger) newEVM(tx Transaction, callback SealEVM.EVMResultCallback, }), &contract, nil } -func (l Ledger) processEVMBalanceCache(cache storage.BalanceCache, resultCache txResultCache, newState *[]StateData) { +func (l *Ledger) processEVMBalanceCache(cache storage.BalanceCache, resultCache txResultCache, newState *[]StateData) { keys := make([]string, 0, len(cache)) for k := range cache { keys = append(keys, k) @@ -130,7 +131,8 @@ func (l Ledger) processEVMBalanceCache(cache storage.BalanceCache, resultCache t localBalance.Add(localBalance, val) balanceToChange = append(balanceToChange, StateData{ - Key: BuildKey(StoragePrefixes.Balance, addr), + Type: StateType.Balance.String(), + Key: addr, NewVal: localBalance.Bytes(), OrgVal: orgBalance, }) @@ -139,7 +141,7 @@ func (l Ledger) processEVMBalanceCache(cache storage.BalanceCache, resultCache t *newState = balanceToChange } -func (l Ledger) processEVMNamedStateCache(ns string, cache storage.Cache, org storage.Cache, newState *[]StateData) { +func (l *Ledger) processEVMNamedStateCache(ns string, cache storage.Cache, org storage.Cache, newState *[]StateData) { keys := make([]string, 0, len(cache)) for k := range cache { keys = append(keys, k) @@ -157,7 +159,9 @@ func (l Ledger) processEVMNamedStateCache(ns string, cache storage.Cache, org st } state = append(state, StateData{ - Key: BuildKey(StoragePrefixes.ContractData, []byte(ns), []byte(k)), + Type: StateType.ContractData.String(), + Key: []byte(ns), + SubKey: []byte(k), NewVal: cacheData.Bytes(), OrgVal: orgVal, }) @@ -166,7 +170,7 @@ func (l Ledger) processEVMNamedStateCache(ns string, cache storage.Cache, org st *newState = state } -func (l Ledger) processEVMStateCache(cache storage.CacheUnderNamespace, org storage.CacheUnderNamespace, newState *[]StateData) { +func (l *Ledger) processEVMStateCache(cache storage.CacheUnderNamespace, org storage.CacheUnderNamespace, newState *[]StateData) { keys := make([]string, 0, len(cache)) for k := range cache { keys = append(keys, k) @@ -178,7 +182,7 @@ func (l Ledger) processEVMStateCache(cache storage.CacheUnderNamespace, org stor } } -func (l Ledger) processEVMLogData(ns string, logList []storage.Log, newState *[]StateData) { +func (l *Ledger) processEVMLogData(ns string, logList []storage.Log, newState *[]StateData) { state := *newState for _, contractLog := range logList { @@ -200,7 +204,7 @@ func (l Ledger) processEVMLogData(ns string, logList []storage.Log, newState *[] *newState = state } -func (l Ledger) processEVMLogCache(cache storage.LogCache, newState *[]StateData) { +func (l *Ledger) processEVMLogCache(cache storage.LogCache, newState *[]StateData) { keys := make([]string, 0, len(cache)) for k := range cache { keys = append(keys, k) @@ -212,7 +216,7 @@ func (l Ledger) processEVMLogCache(cache storage.LogCache, newState *[]StateData } } -func (l Ledger) processEVMDestructs(cache storage.Cache, newState *[]StateData) { +func (l *Ledger) processEVMDestructs(cache storage.Cache, newState *[]StateData) { keys := make([]string, 0, len(cache)) for k := range cache { keys = append(keys, k) @@ -231,7 +235,7 @@ func (l Ledger) processEVMDestructs(cache storage.Cache, newState *[]StateData) *newState = state } -func (l Ledger) newStateFromEVMResult(evmRet SealEVM.ExecuteResult, cache txResultCache) []StateData { +func (l *Ledger) newStateFromEVMResult(evmRet SealEVM.ExecuteResult, cache txResultCache) []StateData { evmCache := evmRet.StorageCache var newState []StateData diff --git a/service/application/smartAssets/smartAssetsLedger/ledger.go b/service/application/smartAssets/smartAssetsLedger/ledger.go index cea8e65..bc26c1f 100644 --- a/service/application/smartAssets/smartAssetsLedger/ledger.go +++ b/service/application/smartAssets/smartAssetsLedger/ledger.go @@ -58,9 +58,11 @@ type Ledger struct { storageForEVM contractStorage - StateDB *state.StateDB + stateDB *state.StateDB applicationName string + + genesisRoot []byte } func Load() { @@ -75,22 +77,45 @@ func Load() { func (l *Ledger) SetChain(chain chainStructure.IChainInterface) { l.chain = chain - if chain.GetLastBlock() != nil { - root, exist := chain.GetLastBlock().Header.StateRoot[l.applicationName] - if !exist { - log.Log.Error("Failed to reset txpool state") - return - } - stateRoot := common.BytesToHash(root) - stateDB, err := state.New(stateRoot, state.NewDatabase(l.Storage), l.CryptoTools, &AccountTool{}) - if err != nil { - log.Log.Error("Failed to reset txpool state", "err", err) - } + parentRoot, _ := l.getParentRoot() + stateDB, err := l.NewState(parentRoot) + if err != nil { + panic(err) + return + } + + l.stateDB = stateDB + + l.txPool.setChain(chain, l.stateDB) +} + +func (l *Ledger) genesisState() { + batch := l.Storage.NewBatch() + + r, _ := l.stateDB.Commit(batch, true) + + l.genesisRoot = r.Bytes() + err := l.Storage.BatchWrite(batch) + if err != nil { + log.Log.Error("genesis root error") + return + } + + return +} - l.StateDB = stateDB +func (l *Ledger) getParentRoot() (root []byte, err error) { + blockEntity := l.chain.GetLastBlock() + if blockEntity == nil { + root = l.genesisRoot + return + } + root, _ = blockEntity.Header.StateRoot[l.applicationName] + if len(root) == 0 { + root = l.genesisRoot } - l.txPool.setChain(chain, l.StateDB) + return } func (l *Ledger) NewStateAndLoadGenesisAssets(owner []byte, assets BaseAssetsData) (err error) { @@ -107,11 +132,11 @@ func (l *Ledger) NewStateAndLoadGenesisAssets(owner []byte, assets BaseAssetsDat return errors.New("no owner for system assets") } - stateDB, err := state.New(common.Hash{}, state.NewDatabase(l.Storage), l.CryptoTools, &AccountTool{}) + stateDB, err := l.NewState(common.Hash{}.Bytes()) if err != nil { return err } - l.StateDB = stateDB + l.stateDB = stateDB addr := common.BytesToAddress(owner) exist := stateDB.Exist(addr) @@ -170,6 +195,7 @@ func (l *Ledger) NewStateAndLoadGenesisAssets(owner []byte, assets BaseAssetsDat stateDB.AddBalance(addr, balance) stateDB.SetNonce(addr, 0) + l.genesisState() return } @@ -271,7 +297,14 @@ func (l Ledger) PreExecute(txList TransactionList, blk block.Entity) (root []byt }, } - stateDB := l.StateDB.Copy() + parentRoot, err := l.getParentRoot() + if err != nil { + return + } + stateDB, err := l.NewState(parentRoot) + if err != nil { + return + } for _, tx := range txList.Transactions { hash := string(tx.DataSeal.Hash) @@ -299,24 +332,29 @@ func (l Ledger) PreExecute(txList TransactionList, blk block.Entity) (root []byt break } - switch tx.Type { - case TxType.Transfer.String(): - l.setTransferState(tx.TransactionResult.NewState, stateDB) - } + l.setTransactionState(tx, stateDB, nil) } } root = stateDB.IntermediateRoot().Bytes() stateRoot := blk.Header.StateRoot[l.applicationName] + + l.removeTransactionsFromPool(txList.Transactions) + if !bytes.Equal(root, stateRoot) { err = fmt.Errorf("invalid merkle root (remote: %x local: %x)", stateRoot, root) } + return } func (l *Ledger) removeTransactionsFromPool(txList []Transaction) { l.txPool.removeUnenforceable() + for _, tx := range txList { + l.txPool.removeTx(tx.getCommonHash()) + } + for _, tx := range txList { client := string(tx.DataSeal.SignerPublicKey) if l.clientTxCount[client] > 0 { @@ -335,44 +373,74 @@ func (l *Ledger) Execute(txList TransactionList, blk block.Entity) (result []byt txData, _ := structSerializer.ToMFBytes(tx) batch.Put(BuildKey(StoragePrefixes.Transaction, tx.DataSeal.Hash), txData) - switch tx.Type { - case TxType.Transfer.String(): - l.setTransferState(tx.TransactionResult.NewState, l.StateDB) - default: - for _, s := range tx.TransactionResult.NewState { - batch.Put(s.Key, s.NewVal) - } - } - + l.setTransactionState(tx, l.stateDB, batch) } - root, err = l.StateDB.CommitTo(batch, true) + root, err = l.stateDB.Commit(batch, true) + err = l.Storage.BatchWrite(batch) if err != nil { return } - err = l.Storage.BatchWrite(batch) - if err != nil { - return + return +} + +func (l *Ledger) setTransactionState(tx Transaction, state *state.StateDB, batch kvDatabase.Batch) { + from := common.BytesToAddress(tx.From) + + switch tx.Type { + case TxType.Transfer.String(): + l.setTransferState(tx.TransactionResult.NewState, state) + case TxType.CreateContract.String(): + fallthrough + case TxType.ContractCall.String(): + l.setContractState(tx.TransactionResult.NewState, state, batch) } - l.removeTransactionsFromPool(txList.Transactions) + state.SetNonce(from, state.GetNonce(from)+1) +} - return +func (l *Ledger) setContractState(states []StateData, state *state.StateDB, batch kvDatabase.Batch) { + for _, s := range states { + switch s.Type { + case StateType.Balance.String(): + l.setBalance(s.Key, s.NewVal, state) + + case StateType.ContractData.String(): + + addr := common.BytesToAddress(s.Key) + key := common.BytesToHash(s.SubKey) + value := common.BytesToHash(s.NewVal) + + state.SetState(addr, key, value) + case StateType.ContractCode.String(): + + addr := common.BytesToAddress(s.Key) + + state.SetCode(addr, s.NewVal) + case StateType.ContractHash.String(): + continue + default: + if batch == nil { + continue + } + batch.Put(s.Key, s.NewVal) + } + } } func (l *Ledger) setTransferState(s []StateData, state *state.StateDB) { for _, s := range s { - balance := big.NewInt(0) - balance.SetBytes(s.NewVal) + l.setBalance(s.Key, s.NewVal, state) + } +} - address := common.BytesToAddress(s.Key) +func (l *Ledger) setBalance(addr, value []byte, state *state.StateDB) { + balance := big.NewInt(0) + balance.SetBytes(value) + address := common.BytesToAddress(addr) - state.SetBalance(address, balance) - if s.Type == StateType.TransferFrom.String() { - state.SetNonce(address, state.GetNonce(address)+1) - } - } + state.SetBalance(address, balance) } func (l *Ledger) setTxNewState(err error, newState []StateData, tx *Transaction) { @@ -393,6 +461,7 @@ func (l *Ledger) GetTransactionsFromPool(blk block.Entity) (txList TransactionLi txs := l.txPool.Pending() count = uint32(len(txs)) + if count == 0 { return } @@ -411,7 +480,15 @@ func (l *Ledger) GetTransactionsFromPool(blk block.Entity) (txList TransactionLi }, } - stateDB := l.StateDB.Copy() + parentRoot, err := l.getParentRoot() + if err != nil { + return + } + stateDB, err := l.NewState(parentRoot) + if err != nil { + return + } + mt := merkleTree.Tree{} for idx, tx := range txs { @@ -426,10 +503,7 @@ func (l *Ledger) GetTransactionsFromPool(blk block.Entity) (txList TransactionLi tx.TransactionResult.ReturnData = resultCache[CachedContractReturnData].Data tx.TransactionResult.NewAddress = resultCache[CachedContractCreationAddress].address - switch tx.Type { - case TxType.Transfer.String(): - l.setTransferState(tx.TransactionResult.NewState, stateDB) - } + l.setTransactionState(*tx, stateDB, nil) } txList.Transactions = append(txList.Transactions, *tx) @@ -437,6 +511,8 @@ func (l *Ledger) GetTransactionsFromPool(blk block.Entity) (txList TransactionLi txRoot, _ = mt.Calculate() stateRoot = stateDB.IntermediateRoot().Bytes() + + l.removeTransactionsFromPool(txList.Transactions) return } diff --git a/service/application/smartAssets/smartAssetsLedger/ledger_for_state.go b/service/application/smartAssets/smartAssetsLedger/ledger_for_state.go new file mode 100644 index 0000000..80c2ac3 --- /dev/null +++ b/service/application/smartAssets/smartAssetsLedger/ledger_for_state.go @@ -0,0 +1,49 @@ +package smartAssetsLedger + +import ( + "fmt" + "github.com/SealSC/SealABC/common" + "github.com/SealSC/SealABC/dataStructure/state" + "math/big" +) + +func (l *Ledger) NewState(root []byte) (stateDB *state.StateDB, err error) { + stateRoot := common.Hash{} + if len(root) != 0 { + stateRoot = common.BytesToHash(root) + } + + stateDB, err = state.New(stateRoot, state.NewDatabase(l.Storage), l.CryptoTools, &AccountTool{}) + if err != nil { + err = fmt.Errorf("failed to create state trie at %x: %v", root, err) + } + return +} + +func (l *Ledger) BalanceOf(address []byte) (balance *big.Int, err error) { + balance = l.stateDB.GetBalance(common.BytesToAddress(address)) + return +} + +func (l *Ledger) NonceOf(address []byte) (nonce uint64) { + nonce = l.stateDB.GetNonce(common.BytesToAddress(address)) + return +} + +func (l *Ledger) CodeHashOf(address []byte) (hash []byte) { + hash = l.stateDB.GetCodeHash(common.BytesToAddress(address)).Bytes() + return +} + +func (l *Ledger) CodeSizeOf(address []byte) (size int) { + size = l.stateDB.GetCodeSize(common.BytesToAddress(address)) + return +} + +func (l *Ledger) CodeOf(address []byte) []byte { + return l.stateDB.GetCode(common.BytesToAddress(address)) +} + +func (l *Ledger) StateOf(address []byte, key []byte) []byte { + return l.stateDB.GetState(common.BytesToAddress(address), common.BytesToHash(key)).Bytes() +} diff --git a/service/application/smartAssets/smartAssetsLedger/operationForContractCreation.go b/service/application/smartAssets/smartAssetsLedger/operationForContractCreation.go index 41afa58..d55ffdc 100644 --- a/service/application/smartAssets/smartAssetsLedger/operationForContractCreation.go +++ b/service/application/smartAssets/smartAssetsLedger/operationForContractCreation.go @@ -18,6 +18,9 @@ package smartAssetsLedger import ( + "encoding/hex" + "fmt" + "github.com/SealSC/SealABC/common" "github.com/SealSC/SealABC/metadata/block" "github.com/SealSC/SealEVM/evmInt256" "github.com/SealSC/SealEVM/opcodes" @@ -34,35 +37,38 @@ func (l *Ledger) preContractCreation(tx Transaction, cache txResultCache, blk bl initGas := cache[CachedBlockGasKey].gasLeft evm, contract, _ := l.newEVM(tx, nil, blk, evmInt256.New(int64(initGas))) - ret, err := evm.ExecuteContract(true) newState := l.newStateFromEVMResult(ret, cache) gasCost := initGas - ret.GasLeft - cache[CachedBlockGasKey].gasLeft -= gasCost + contractAddr := common.BytesToAddress(contract.Namespace.Bytes()) + contractAddrBytes := contractAddr.Bytes() + cache[CachedBlockGasKey].gasLeft -= gasCost if err == nil { if ret.ExitOpCode == opcodes.REVERT { err = Errors.ContractExecuteRevert return nil, nil, err } - contractAddr := contract.Namespace.Bytes() newState = append(newState, StateData{ - Key: BuildKey(StoragePrefixes.ContractCode, contractAddr), + Type: StateType.ContractCode.String(), + Key: contractAddrBytes, NewVal: ret.ResultData, }, StateData{ - Key: BuildKey(StoragePrefixes.ContractHash, contractAddr), + Type: StateType.ContractHash.String(), + Key: contractAddrBytes, NewVal: contract.Hash.Bytes(), }, ) } else { return nil, nil, Errors.ContractCreationFailed.NewErrorWithNewMessage(err.Error()) } - - cache[CachedContractCreationAddress].address = contract.Namespace.Bytes() + cache[CachedContractCreationAddress].address = contractAddrBytes cache[CachedContractReturnData].Data = ret.ResultData + + fmt.Println("contractAddress: ", hex.EncodeToString(contractAddrBytes)) return newState, cache, Errors.Success } diff --git a/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go b/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go index fd80b30..bebcad5 100644 --- a/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go +++ b/service/application/smartAssets/smartAssetsLedger/operationForTransfer.go @@ -90,14 +90,14 @@ func (l *Ledger) preTransfer(tx Transaction, cache txResultCache, _ block.Entity statusToChange := []StateData{ { - Type: StateType.TransferFrom.String(), + Type: StateType.Balance.String(), Key: tx.From, NewVal: fromBalance.Bytes(), OrgVal: orgFromBalance, }, { - Type: StateType.TransferTo.String(), + Type: StateType.Balance.String(), Key: tx.To, NewVal: toBalance.Bytes(), OrgVal: orgToBalance, diff --git a/service/application/smartAssets/smartAssetsLedger/storage.go b/service/application/smartAssets/smartAssetsLedger/storage.go index 6710499..5d97d75 100644 --- a/service/application/smartAssets/smartAssetsLedger/storage.go +++ b/service/application/smartAssets/smartAssetsLedger/storage.go @@ -18,7 +18,6 @@ package smartAssetsLedger import ( - "errors" "github.com/SealSC/SealABC/common/utility/serializer/structSerializer" "github.com/SealSC/SealABC/dataStructure/enum" "github.com/SealSC/SealEVM/environment" @@ -100,46 +99,20 @@ func (c *contractStorage) CanTransfer(from, to, val *evmInt256.Int) bool { } func (c *contractStorage) GetCode(address *evmInt256.Int) ([]byte, error) { - key := BuildKey(StoragePrefixes.ContractCode, address.Bytes()) - - codeKV, err := c.basedLedger.Storage.Get(key) - if err != nil { - return nil, err - } - - if !codeKV.Exists { - return nil, errors.New("no such contract") - } - - return codeKV.Data, nil + code := c.basedLedger.CodeOf(address.Bytes()) + return code, nil } func (c *contractStorage) GetCodeSize(address *evmInt256.Int) (*evmInt256.Int, error) { - key := BuildKey(StoragePrefixes.ContractCode, address.Bytes()) - - codeKV, err := c.basedLedger.Storage.Get(key) - if err != nil { - return nil, err - } - - if codeKV.Exists { - return evmInt256.New(int64(len(codeKV.Data))), nil - } - return evmInt256.New(0), nil + size := c.basedLedger.CodeSizeOf(address.Bytes()) + return evmInt256.New(int64(size)), nil } func (c *contractStorage) GetCodeHash(address *evmInt256.Int) (*evmInt256.Int, error) { - key := BuildKey(StoragePrefixes.ContractHash, address.Bytes()) - hashKV, err := c.basedLedger.Storage.Get(key) - if err != nil { - return nil, err - } - ret := evmInt256.New(0) - //todo: if not exists, in ethereum protocol there's several return situations need to be done in future - if hashKV.Exists { - ret.SetBytes(hashKV.Data) - } + hash := c.basedLedger.CodeHashOf(address.Bytes()) + // todo: if not exists, in ethereum protocol there's several return situations need to be done in future + ret.SetBytes(hash) return ret, nil } @@ -189,17 +162,8 @@ func (c *contractStorage) CreateFixedAddress(caller *evmInt256.Int, salt *evmInt } func (c *contractStorage) Load(n string, k string) (*evmInt256.Int, error) { - key := BuildKey(StoragePrefixes.ContractData, []byte(n), []byte(k)) - data, err := c.basedLedger.Storage.Get(key) - - if err != nil { - return nil, err - } - ret := evmInt256.New(0) - if data.Exists { - ret.SetBytes(data.Data) - } - + data := c.basedLedger.StateOf([]byte(n), []byte(k)) + ret.SetBytes(data) return ret, nil } diff --git a/service/application/smartAssets/smartAssetsLedger/transaction.go b/service/application/smartAssets/smartAssetsLedger/transaction.go index 1a8279f..b379c36 100644 --- a/service/application/smartAssets/smartAssetsLedger/transaction.go +++ b/service/application/smartAssets/smartAssetsLedger/transaction.go @@ -41,8 +41,8 @@ var TxType struct { } var StateType struct { - TransferFrom enum.Element - TransferTo enum.Element + Balance enum.Element + ContractData enum.Element ContractCode enum.Element ContractHash enum.Element } @@ -63,8 +63,8 @@ func GetTxTypeCodeForName(name string) int { } type TransactionData struct { - Nonce uint64 Type string + Nonce uint64 From []byte To []byte Value string @@ -76,6 +76,7 @@ type TransactionData struct { type StateData struct { Type string Key []byte + SubKey []byte NewVal []byte OrgVal []byte } diff --git a/service/application/smartAssets/smartAssetsLedger/txpool.go b/service/application/smartAssets/smartAssetsLedger/txpool.go index 0daa72f..70443cf 100644 --- a/service/application/smartAssets/smartAssetsLedger/txpool.go +++ b/service/application/smartAssets/smartAssetsLedger/txpool.go @@ -100,7 +100,11 @@ func (pool *TxPool) add(tx *Transaction) (bool, error) { } func (pool *TxPool) validateTx(tx *Transaction) error { - amount, _ := big.NewInt(0).SetString(string(tx.Value), 10) + value := tx.Value + if value == "" { + value = "0" + } + amount, _ := big.NewInt(0).SetString(value, 10) if amount.Sign() < 0 { return ErrNegativeValue } @@ -166,25 +170,16 @@ func (pool *TxPool) removeTx(hash common.Hash) { if removed, _ := pending.Remove(tx); removed { if pending.Empty() { delete(pool.pending, addr) - } else { - //for _, tx := range invalids { - // - //} - } - - if nonce := tx.Nonce; pool.pendingState.GetNonce(addr) > nonce { - pool.pendingState.SetNonce(addr, nonce) } - return } } - //if future := pool.queue[addr]; future != nil { - // future.Remove(tx) - // if future.Empty() { - // delete(pool.queue, addr) - // } - //} + if future := pool.queue[addr]; future != nil { + future.Remove(tx) + if future.Empty() { + delete(pool.queue, addr) + } + } } func (pool *TxPool) enqueueTx(hash common.Hash, tx *Transaction) (bool, error) { @@ -225,5 +220,6 @@ func (pool *TxPool) Pending() Transactions { for _, list := range pool.pending { pending = append(pending, list.Flatten()...) } + return pending } diff --git a/service/system/blockchain/chainStructure/operator.go b/service/system/blockchain/chainStructure/operator.go index 8df5481..c6c12fe 100644 --- a/service/system/blockchain/chainStructure/operator.go +++ b/service/system/blockchain/chainStructure/operator.go @@ -89,7 +89,7 @@ func (b *Blockchain) InternalCall(src string, dst string, data []byte) (ret inte func (b *Blockchain) AddBlock(blk block.Entity) (err error) { err = b.executeRequest(&blk) if err != nil { - log.Log.Error("execute requests in the block failed!") + log.Log.Error("execute requests in the block failed!", err) return }