Merge pull request #55 from meshplus/ledger

refactor(ledger): use KV instead of tree
This commit is contained in:
Aiden X 2020-04-26 21:05:59 +08:00 committed by GitHub
commit fc272f869a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 667 additions and 315 deletions

View File

@ -20,18 +20,18 @@ func (cbs *ChainBrokerService) GetAccountBalance(ctx context.Context, req *pb.Ad
account := cbs.api.Account().GetAccount(addr)
hash := types.Bytes2Hash(account.CodeHash)
hash := types.Bytes2Hash(account.CodeHash())
typ := "normal"
if account.CodeHash != nil {
if account.CodeHash() != nil {
typ = "contract"
}
ret := &Account{
Type: typ,
Balance: account.Balance,
ContractCount: account.Nonce,
Balance: account.GetBalance(),
ContractCount: account.GetNonce(),
CodeHash: hash,
}

5
go.mod
View File

@ -9,6 +9,7 @@ require (
github.com/gobuffalo/packr v1.30.1
github.com/gogo/protobuf v1.3.1
github.com/golang/mock v1.4.3
github.com/golangci/golangci-lint v1.23.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.13.0
github.com/hokaccha/go-prettyjson v0.0.0-20190818114111-108c894c2c0e
github.com/libp2p/go-libp2p-core v0.3.0
@ -17,6 +18,7 @@ require (
github.com/meshplus/bitxhub-kit v1.0.0
github.com/meshplus/bitxhub-model v1.0.0-rc4
github.com/meshplus/go-bitxhub-client v1.0.0-rc4
github.com/minio/sha256-simd v0.1.1
github.com/mitchellh/go-homedir v1.1.0
github.com/multiformats/go-multiaddr v0.2.0
github.com/pkg/errors v0.9.1
@ -26,14 +28,11 @@ require (
github.com/spf13/viper v1.6.1
github.com/stretchr/testify v1.4.0
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d
github.com/tendermint/iavl v0.12.4
github.com/tendermint/tm-db v0.1.1
github.com/tidwall/gjson v1.3.5
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5
github.com/urfave/cli v1.22.1
github.com/wasmerio/go-ext-wasm v0.3.1
github.com/willf/bloom v2.0.3+incompatible
github.com/wonderivan/logger v1.0.0
google.golang.org/grpc v1.27.1
)

134
go.sum
View File

@ -21,6 +21,8 @@ github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8L
github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us=
github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM=
github.com/Rican7/retry v0.1.0 h1:FqK94z34ly8Baa6K+G8Mmza9rYWTKOJk+yckIBB5qVk=
github.com/Rican7/retry v0.1.0/go.mod h1:FgOROf8P5bebcC1DS0PdOQiqGUridaZvikzUmkFW6gg=
github.com/Shopify/sarama v1.26.1 h1:3jnfWKD7gVwbB1KSy/lE0szA9duPuSFLViK0o/d3DgA=
@ -53,6 +55,8 @@ github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bombsimon/wsl/v2 v2.0.0 h1:+Vjcn+/T5lSrO8Bjzhk4v14Un/2UyCA1E3V5j9nwTkQ=
github.com/bombsimon/wsl/v2 v2.0.0/go.mod h1:mf25kr/SqFEPhhcxW1+7pxzGlW+hIl/hYTKY95VwV8U=
github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ=
github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0=
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78=
@ -108,6 +112,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSY
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -163,18 +168,43 @@ github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-critic/go-critic v0.4.1 h1:4DTQfT1wWwLg/hzxwD9bkdhDQrdJtxe6DUTadPlrIeE=
github.com/go-critic/go-critic v0.4.1/go.mod h1:7/14rZGnZbY6E38VEGk2kVhoq6itzc1E68facVDK23g=
github.com/go-kit/kit v0.6.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-lintpack/lintpack v0.5.2 h1:DI5mA3+eKdWeJ40nU4d6Wc26qmdG8RCi/btYq0TuRN0=
github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
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/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g=
github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4=
github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8=
github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ=
github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ=
github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg=
github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k=
github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw=
github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU=
github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk=
github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg=
github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI=
github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks=
github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc=
github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4=
github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
github.com/go-toolsmith/typep v1.0.0 h1:zKymWyA1TRYvqYrYDrfEMZULyrhcnGY3x7LDKU2XQaA=
github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU=
github.com/gobuffalo/envy v1.7.0 h1:GlXgaiBkmrYMHco6t4j7SacKO4XUjvh5pwXh0f4uxXU=
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
github.com/gobuffalo/envy v1.9.0 h1:eZR0DuEgVLfeIb1zIKt3bT4YovIMf9O9LXQeCZLXpqE=
@ -189,6 +219,10 @@ github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wK
github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk=
github.com/gobuffalo/packr/v2 v2.5.1 h1:TFOeY2VoGamPjQLiNDT3mn//ytzk236VMO2j7iHxJR4=
github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b h1:ekuhfTjngPhisSjOJ0QWKpPQE8/rbknHaes6WVJj5Hw=
github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
@ -219,6 +253,36 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pO
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0=
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4=
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM=
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk=
github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6 h1:YYWNAGTKWhKpcLLt7aSj/odlKrSrelQwlovBpDuf19w=
github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0=
github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw=
github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8=
github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3 h1:pe9JHs3cHHDQgOFXJJdYkK6fLz2PWyYtP4hthoCMvs8=
github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o=
github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee h1:J2XAy40+7yz70uaOiMbNnluTg7gyQhtGqLQncQh+4J8=
github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU=
github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks=
github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU=
github.com/golangci/golangci-lint v1.23.0 h1:KbgYALkl4Xi1e39eXhdIFj4ldWUbzAK3F6YOKypTplg=
github.com/golangci/golangci-lint v1.23.0/go.mod h1:LNexeEyqT5hQH7v47e67JekL0V51lXFUjbPkopxNSK4=
github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc h1:gLLhTLMk2/SutryVJ6D4VZCU3CUqr8YloG7FPIBWFpI=
github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU=
github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA=
github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg=
github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA=
github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o=
github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770 h1:EL/O5HGrF7Jaq0yNhBLucz9hTuRzj2LdwGBOaENgxIk=
github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA=
github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21 h1:leSNB7iYzLYSSx3J/s5sVf4Drkc68W2wm4Ixh/mr0us=
github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI=
github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0 h1:HVfrLniijszjS1aiNg8JbBMO2+E1WIQ+j/gL4SQqGPg=
github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4=
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys=
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@ -231,6 +295,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
@ -241,6 +306,8 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA
github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3 h1:JVnpOZS+qxli+rgVl98ILOXVNbW+kb5wcxeGx8ShUIw=
github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
@ -331,9 +398,14 @@ github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a h1:GmsqmapfzSJkm28dhRoHz2tLRbJmqhU86IPgBtN3mmk=
github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a/go.mod h1:xRskid8CManxVta/ALEhJha/pweKBaVG6fWgc0yH25s=
github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3 h1:jNYPNLe3d8smommaoQlK7LOA5ESyUJJ+Wf79ZtA7Vp4=
github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U=
github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ=
github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
@ -356,9 +428,13 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.10.1 h1:a/QY0o9S6wCi0XhxaMX/QmusicNUqCqFugR6WKPOSoQ=
github.com/klauspost/compress v1.10.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
@ -374,6 +450,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
@ -383,6 +460,8 @@ github.com/lestrrat-go/file-rotatelogs v2.2.0+incompatible h1:eXEwY0f2h6mcobdAxm
github.com/lestrrat-go/file-rotatelogs v2.2.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
github.com/lestrrat-go/strftime v1.0.0 h1:wZIfTHGdu7TeGu318uLJwuQvTMt9UpRyS+XV2Rc4wo4=
github.com/lestrrat-go/strftime v1.0.0/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/libp2p/go-addr-util v0.0.1 h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88=
github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ=
github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg=
@ -487,11 +566,14 @@ github.com/libp2p/go-yamux v1.2.2 h1:s6J6o7+ajoQMjHe7BEnq+EynOj5D2EoG8CuQgL3F2vg
github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow=
github.com/libp2p/go-yamux v1.2.3 h1:xX8A36vpXb59frIzWFdEgptLMsOANMFq2K7fPRlunYI=
github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow=
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb h1:RHba4YImhrUVQDHUCe2BNSOz4tVy2yGyXhvYDvxGgeE=
github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=
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.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
@ -509,6 +591,8 @@ github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW1
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
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-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/meshplus/bitxhub v1.0.0-rc2/go.mod h1:ijWzPl7GExD3IKXJ0LhV4q680kDy1IFQKd2Kzyzmtl0=
@ -544,6 +628,7 @@ github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKU
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -552,6 +637,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
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/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ=
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
@ -600,6 +686,8 @@ github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1ORQBMvzfzBgpsctsbQikCVpvC+tX285E=
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
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=
@ -625,6 +713,7 @@ github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
@ -670,6 +759,7 @@ github.com/prometheus/procfs v0.0.10 h1:QJQN3jYQhkamO4mhfUWqdDH2asK7ONOI9MTWjyAx
github.com/prometheus/procfs v0.0.10/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
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/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563 h1:dY6ETXrvDG7Sa4vE8ZQG4yqWg6UnOcbqTAahkV813vQ=
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
@ -696,6 +786,12 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
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/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/securego/gosec v0.0.0-20200103095621-79fbf3af8d83 h1:AtnWoOvTioyDXFvu96MWEeE8qj4COSQnJogzLy/u41A=
github.com/securego/gosec v0.0.0-20200103095621-79fbf3af8d83/go.mod h1:vvbZ2Ae7AzSq3/kywjUDxSNq2SJ27RxCz2un0H3ePqE=
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
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=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
@ -710,6 +806,8 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9
github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY=
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/sourcegraph/go-diff v0.5.1 h1:gO6i5zugwzo1RVTvgvfwCOSVegNuvnNi6bAD1QCmkHs=
github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE=
github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0=
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU=
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc=
@ -778,17 +876,31 @@ github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e h1:RumXZ56IrCj4CL+g1b9OL/oH0QnsF976bC8xQFYUD5Q=
github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
github.com/tjfoc/gmsm v1.3.0/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tommy-muehle/go-mnd v1.1.1 h1:4D0wuPKjOTiK2garzuPGGvm4zZ/wLYDOH8TJSABC7KU=
github.com/tommy-muehle/go-mnd v1.1.1/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig=
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ultraware/funlen v0.0.2 h1:Av96YVBwwNSe4MLR7iI/BIa3VyI7/djnto/pK3Uxbdo=
github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
github.com/ultraware/whitespace v0.0.4 h1:If7Va4cM03mpgrNH9k49/VOicWpGoG70XPBFFODYDsg=
github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA=
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.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
github.com/uudashr/gocognit v1.0.1 h1:MoG2fZ0b/Eo7NXoIwCVFLG5JED3qgQz5/NEE+rOsjPs=
github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/wasmerio/go-ext-wasm v0.3.1 h1:G95XP3fE2FszQSwIU+fHPBYzD0Csmd2ef33snQXNA5Q=
github.com/wasmerio/go-ext-wasm v0.3.1/go.mod h1:VGyarTzasuS7k5KhSIGpM3tciSZlkP31Mp9VJTHMMeI=
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc=
@ -873,6 +985,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
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-20180911220305-26e67e76b6c3/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-20181220203305-927f97764cc3 h1:eH6Eip3UpmR+yM/qI9Ijluzb1bNv/cAU/n+6l8tRSis=
@ -889,6 +1002,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2 h1:4dVFTC832rPn4pomLSz1vA+are2+dU19w1H8OngV7nc=
golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0 h1:2mqDk8w/o6UmeUCu5Qiq2y7iMf6anbx+YA8d1JFoFrs=
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@ -942,21 +1056,33 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZe
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181130052023-1c3d964395ce/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190221204921-83362c3779f5/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c h1:KfpJVdWhuRqNk4XVXzjXf2KAV4TBEP77SYdFGjeGuIE=
golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113232020-e2727e816f5a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200102140908-9497f49d5709/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd h1:hHkvGJK23seRCflePJnVa9IMv8fsuavSCWKd11kDQFs=
golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -1039,5 +1165,13 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069z
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I=
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo=
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4 h1:JPJh2pk3+X4lXAkZIk2RuE/7/FoK9maXw+TNPJhVS/c=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=

View File

@ -55,7 +55,7 @@ func TestBlockExecutor_ExecuteBlock(t *testing.T) {
evs = append(evs, ev)
mockLedger.EXPECT().GetChainMeta().Return(chainMeta).AnyTimes()
mockLedger.EXPECT().Events(gomock.Any()).Return(evs).AnyTimes()
mockLedger.EXPECT().Commit().Return(types.String2Hash(from), nil).AnyTimes()
mockLedger.EXPECT().Commit(gomock.Any()).Return(types.String2Hash(from), nil).AnyTimes()
mockLedger.EXPECT().Clear().AnyTimes()
mockLedger.EXPECT().GetState(gomock.Any(), gomock.Any()).Return(true, []byte("10")).AnyTimes()
mockLedger.EXPECT().SetState(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
@ -178,7 +178,7 @@ func TestBlockExecutor_ExecuteBlock_Transfer(t *testing.T) {
_, from := loadAdminKey(t)
ledger.SetBalance(from, 100000000)
_, err = ledger.Commit()
_, err = ledger.Commit(1)
require.Nil(t, err)
err = ledger.PersistExecutionResult(mockBlock(1, nil), nil)
require.Nil(t, err)

View File

@ -68,7 +68,7 @@ func (exec *BlockExecutor) processExecuteEvent(block *pb.Block) {
}
block.BlockHeader.InterchainIndex = idx
hash, err := exec.ledger.Commit()
hash, err := exec.ledger.Commit(block.BlockHeader.Number)
if err != nil {
panic(err)
}

View File

@ -3,141 +3,289 @@ package ledger
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"sort"
"github.com/meshplus/bitxhub-kit/types"
"github.com/tendermint/iavl"
db "github.com/tendermint/tm-db"
"github.com/meshplus/bitxhub/pkg/storage"
"github.com/syndtr/goleveldb/leveldb/errors"
)
type Account struct {
Nonce uint64 `json:"nonce"`
Balance uint64 `json:"balance"`
Version int64 `json:"version"`
StateRoot types.Hash `json:"merkle_root"`
CodeHash []byte `json:"code_hash"`
tree *iavl.MutableTree
code []byte
Addr types.Address
originAccount *innerAccount
dirtyAccount *innerAccount
originState map[string][]byte
dirtyState map[string][]byte
originCode []byte
dirtyCode []byte
dirtyStateHash types.Hash
ldb storage.Storage
}
func newAccount(l *ChainLedger, ldb db.DB, addr types.Address) *Account {
account := &Account{}
_, data := l.tree.Get(compositeKey(accountKey, addr.Hex()))
if data != nil {
if err := account.Unmarshal(data); err != nil {
panic(err)
}
type innerAccount struct {
Nonce uint64 `json:"nonce"`
Balance uint64 `json:"balance"`
CodeHash []byte `json:"code_hash"`
}
func newAccount(ldb storage.Storage, addr types.Address) *Account {
return &Account{
Addr: addr,
originState: make(map[string][]byte),
dirtyState: make(map[string][]byte),
ldb: ldb,
}
}
// GetState Get state from local cache, if not found, then get it from DB
func (o *Account) GetState(key []byte) (bool, []byte) {
hexKey := hex.EncodeToString(key)
if val, exist := o.dirtyState[hexKey]; exist {
return val != nil, val
}
p := []byte(fmt.Sprintf("account-%s", addr.Hex()))
tree := iavl.NewMutableTree(db.NewPrefixDB(ldb, p), defaultIAVLCacheSize)
_, err := tree.Load()
if err != nil {
if val, exist := o.originState[hexKey]; exist {
return val != nil, val
}
val, err := o.ldb.Get(append(o.Addr.Bytes(), key...))
if err != nil && err != errors.ErrNotFound {
panic(err)
}
account.tree = tree
return account
}
o.originState[hexKey] = val
// GetState Get state from the tree
func (o *Account) GetState(key []byte) (bool, []byte) {
_, v := o.tree.Get(key)
return v != nil, v
return val != nil, val
}
// SetState Set account state
func (o *Account) SetState(key []byte, value []byte) {
o.tree.Set(key, value)
o.dirtyState[hex.EncodeToString(key)] = value
}
// SetCodeAndHash Set the contract code and hash
func (o *Account) SetCodeAndHash(code []byte) {
ret := sha256.Sum256(code)
o.CodeHash = ret[:]
o.SetState(o.CodeHash, code)
o.code = code
if o.dirtyAccount == nil {
o.dirtyAccount = copyOrNewIfEmpty(o.originAccount)
}
o.dirtyAccount.CodeHash = ret[:]
o.dirtyCode = code
}
// Code return the contract code
func (o *Account) Code() []byte {
if o.code != nil {
return o.code
if o.dirtyCode != nil {
return o.dirtyCode
}
if bytes.Equal(o.CodeHash, nil) {
if o.originCode != nil {
return o.originCode
}
if bytes.Equal(o.CodeHash(), nil) {
return nil
}
ok, code := o.GetState(o.CodeHash)
if !ok {
return nil
code, err := o.ldb.Get(compositeKey(codeKey, o.Addr.Hex()))
if err != nil && err != errors.ErrNotFound {
panic(err)
}
o.code = code
o.originCode = code
o.dirtyCode = code
return code
}
func (o *Account) CodeHash() []byte {
if o.dirtyAccount != nil {
return o.dirtyAccount.CodeHash
}
if o.originAccount != nil {
return o.originAccount.CodeHash
}
return nil
}
// SetNonce Set the nonce which indicates the contract number
func (o *Account) SetNonce(nonce uint64) {
o.Nonce = nonce
if o.dirtyAccount == nil {
o.dirtyAccount = copyOrNewIfEmpty(o.originAccount)
}
o.dirtyAccount.Nonce = nonce
}
// GetNonce Get the nonce from user account
func (o *Account) GetNonce() uint64 {
return o.Nonce
if o.dirtyAccount != nil {
return o.dirtyAccount.Nonce
}
if o.originAccount != nil {
return o.originAccount.Nonce
}
return 0
}
// SetStateRoot Set the state root hash
func (o *Account) SetStateRoot(hash types.Hash) {
o.StateRoot = hash
// GetBalance Get the balance from the account
func (o *Account) GetBalance() uint64 {
if o.dirtyAccount != nil {
return o.dirtyAccount.Balance
}
if o.originAccount != nil {
return o.originAccount.Balance
}
return 0
}
// SetBalance Set the balance to the account
func (o *Account) SetBalance(balance uint64) {
if o.dirtyAccount == nil {
o.dirtyAccount = copyOrNewIfEmpty(o.originAccount)
}
o.dirtyAccount.Balance = balance
}
// Query Query the value using key
func (o *Account) Query(prefix string) (bool, [][]byte) {
var ret [][]byte
begin, end := bytesPrefix([]byte(prefix))
o.tree.IterateRange(begin, end, false, func(key []byte, value []byte) bool {
ret = append(ret, value)
return false
})
begin, end := bytesPrefix(append(o.Addr.Bytes(), prefix...))
it := o.ldb.Iterator(begin, end)
for it.Next() {
val := make([]byte, len(it.Value()))
copy(val, it.Value())
ret = append(ret, val)
}
return len(ret) != 0, ret
}
// Commit Commit the result
func (o *Account) Commit() (types.Hash, error) {
hash, ver, err := o.tree.SaveVersion()
if err != nil {
return types.Hash{}, err
func (o *Account) getJournalIfModified(ldbBatch storage.Batch) []journalEntry {
var entries []journalEntry
if !innerAccountChanged(o.originAccount, o.dirtyAccount) {
data, err := o.dirtyAccount.Marshal()
if err != nil {
panic(err)
}
ldbBatch.Put(compositeKey(accountKey, o.Addr.Hex()), data)
entries = append(entries, accountChange{address: o.Addr, prevAccount: o.originAccount})
}
o.Version = ver
if bytes.Compare(o.originCode, o.dirtyCode) != 0 {
if o.dirtyCode != nil {
ldbBatch.Put(compositeKey(codeKey, o.Addr.Hex()), o.dirtyCode)
} else {
ldbBatch.Delete(compositeKey(codeKey, o.Addr.Hex()))
}
entries = append(entries, codeChange{address: o.Addr, prevCode: o.originCode})
}
return types.Bytes2Hash(hash), nil
stateJournal := o.getStateJournalAndComputeHash(ldbBatch)
if len(stateJournal.prevStates) != 0 {
entries = append(entries, stateJournal)
}
return entries
}
func (o *Account) getStateJournalAndComputeHash(ldbBatch storage.Batch) stateChange {
stateJournal := stateChange{
address: o.Addr,
prevStates: make(map[string][]byte),
}
var dirtyStateKeys []string
var dirtyStateData []byte
for key, val := range o.dirtyState {
origVal := o.originState[key]
if bytes.Compare(origVal, val) != 0 {
dirtyStateKeys = append(dirtyStateKeys, key)
byteKey, err := hex.DecodeString(key)
if err != nil {
panic(err)
}
if val != nil {
ldbBatch.Put(append(o.Addr.Bytes(), byteKey...), val)
} else {
ldbBatch.Delete(append(o.Addr.Bytes(), byteKey...))
}
stateJournal.prevStates[key] = origVal
}
}
sort.Strings(dirtyStateKeys)
for _, key := range dirtyStateKeys {
dirtyStateData = append(dirtyStateData, key...)
dirtyStateData = append(dirtyStateData, o.dirtyState[key]...)
}
o.dirtyStateHash = sha256.Sum256(dirtyStateData)
return stateJournal
}
func (o *Account) getDirtyData() []byte {
var dirtyData []byte
dirtyData = append(dirtyData, o.Addr.Bytes()...)
if o.dirtyAccount != nil {
data, err := o.dirtyAccount.Marshal()
if err != nil {
panic(err)
}
dirtyData = append(dirtyData, data...)
}
return append(dirtyData, o.dirtyStateHash[:]...)
}
func innerAccountChanged(account0 *innerAccount, account1 *innerAccount) bool {
if account1 == nil ||
account0 != nil &&
account0.Nonce == account1.Nonce &&
account0.Balance == account1.Balance &&
bytes.Compare(account0.CodeHash, account1.CodeHash) == 0 {
return true
}
return false
}
// Marshal Marshal the account into byte
func (o *Account) Marshal() ([]byte, error) {
obj := &Account{
Nonce: o.Nonce,
Balance: o.Balance,
CodeHash: o.CodeHash,
Version: o.Version,
StateRoot: o.StateRoot,
func (o *innerAccount) Marshal() ([]byte, error) {
obj := &innerAccount{
Nonce: o.Nonce,
Balance: o.Balance,
CodeHash: o.CodeHash,
}
return json.Marshal(obj)
}
// Unmarshal Unmarshal the account byte into structure
func (o *Account) Unmarshal(data []byte) error {
func (o *innerAccount) Unmarshal(data []byte) error {
return json.Unmarshal(data, o)
}
func copyOrNewIfEmpty(o *innerAccount) *innerAccount {
if o == nil {
return &innerAccount{}
}
return &innerAccount{
Nonce: o.Nonce,
Balance: o.Balance,
CodeHash: o.CodeHash,
}
}
func bytesPrefix(prefix []byte) ([]byte, []byte) {
var limit []byte
for i := len(prefix) - 1; i >= 0; i-- {

View File

@ -4,16 +4,13 @@ import (
"io/ioutil"
"testing"
"github.com/meshplus/bitxhub-kit/crypto/asym"
"github.com/meshplus/bitxhub-kit/log"
"github.com/meshplus/bitxhub/pkg/storage/leveldb"
"github.com/stretchr/testify/require"
"github.com/meshplus/bitxhub-kit/bytesutil"
"github.com/meshplus/bitxhub-kit/crypto/asym"
"github.com/meshplus/bitxhub-kit/hexutil"
"github.com/meshplus/bitxhub-kit/log"
"github.com/meshplus/bitxhub-kit/types"
"github.com/meshplus/bitxhub/pkg/storage/leveldb"
"github.com/stretchr/testify/assert"
db "github.com/tendermint/tm-db"
)
func TestAccount_GetState(t *testing.T) {
@ -26,60 +23,18 @@ func TestAccount_GetState(t *testing.T) {
ledger, err := New(repoRoot, blockStorage, log.NewWithModule("ChainLedger"))
assert.Nil(t, err)
dir, err := ioutil.TempDir("", "")
require.Nil(t, err)
ldb, err := db.NewGoLevelDB("ledger", dir)
assert.Nil(t, err)
ldb := ledger.ldb
h := hexutil.Encode(bytesutil.LeftPadBytes([]byte{11}, 20))
addr := types.String2Address(h)
account := newAccount(ledger, ldb, addr)
account := newAccount(ldb, addr)
account.SetState([]byte("a"), []byte("b"))
ok, v := account.GetState([]byte("a"))
assert.True(t, ok)
assert.Equal(t, []byte("b"), v)
// save into db
hash, err := account.Commit()
assert.Nil(t, err)
assert.Equal(t, "0x07babb4c717e4c854558e806f6c0c82344009b234f1733b638c14730f625e8d1", hash.Hex())
// recreate account
account2 := newAccount(ledger, ldb, addr)
ok2, v2 := account2.GetState([]byte("a"))
assert.True(t, ok2)
assert.Equal(t, []byte("b"), v2)
}
func TestAccount_Commit(t *testing.T) {
_, err := asym.GenerateKey(asym.ECDSASecp256r1)
assert.Nil(t, err)
repoRoot, err := ioutil.TempDir("", "ledger_commit")
assert.Nil(t, err)
blockStorage, err := leveldb.New(repoRoot)
assert.Nil(t, err)
ledger, err := New(repoRoot, blockStorage, log.NewWithModule("ChainLedger"))
assert.Nil(t, err)
dir, err := ioutil.TempDir("", "")
require.Nil(t, err)
ldb, err := db.NewGoLevelDB("ledger", dir)
assert.Nil(t, err)
h := hexutil.Encode(bytesutil.LeftPadBytes([]byte{11}, 20))
addr := types.String2Address(h)
account := newAccount(ledger, ldb, addr)
account.SetState([]byte("alice"), []byte("bob"))
// save into db
hash, err := account.Commit()
assert.Nil(t, err)
assert.Equal(t, "0x73f56a5593a5ab27d7db1c91bd1c78d26ebd3c5a235a226428f57d4abaa49fab", hash.Hex())
account.SetState([]byte("a"), []byte("b"))
hash, err = account.Commit()
assert.Nil(t, err)
assert.Equal(t, "0x8ebbcd9523cf21e5b284325542f8e7dcf588f3cddd2e94342a2acdbfb9dd3358", hash.Hex())
account.SetState([]byte("a"), nil)
ok, v = account.GetState([]byte("a"))
assert.False(t, ok)
}

View File

@ -28,7 +28,7 @@ func Initialize(config *repo.Config, ledger ledger.Ledger) error {
ledger.SetState(roleAddr, []byte("admin-roles"), body)
hash, err := ledger.Commit()
hash, err := ledger.Commit(1)
if err != nil {
return err
}

View File

@ -0,0 +1,84 @@
package ledger
import (
"fmt"
"github.com/meshplus/bitxhub-kit/types"
"github.com/meshplus/bitxhub/pkg/storage"
)
type journalEntry interface {
revert(batch storage.Batch)
}
type (
accountChange struct {
address types.Address
prevAccount *innerAccount
}
stateChange struct {
address types.Address
prevStates map[string][]byte
}
codeChange struct {
address types.Address
prevCode []byte
}
)
type BlockJournal struct {
journals []journalEntry
changedHash types.Hash
}
func (journal accountChange) revert(batch storage.Batch) {
if journal.prevAccount != nil {
data, err := journal.prevAccount.Marshal()
if err != nil {
panic(err)
}
batch.Put(compositeKey(accountKey, journal.address.Hex()), data)
} else {
batch.Delete(compositeKey(accountKey, journal.address.Hex()))
}
}
func (journal stateChange) revert(batch storage.Batch) {
for key, val := range journal.prevStates {
if val != nil {
batch.Put(compositeKey(journal.address.Hex(), key), val)
} else {
batch.Delete(compositeKey(journal.address.Hex(), key))
}
}
}
func (journal codeChange) revert(batch storage.Batch) {
if journal.prevCode != nil {
batch.Put(compositeKey(codeKey, journal.address.Hex()), journal.prevCode)
} else {
batch.Delete(compositeKey(codeKey, journal.address.Hex()))
}
}
func getHeightFromJournal(ldb storage.Storage) (uint64, error) {
height := uint64(0)
begin, end := bytesPrefix([]byte(journalKey))
it := ldb.Iterator(begin, end)
for it.Next() {
h := uint64(0)
_, e := fmt.Sscanf(string(it.Key()), journalKey+"%d", &h)
if e != nil {
return 0, e
}
if h > height {
height = h
}
}
return height, nil
}

View File

@ -3,13 +3,15 @@ package ledger
import "fmt"
const (
ledgerTreePrefix = "ChainLedger"
blockKey = "block-"
blockHashKey = "block-hash-"
receiptKey = "receipt-"
transactionKey = "tx-"
transactionMetaKey = "tx-meta-"
chainMetaKey = "chain-meta"
accountKey = "account-"
codeKey = "code-"
journalKey = "journal-"
)
func compositeKey(prefix string, value interface{}) []byte {

View File

@ -1,7 +1,6 @@
package ledger
import (
"bytes"
"fmt"
"sync"
@ -9,10 +8,8 @@ import (
"github.com/meshplus/bitxhub-model/pb"
"github.com/meshplus/bitxhub/internal/repo"
"github.com/meshplus/bitxhub/pkg/storage"
"github.com/meshplus/bitxhub/pkg/storage/leveldb"
"github.com/sirupsen/logrus"
"github.com/tendermint/iavl"
db "github.com/tendermint/tm-db"
"github.com/wonderivan/logger"
)
var _ Ledger = (*ChainLedger)(nil)
@ -21,19 +18,14 @@ var (
ErrorRollbackTohigherNumber = fmt.Errorf("rollback to higher blockchain height")
)
const (
defaultIAVLCacheSize = 10000
)
type ChainLedger struct {
logger logrus.FieldLogger
blockchainStore storage.Storage
ldb db.DB
tree *iavl.MutableTree
ldb storage.Storage
height uint64
events map[string][]*pb.Event
accounts map[string]*Account
modifiedAccount map[string]bool
prevJournalHash types.Hash
chainMutex sync.RWMutex
chainMeta *pb.ChainMeta
@ -41,7 +33,7 @@ type ChainLedger struct {
// New create a new ledger instance
func New(repoRoot string, blockchainStore storage.Storage, logger logrus.FieldLogger) (*ChainLedger, error) {
ldb, err := db.NewGoLevelDB("ledger", repo.GetStoragePath(repoRoot))
ldb, err := leveldb.New(repo.GetStoragePath(repoRoot, "ledger"))
if err != nil {
return nil, fmt.Errorf("create tm-leveldb: %w", err)
}
@ -51,13 +43,12 @@ func New(repoRoot string, blockchainStore storage.Storage, logger logrus.FieldLo
return nil, fmt.Errorf("load chain meta: %w", err)
}
tree := iavl.NewMutableTree(db.NewPrefixDB(ldb, []byte(ledgerTreePrefix)), defaultIAVLCacheSize)
height, err := tree.LoadVersionForOverwriting(int64(chainMeta.Height))
height, err := getHeightFromJournal(ldb)
if err != nil {
return nil, fmt.Errorf("load state tree: %w", err)
return nil, fmt.Errorf("get journal height: %w", err)
}
if uint64(height) < chainMeta.Height {
if height < chainMeta.Height {
// TODO(xcc): how to handle this case
panic("state tree height is less than blockchain height")
}
@ -67,10 +58,9 @@ func New(repoRoot string, blockchainStore storage.Storage, logger logrus.FieldLo
chainMeta: chainMeta,
blockchainStore: blockchainStore,
ldb: ldb,
tree: tree,
height: height,
events: make(map[string][]*pb.Event, 10),
accounts: make(map[string]*Account),
modifiedAccount: make(map[string]bool),
}, nil
}
@ -99,34 +89,7 @@ func (l *ChainLedger) Rollback(height uint64) error {
// clean cache account
l.Clear()
_, err = l.tree.LoadVersionForOverwriting(int64(height))
if err != nil {
return err
}
begin, end := bytesPrefix([]byte(accountKey))
l.tree.IterateRange(begin, end, false, func(key []byte, value []byte) bool {
arr := bytes.Split(key, []byte("-"))
if len(arr) != 2 {
logger.Info("wrong account key")
}
a := newAccount(l, l.ldb, types.String2Address(string(arr[1])))
if err := a.Unmarshal(value); err != nil {
logger.Error(err)
}
if _, err := a.tree.LoadVersionForOverwriting(a.Version); err != nil {
logger.Error(err)
}
_, err = a.Commit()
if err != nil {
logger.Error(err)
}
return false
})
// TODO
return nil
}

View File

@ -7,7 +7,6 @@ import (
"github.com/meshplus/bitxhub-kit/bytesutil"
"github.com/meshplus/bitxhub-kit/log"
"github.com/meshplus/bitxhub-kit/types"
"github.com/meshplus/bitxhub-model/pb"
"github.com/meshplus/bitxhub/pkg/storage/leveldb"
"github.com/stretchr/testify/assert"
)
@ -24,22 +23,36 @@ func TestLedger_Commit(t *testing.T) {
account := types.Bytes2Address(bytesutil.LeftPadBytes([]byte{100}, 20))
ledger.SetState(account, []byte("a"), []byte("b"))
hash, err := ledger.Commit()
hash, err := ledger.Commit(1)
assert.Nil(t, err)
assert.Equal(t, uint64(1), ledger.Version())
assert.Equal(t, "0x711ba7e0fbb4011960870c9c98fdf930809a384243f580aae3b5d9d0d3f19f50", hash.Hex())
assert.Equal(t, "0xe5ace5cd035b4c3d9d73a3f4a4a64e6e306010c75c35558283847c7c6473d66c", hash.Hex())
hash, err = ledger.Commit()
hash, err = ledger.Commit(2)
assert.Nil(t, err)
assert.Equal(t, uint64(2), ledger.Version())
assert.Equal(t, "0x711ba7e0fbb4011960870c9c98fdf930809a384243f580aae3b5d9d0d3f19f50", hash.Hex())
assert.Equal(t, "0x4204720214cb812d802b2075c5fed85cd5dfe8a6065627489b6296108f0fedc2", hash.Hex())
ledger.SetState(account, []byte("a"), []byte("3"))
ledger.SetState(account, []byte("a"), []byte("2"))
hash, err = ledger.Commit()
hash, err = ledger.Commit(3)
assert.Nil(t, err)
assert.Equal(t, uint64(3), ledger.Version())
assert.Equal(t, "0x102f75930e478956e0cc1ae4f79d24723d893bdf40e65186b6bb109c6f17131e", hash.Hex())
assert.Equal(t, "0xf08cc4b2da3f277202dc50a094ff2021300375915c14894a53fe02540feb3411", hash.Hex())
ledger.SetBalance(account, 100)
hash, err = ledger.Commit(4)
assert.Nil(t, err)
assert.Equal(t, uint64(4), ledger.Version())
assert.Equal(t, "0x8ef7f408372406532c7060045d77fb67d322cea7aa49afdc3a741f4f340dc6d5", hash.Hex())
code := bytesutil.RightPadBytes([]byte{100}, 100)
ledger.SetCode(account, code)
ledger.SetState(account, []byte("b"), []byte("3"))
ledger.SetState(account, []byte("c"), []byte("2"))
hash, err = ledger.Commit(5)
assert.Nil(t, err)
assert.Equal(t, uint64(5), ledger.Version())
ledger.Close()
@ -50,73 +63,18 @@ func TestLedger_Commit(t *testing.T) {
ok, value := ldg.GetState(account, []byte("a"))
assert.True(t, ok)
assert.Equal(t, []byte("2"), value)
ok, value = ldg.GetState(account, []byte("b"))
assert.True(t, ok)
assert.Equal(t, []byte("3"), value)
ok, value = ldg.GetState(account, []byte("c"))
assert.True(t, ok)
assert.Equal(t, []byte("2"), value)
assert.Equal(t, uint64(100), ldg.GetBalance(account))
assert.Equal(t, code, ldg.GetCode(account))
ver := ldg.Version()
assert.Equal(t, uint64(3), ver)
assert.Equal(t, "0x102f75930e478956e0cc1ae4f79d24723d893bdf40e65186b6bb109c6f17131e", hash.Hex())
}
func TestLedger_Rollback(t *testing.T) {
repoRoot, err := ioutil.TempDir("", "ledger_rollback")
assert.Nil(t, err)
blockStorage, err := leveldb.New(repoRoot)
assert.Nil(t, err)
ledger, err := New(repoRoot, blockStorage, log.NewWithModule("executor"))
assert.Nil(t, err)
// create an account
account := types.Bytes2Address(bytesutil.LeftPadBytes([]byte{100}, 20))
ledger.SetState(account, []byte("a"), []byte("b"))
_, err = ledger.Commit()
assert.Nil(t, err)
ledger.SetState(account, []byte("a"), []byte("c"))
_, err = ledger.Commit()
assert.Nil(t, err)
ledger.SetState(account, []byte("a"), []byte("d"))
_, err = ledger.Commit()
assert.Nil(t, err)
block1 := &pb.Block{BlockHeader: &pb.BlockHeader{Number: 1}}
block1.BlockHash = block1.Hash()
block2 := &pb.Block{BlockHeader: &pb.BlockHeader{Number: 2}}
block2.BlockHash = block2.Hash()
block3 := &pb.Block{BlockHeader: &pb.BlockHeader{Number: 3}}
block3.BlockHash = block3.Hash()
err = ledger.PutBlock(1, block1)
assert.Nil(t, err)
err = ledger.PutBlock(2, block2)
assert.Nil(t, err)
err = ledger.PutBlock(3, block3)
assert.Nil(t, err)
ledger.UpdateChainMeta(&pb.ChainMeta{
Height: 3,
BlockHash: types.Hash{},
})
err = ledger.Rollback(1)
assert.Nil(t, err)
assert.Equal(t, uint64(1), ledger.Version())
err = ledger.Rollback(2)
assert.Equal(t, ErrorRollbackTohigherNumber, err)
ok, value := ledger.GetState(account, []byte("a"))
assert.True(t, ok)
assert.Equal(t, []byte("b"), value)
ledger.SetState(account, []byte("a"), []byte("c"))
_, err = ledger.Commit()
assert.Nil(t, err)
ledger.SetState(account, []byte("a"), []byte("d"))
_, err = ledger.Commit()
assert.Nil(t, err)
err = ledger.PutBlock(2, block2)
assert.Nil(t, err)
err = ledger.PutBlock(3, block3)
assert.Nil(t, err)
ok, value = ledger.GetState(account, []byte("a"))
assert.True(t, ok)
assert.Equal(t, []byte("d"), value)
assert.Equal(t, uint64(3), ledger.Version())
assert.Equal(t, uint64(5), ver)
}

View File

@ -1,34 +1,28 @@
package ledger
import (
"crypto/sha256"
"encoding/json"
"sort"
"github.com/syndtr/goleveldb/leveldb/errors"
"github.com/meshplus/bitxhub-kit/types"
"github.com/meshplus/bitxhub-model/pb"
)
var _ Ledger = (*ChainLedger)(nil)
const (
accountKey = "account-"
)
// GetOrCreateAccount get the account, if not exist, create a new account
func (l *ChainLedger) GetOrCreateAccount(addr types.Address) *Account {
h := addr.Hex()
value, ok := l.accounts[h]
if ok {
return value
}
obj := l.GetAccount(addr)
obj := newAccount(l, l.ldb, addr)
l.accounts[h] = obj
l.accounts[addr.Hex()] = obj
return obj
}
// GetAccount get account info using account address
// GetAccount get account info using account address, if not found, create a new account
func (l *ChainLedger) GetAccount(addr types.Address) *Account {
h := addr.Hex()
value, ok := l.accounts[h]
@ -36,10 +30,14 @@ func (l *ChainLedger) GetAccount(addr types.Address) *Account {
return value
}
account := &Account{}
_, data := l.tree.Get(compositeKey(accountKey, addr.Hex()))
account := newAccount(l.ldb, addr)
data, err := l.ldb.Get(compositeKey(accountKey, addr.Hex()))
if err != nil && err != errors.ErrNotFound {
panic(err)
}
if data != nil {
if err := account.Unmarshal(data); err != nil {
account.originAccount = &innerAccount{}
if err := account.originAccount.Unmarshal(data); err != nil {
panic(err)
}
}
@ -50,45 +48,31 @@ func (l *ChainLedger) GetAccount(addr types.Address) *Account {
// GetBalanec get account balance using account address
func (l *ChainLedger) GetBalance(addr types.Address) uint64 {
account := l.GetOrCreateAccount(addr)
return account.Balance
return account.GetBalance()
}
// SetBalance set account balance
func (l *ChainLedger) SetBalance(addr types.Address, value uint64) {
h := addr.Hex()
account := l.GetOrCreateAccount(addr)
account.Balance = value
l.accounts[h] = account
l.modifiedAccount[h] = true
account.SetBalance(value)
}
// GetState get account state value using account address and key
func (l *ChainLedger) GetState(addr types.Address, key []byte) (bool, []byte) {
account := l.GetOrCreateAccount(addr)
return account.GetState(key)
}
// SetState set account state value using account address and key
func (l *ChainLedger) SetState(addr types.Address, key []byte, v []byte) {
h := addr.Hex()
account := l.GetOrCreateAccount(addr)
account.SetState(key, v)
l.accounts[h] = account
l.modifiedAccount[h] = true
}
// SetCode set contract code
func (l *ChainLedger) SetCode(addr types.Address, code []byte) {
h := addr.Hex()
account := l.GetOrCreateAccount(addr)
account.SetCodeAndHash(code)
l.accounts[h] = account
l.modifiedAccount[h] = true
}
// GetCode get contract code
@ -105,12 +89,8 @@ func (l *ChainLedger) GetNonce(addr types.Address) uint64 {
// SetNonce set account nonce
func (l *ChainLedger) SetNonce(addr types.Address, nonce uint64) {
h := addr.Hex()
account := l.GetOrCreateAccount(addr)
account.SetNonce(nonce)
l.accounts[h] = account
l.modifiedAccount[h] = true
}
// QueryByPrefix query value using key
@ -122,48 +102,56 @@ func (l *ChainLedger) QueryByPrefix(addr types.Address, prefix string) (bool, []
func (l *ChainLedger) Clear() {
l.events = make(map[string][]*pb.Event, 10)
l.accounts = make(map[string]*Account)
l.modifiedAccount = make(map[string]bool)
}
// Commit commit the state
func (l *ChainLedger) Commit() (types.Hash, error) {
sk := make([]string, 0, len(l.modifiedAccount))
for id := range l.modifiedAccount {
sk = append(sk, id)
func (l *ChainLedger) Commit(height uint64) (types.Hash, error) {
var dirtyAccountData []byte
var journalEntries []journalEntry
sortedAddr := make([]string, 0, len(l.accounts))
accountData := make(map[string][]byte)
ldbBatch := l.ldb.NewBatch()
for addr, account := range l.accounts {
entries := account.getJournalIfModified(ldbBatch)
if len(entries) != 0 {
sortedAddr = append(sortedAddr, addr)
accountData[addr] = account.getDirtyData()
journalEntries = append(journalEntries, entries...)
}
}
sort.Strings(sk)
sort.Strings(sortedAddr)
for _, addr := range sortedAddr {
dirtyAccountData = append(dirtyAccountData, accountData[addr]...)
}
dirtyAccountData = append(dirtyAccountData, l.prevJournalHash[:]...)
journalHash := sha256.Sum256(dirtyAccountData)
for _, id := range sk {
obj := l.accounts[id]
hash, err := obj.Commit()
if err != nil {
return types.Hash{}, err
}
obj.SetStateRoot(hash)
data, err := obj.Marshal()
if err != nil {
return types.Hash{}, err
}
l.tree.Set(compositeKey(accountKey, id), data)
blockJournal := BlockJournal{
journals: journalEntries,
changedHash: journalHash,
}
hash, height, err := l.tree.SaveVersion()
data, err := json.Marshal(blockJournal)
if err != nil {
return types.Hash{}, err
return [32]byte{}, err
}
l.height = uint64(height)
ldbBatch.Put(compositeKey(journalKey, height), data)
if err := ldbBatch.Commit(); err != nil {
panic(err)
}
l.height = height
l.prevJournalHash = journalHash
l.Clear()
return types.Bytes2Hash(hash), nil
return journalHash, nil
}
// Version returns the current version
func (l *ChainLedger) Version() uint64 {
return uint64(l.tree.Version())
return l.height
}

View File

@ -0,0 +1,121 @@
package ledger
import (
"io/ioutil"
"testing"
"github.com/meshplus/bitxhub-kit/bytesutil"
"github.com/meshplus/bitxhub-kit/log"
"github.com/meshplus/bitxhub-kit/types"
"github.com/meshplus/bitxhub/pkg/storage/leveldb"
"github.com/stretchr/testify/assert"
)
func TestChainLedger_QueryByPrefix(t *testing.T) {
repoRoot, err := ioutil.TempDir("", "ledger_commit")
assert.Nil(t, err)
blockStorage, err := leveldb.New(repoRoot)
assert.Nil(t, err)
ledger, err := New(repoRoot, blockStorage, log.NewWithModule("executor"))
assert.Nil(t, err)
addr := types.Bytes2Address(bytesutil.LeftPadBytes([]byte{1}, 20))
key0 := []byte{100, 100}
key1 := []byte{100, 101}
key2 := []byte{100, 102}
ledger.SetState(addr, key0, []byte("0"))
ledger.SetState(addr, key1, []byte("1"))
ledger.SetState(addr, key2, []byte("2"))
ledger.Commit(1)
ok, vals := ledger.QueryByPrefix(addr, string([]byte{100}))
assert.True(t, ok)
assert.Equal(t, 3, len(vals))
assert.Equal(t, []byte("0"), vals[0])
assert.Equal(t, []byte("1"), vals[1])
assert.Equal(t, []byte("2"), vals[2])
}
func TestChainLedger_GetAccount(t *testing.T) {
repoRoot, err := ioutil.TempDir("", "ledger_commit")
assert.Nil(t, err)
blockStorage, err := leveldb.New(repoRoot)
assert.Nil(t, err)
ledger, err := New(repoRoot, blockStorage, log.NewWithModule("executor"))
assert.Nil(t, err)
addr := types.Bytes2Address(bytesutil.LeftPadBytes([]byte{1}, 20))
code := bytesutil.LeftPadBytes([]byte{1}, 120)
key0 := []byte{100, 100}
key1 := []byte{100, 101}
account := ledger.GetOrCreateAccount(addr)
account.SetBalance(1)
account.SetNonce(2)
account.SetCodeAndHash(code)
account.SetState(key0, key1)
account.SetState(key1, key0)
ledger.Commit(1)
account1 := ledger.GetAccount(addr)
assert.Equal(t, account.GetBalance(), ledger.GetBalance(addr))
assert.Equal(t, account.GetBalance(), account1.GetBalance())
assert.Equal(t, account.GetNonce(), account1.GetNonce())
assert.Equal(t, account.CodeHash(), account1.CodeHash())
assert.Equal(t, account.Code(), account1.Code())
ok0, val0 := account.GetState(key0)
ok1, val1 := account.GetState(key1)
assert.Equal(t, ok0, ok1)
assert.Equal(t, val0, key1)
assert.Equal(t, val1, key0)
key2 := []byte{100, 102}
val2 := []byte{111}
ledger.SetState(addr, key0, val0)
ledger.SetState(addr, key2, val2)
ledger.SetState(addr, key0, val1)
ledger.Commit(2)
ledger.SetState(addr, key0, val0)
ledger.SetState(addr, key0, val1)
ledger.Commit(3)
ok, val := ledger.GetState(addr, key0)
assert.True(t, ok)
assert.Equal(t, val1, val)
}
func TestChainLedger_GetCode(t *testing.T) {
repoRoot, err := ioutil.TempDir("", "ledger_commit")
assert.Nil(t, err)
blockStorage, err := leveldb.New(repoRoot)
assert.Nil(t, err)
ledger, err := New(repoRoot, blockStorage, log.NewWithModule("executor"))
assert.Nil(t, err)
addr := types.Bytes2Address(bytesutil.LeftPadBytes([]byte{1}, 20))
key0 := []byte{100, 100}
key1 := []byte{100, 101}
key2 := []byte{100, 102}
ledger.SetState(addr, key0, []byte("0"))
ledger.SetState(addr, key1, []byte("1"))
ledger.SetState(addr, key2, []byte("2"))
code := bytesutil.LeftPadBytes([]byte{10}, 120)
ledger.SetCode(addr, code)
ledger.Commit(1)
vals := ledger.GetCode(addr)
assert.Equal(t, code, vals)
ledger.Commit(2)
vals = ledger.GetCode(addr)
assert.Equal(t, code, vals)
}

View File

@ -59,7 +59,7 @@ type StateAccessor interface {
QueryByPrefix(address types.Address, prefix string) (bool, [][]byte)
// Commit commits the state data
Commit() (types.Hash, error)
Commit(height uint64) (types.Hash, error)
// Version
Version() uint64