From a13cd2b52d8f3b2c613a3003d461094f767fb52d Mon Sep 17 00:00:00 2001 From: pwc5232759 <33342928+pwc5232759@users.noreply.github.com> Date: Fri, 29 Mar 2019 21:28:48 +0800 Subject: [PATCH] update chain contract (#229) - mintage contract support beneficial - fix p2p - refine block to support PoV Signed-off-by: Goren G Co-authored-by: pwc <659672152@qq.com> Co-authored-by: zengchen221 <931891076@qq.com> --- chain/services/ledger_service.go | 6 +- cmd/client/commands/mintage.go | 8 +- common/genesis.go | 136 ++++++----- common/genesis_test.go | 37 ++- common/types/balance.go | 2 +- common/types/block_state.go | 44 ++-- common/types/block_state_gen.go | 349 +++++++++++++++------------ common/types/block_state_gen_test.go | 113 --------- common/types/token.go | 17 +- ledger/ledger_contract.go | 24 +- ledger/ledger_contract_store.go | 1 + ledger/ledger_sms_store.go | 3 +- p2p/node.go | 3 + p2p/stream.go | 6 +- p2p/streamManager.go | 4 +- rpc/api/mintage.go | 3 +- vm/contract/abi/abi_mintage.go | 16 +- vm/contract/abi/abi_pledge.go | 60 ----- vm/contract/abi/abi_vote_pledge.go | 67 +++++ vm/contract/contract.go | 5 +- vm/contract/mintage.go | 43 ++-- vm/contract/pledge.go | 125 ---------- vm/contract/vote_pledge.go | 147 +++++++++++ 23 files changed, 609 insertions(+), 610 deletions(-) delete mode 100644 vm/contract/abi/abi_pledge.go create mode 100644 vm/contract/abi/abi_vote_pledge.go delete mode 100644 vm/contract/pledge.go create mode 100644 vm/contract/vote_pledge.go diff --git a/chain/services/ledger_service.go b/chain/services/ledger_service.go index e232568e8..d548ab0fe 100644 --- a/chain/services/ledger_service.go +++ b/chain/services/ledger_service.go @@ -9,14 +9,14 @@ package services import ( "errors" + + "github.com/qlcchain/go-qlc/common" "github.com/qlcchain/go-qlc/common/types" + "github.com/qlcchain/go-qlc/config" "github.com/qlcchain/go-qlc/ledger" "github.com/qlcchain/go-qlc/ledger/process" "github.com/qlcchain/go-qlc/log" "go.uber.org/zap" - - "github.com/qlcchain/go-qlc/common" - "github.com/qlcchain/go-qlc/config" ) type LedgerService struct { diff --git a/cmd/client/commands/mintage.go b/cmd/client/commands/mintage.go index bc4b787d4..620df5aa6 100644 --- a/cmd/client/commands/mintage.go +++ b/cmd/client/commands/mintage.go @@ -134,7 +134,7 @@ func mintageAction(account, preHash, tokenName, tokenSymbol, totalSupply string, mintageParam := api.MintageParams{ SelfAddr: a.Address(), PrevHash: previous, TokenName: tokenName, - TotalSupply: totalSupply, TokenSymbol: tokenSymbol, Decimals: d, + TotalSupply: totalSupply, TokenSymbol: tokenSymbol, Decimals: d, Beneficial: a.Address(), } send := types.StateBlock{} @@ -161,9 +161,9 @@ func mintageAction(account, preHash, tokenName, tokenSymbol, totalSupply string, return err } - reward.Address = a.Address() - reward.Representative = a.Address() - reward.Link = sendHash + //reward.Address = a.Address() + //reward.Representative = a.Address() + //reward.Link = sendHash reward.Signature = a.Sign(reward.GetHash()) var w2 types.Work worker2, _ := types.NewWorker(w2, reward.Root()) diff --git a/common/genesis.go b/common/genesis.go index ab54cdc60..cd1e3a46c 100644 --- a/common/genesis.go +++ b/common/genesis.go @@ -18,71 +18,87 @@ import ( var ( jsonMintage = `{ - "type": "ContractSend", - "token": "45dd217cd9ff89f7b64ceda4886cc68dde9dfa47a8a422d165e2ce6f9a834fad", - "address": "qlc_3qjky1ptg9qkzm8iertdzrnx9btjbaea33snh1w4g395xqqczye4kgcfyfs1", - "balance": "0", - "previous": "0000000000000000000000000000000000000000000000000000000000000000", - "link": "0000000000000000000000000000000000000000000000000000000000000000", - "message": "0000000000000000000000000000000000000000000000000000000000000000", - "data": "RtDOi0XdIXzZ/4n3tkztpIhsxo3enfpHqKQi0WXizm+ag0+tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADVKa6ehgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1FMQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANRTEMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", - "quota": 0, - "timestamp": 1553990401, - "extra": "0000000000000000000000000000000000000000000000000000000000000000", - "representative": "qlc_1t1uynkmrs597z4ns6ymppwt65baksgdjy1dnw483ubzm97oayyo38ertg44", - "work": "0000000000000000", - "signature": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - }` + "type": "ContractSend", + "token": "45dd217cd9ff89f7b64ceda4886cc68dde9dfa47a8a422d165e2ce6f9a834fad", + "address": "qlc_3qjky1ptg9qkzm8iertdzrnx9btjbaea33snh1w4g395xqqczye4kgcfyfs1", + "balance": "0", + "vote": "0", + "network": "0", + "storage": "0", + "oracle": "0", + "previous": "0000000000000000000000000000000000000000000000000000000000000000", + "link": "0000000000000000000000000000000000000000000000000000000000000000", + "message": "0000000000000000000000000000000000000000000000000000000000000000", + "data": "6TrdxEXdIXzZ/4n3tkztpIhsxo3enfpHqKQi0WXizm+ag0+tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADVKa6ehgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhoG/UlPGRnL8VMk9O1uaINKJZcuPgLpwRg7T+Zy1R71QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADUUxDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1FMQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "povHeight": 0, + "timestamp": 1553990401, + "extra": "0000000000000000000000000000000000000000000000000000000000000000", + "representative": "qlc_1t1uynkmrs597z4ns6ymppwt65baksgdjy1dnw483ubzm97oayyo38ertg44", + "work": "000000000048f5b9", + "signature": "02c2d305fae4717cf132c8f653be5bcd8cd01a671af33ad144353e66fcbe7262224de0f929934d4871b8a1c971cf29131e4a4adceff856edc69a15bb8d759e0a" + }` jsonGenesis = `{ - "type": "ContractReward", - "token": "45dd217cd9ff89f7b64ceda4886cc68dde9dfa47a8a422d165e2ce6f9a834fad", - "address": "qlc_1t1uynkmrs597z4ns6ymppwt65baksgdjy1dnw483ubzm97oayyo38ertg44", - "balance": "60000000000000000", - "previous": "0000000000000000000000000000000000000000000000000000000000000000", - "link": "bf1cb34e79f8739367ad7de4a16c87c0e72ea483521fec0f0ddf7b5e90d03abd", - "message": "0000000000000000000000000000000000000000000000000000000000000000", - "data": "Rd0hfNn/ife2TO2kiGzGjd6d+keopCLRZeLOb5qDT60AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANUprp6GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACGgb9SU8ZGcvxUyT07W5og0olly4+AunBGDtP5nLVHvVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADUUxDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1FMQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - "quota": 0, - "timestamp": 1553990410, - "extra": "0000000000000000000000000000000000000000000000000000000000000000", - "representative": "qlc_1t1uynkmrs597z4ns6ymppwt65baksgdjy1dnw483ubzm97oayyo38ertg44", - "work": "000000000054b46a", - "signature": "3420612d28da9e5990bec8aa53d5dab89c9bcc70d020ce1dc8c74c844274e6eaf3eb7bba24bca95e566b036b17c9f01936835042dde70d0bd8f49659f83c0306" - }` + "type": "ContractReward", + "token": "45dd217cd9ff89f7b64ceda4886cc68dde9dfa47a8a422d165e2ce6f9a834fad", + "address": "qlc_1t1uynkmrs597z4ns6ymppwt65baksgdjy1dnw483ubzm97oayyo38ertg44", + "balance": "60000000000000000", + "vote": "0", + "network": "0", + "storage": "0", + "oracle": "0", + "previous": "0000000000000000000000000000000000000000000000000000000000000000", + "link": "90f28436423396887ccb08362b62061ca4b3c5a297a84e30f405e8973f652484", + "message": "0000000000000000000000000000000000000000000000000000000000000000", + "data": "Rd0hfNn/ife2TO2kiGzGjd6d+keopCLRZeLOb5qDT60AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANUprp6GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACGgb9SU8ZGcvxUyT07W5og0olly4+AunBGDtP5nLVHvVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGgb9SU8ZGcvxUyT07W5og0olly4+AunBGDtP5nLVHvVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANRTEMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADUUxDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "povHeight": 0, + "timestamp": 1553990410, + "extra": "0000000000000000000000000000000000000000000000000000000000000000", + "representative": "qlc_1t1uynkmrs597z4ns6ymppwt65baksgdjy1dnw483ubzm97oayyo38ertg44", + "work": "000000000048f5b9", + "signature": "d468c4c750eca3cb3a4005918f4dba4b72f4882a39caafc057d32f120e54e8173cd548f1779890cdff02f11ac2e09d62003327b0e027d2c09d78db6302b9fc07" + }` testJsonMintage = `{ - "type": "ContractSend", - "token": "a7e8fa30c063e96a489a47bc43909505bd86735da4a109dca28be936118a8582", - "address": "qlc_3qjky1ptg9qkzm8iertdzrnx9btjbaea33snh1w4g395xqqczye4kgcfyfs1", - "balance": "0", - "previous": "0000000000000000000000000000000000000000000000000000000000000000", - "link": "0000000000000000000000000000000000000000000000000000000000000000", - "message": "0000000000000000000000000000000000000000000000000000000000000000", - "data": "RtDOi6fo+jDAY+lqSJpHvEOQlQW9hnNdpKEJ3KKL6TYRioWCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADVKa6ehgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1FMQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANRTEMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", - "quota": 0, - "timestamp": 1553990401, - "extra": "0000000000000000000000000000000000000000000000000000000000000000", - "representative": "qlc_3hw8s1zubhxsykfsq5x7kh6eyibas9j3ga86ixd7pnqwes1cmt9mqqrngap4", - "work": "0000000000000000", - "signature": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - }` + "type": "ContractSend", + "token": "a7e8fa30c063e96a489a47bc43909505bd86735da4a109dca28be936118a8582", + "address": "qlc_3qjky1ptg9qkzm8iertdzrnx9btjbaea33snh1w4g395xqqczye4kgcfyfs1", + "balance": "0", + "vote": "0", + "network": "0", + "storage": "0", + "oracle": "0", + "previous": "0000000000000000000000000000000000000000000000000000000000000000", + "link": "0000000000000000000000000000000000000000000000000000000000000000", + "message": "0000000000000000000000000000000000000000000000000000000000000000", + "data": "6TrdxKfo+jDAY+lqSJpHvEOQlQW9hnNdpKEJ3KKL6TYRioWCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADVKa6ehgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi/hsg/tL+59Jubj6WTyM9BKMniFyDEh1ZbUvxmQKno8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADUUxDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1FMQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "povHeight": 0, + "timestamp": 1553990401, + "extra": "0000000000000000000000000000000000000000000000000000000000000000", + "representative": "qlc_3hw8s1zubhxsykfsq5x7kh6eyibas9j3ga86ixd7pnqwes1cmt9mqqrngap4", + "work": "000000000048f5b9", + "signature": "296a9af6b30d6b05216a4cb86996a54442d1e8d0e6fd7ad7636f294d31475474ec61147ab9524a8f98d9c110852591910f95cede1b125752c6217d3b6e8a4906" + }` testJsonGenesis = `{ - "type": "ContractReward", - "token": "a7e8fa30c063e96a489a47bc43909505bd86735da4a109dca28be936118a8582", - "address": "qlc_3hw8s1zubhxsykfsq5x7kh6eyibas9j3ga86ixd7pnqwes1cmt9mqqrngap4", - "balance": "60000000000000000", - "previous": "0000000000000000000000000000000000000000000000000000000000000000", - "link": "f1042ef1472b02ee61048cf4eba923b81d0a64876665888b44bb2c46534f9655", - "message": "0000000000000000000000000000000000000000000000000000000000000000", - "quota": 0, - "data": "p+j6MMBj6WpImke8Q5CVBb2Gc12koQncoovpNhGKhYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANUprp6GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACL+GyD+0v7n0m5uPpZPIz0EoyeIXIMSHVltS/GZAqejzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADUUxDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1FMQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - "timestamp": 1553990410, - "extra": "0000000000000000000000000000000000000000000000000000000000000000", - "representative": "qlc_3hw8s1zubhxsykfsq5x7kh6eyibas9j3ga86ixd7pnqwes1cmt9mqqrngap4", - "work": "000000000048f5b9", - "signature": "e89c3f7e28a51b5fed0af6cae206a82bcae436576c08db5e056a168e4337aa803d8b38a6d0438f377e57ece1d83cbf18a4cab9bc176bf640d1c62452e5c0f003" - }` + "type": "ContractReward", + "token": "a7e8fa30c063e96a489a47bc43909505bd86735da4a109dca28be936118a8582", + "address": "qlc_3hw8s1zubhxsykfsq5x7kh6eyibas9j3ga86ixd7pnqwes1cmt9mqqrngap4", + "balance": "60000000000000000", + "vote": "0", + "network": "0", + "storage": "0", + "oracle": "0", + "previous": "0000000000000000000000000000000000000000000000000000000000000000", + "link": "67513e803863279bc62d8e49a087b623895c8e2b21160a874f337ce147c859f1", + "message": "0000000000000000000000000000000000000000000000000000000000000000", + "data": "p+j6MMBj6WpImke8Q5CVBb2Gc12koQncoovpNhGKhYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANUprp6GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACL+GyD+0v7n0m5uPpZPIz0EoyeIXIMSHVltS/GZAqejzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL+GyD+0v7n0m5uPpZPIz0EoyeIXIMSHVltS/GZAqejzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANRTEMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADUUxDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "povHeight": 0, + "timestamp": 1553990410, + "extra": "0000000000000000000000000000000000000000000000000000000000000000", + "representative": "qlc_3hw8s1zubhxsykfsq5x7kh6eyibas9j3ga86ixd7pnqwes1cmt9mqqrngap4", + "work": "000000000048f5b9", + "signature": "60f7265b7379cc41d7ec533a4d2de08840e8d15d63599aa7e665c12d199d91b6ead07ab4a2b437e3e3957e60cf63bb79dcb1a82670339f7b3568b5207fa83b0d" + }` units = map[string]*big.Int{ "qlc": big.NewInt(1), diff --git a/common/genesis_test.go b/common/genesis_test.go index 314294144..02b173078 100644 --- a/common/genesis_test.go +++ b/common/genesis_test.go @@ -8,45 +8,44 @@ package common import ( + "github.com/qlcchain/go-qlc/common/types" + "github.com/qlcchain/go-qlc/common/util" "math/big" "reflect" "testing" - - "github.com/qlcchain/go-qlc/common/types" - "github.com/qlcchain/go-qlc/common/util" ) func TestGenesisBlock(t *testing.T) { - h, _ := types.NewHash("758f79b656340c329cb5b11302865c5ff0b0c99fd8a268d6b8760170e33e8cd1") - genesis := GenesisBlock() - h2 := genesis.GetHash() + h, _ := types.NewHash("8858a2b2563f6a702690beb4f29b61a88fc5a56dc50f3a26f2c97db1bf99c114") + + h2 := genesisBlock.GetHash() if h2 != h { - t.Log(util.ToString(genesis)) + t.Log(util.ToString(genesisBlock)) t.Fatal("invalid genesis block", h2.String(), h.String()) } - h3, _ := types.NewHash("bf1cb34e79f8739367ad7de4a16c87c0e72ea483521fec0f0ddf7b5e90d03abd") - mintage := GenesisMintageBlock() - h4 := mintage.GetHash() + h3, _ := types.NewHash("90f28436423396887ccb08362b62061ca4b3c5a297a84e30f405e8973f652484") + h4 := genesisMintageBlock.GetHash() if h3 != h4 { - t.Fatal(h3.String(), h4.String()) + t.Log(util.ToIndentString(genesisMintageBlock)) + t.Fatal("invalid genesis mintage block", h3.String(), h4.String()) } } func TestGenesisBlock2(t *testing.T) { - h, _ := types.NewHash("a217c8d4374377562e891d0f6b50fcdcd02c68ab7fe7d72efd14ea5c4136a214") - genesis := testGenesisBlock - h2 := genesis.GetHash() + h, _ := types.NewHash("b14e95d66841ea82f77d5293a1e477691fe66e9c1a68db92d2bb040a2b67ba71") + + h2 := testGenesisBlock.GetHash() if h2 != h { - t.Log(util.ToString(genesis)) + t.Log(util.ToString(testGenesisBlock)) t.Fatal("invalid genesis block", h2.String(), h.String()) } - h3, _ := types.NewHash("f1042ef1472b02ee61048cf4eba923b81d0a64876665888b44bb2c46534f9655") - mintage := testGenesisMintageBlock - h4 := mintage.GetHash() + h3, _ := types.NewHash("67513e803863279bc62d8e49a087b623895c8e2b21160a874f337ce147c859f1") + h4 := testGenesisMintageBlock.GetHash() if h3 != h4 { - t.Fatal(h3.String(), h4.String()) + t.Log(util.ToIndentString(testGenesisMintageBlock)) + t.Fatal("invalid genesis mintage block", h3.String(), h4.String()) } } diff --git a/common/types/balance.go b/common/types/balance.go index 6166ecffa..448baccc3 100644 --- a/common/types/balance.go +++ b/common/types/balance.go @@ -10,7 +10,7 @@ import ( ) func init() { - msgp.RegisterExtension(BalanceExtensionType, func() msgp.Extension { return new(Address) }) + msgp.RegisterExtension(BalanceExtensionType, func() msgp.Extension { return new(Balance) }) } const ( diff --git a/common/types/block_state.go b/common/types/block_state.go index 6e2570417..cf6a74ded 100644 --- a/common/types/block_state.go +++ b/common/types/block_state.go @@ -12,13 +12,17 @@ type StateBlock struct { Token Hash `msg:"token,extension" json:"token"` Address Address `msg:"address,extension" json:"address"` Balance Balance `msg:"balance,extension" json:"balance"` + Vote Balance `msg:"vote,extension" json:"vote"` + Network Balance `msg:"network,extension" json:"network"` + Storage Balance `msg:"storage,extension" json:"storage"` + Oracle Balance `msg:"oracle,extension" json:"oracle"` Previous Hash `msg:"previous,extension" json:"previous"` Link Hash `msg:"link,extension" json:"link"` Sender []byte `msg:"sender" json:"sender,omitempty"` Receiver []byte `msg:"receiver" json:"receiver,omitempty"` Message Hash `msg:"message,extension" json:"message,omitempty"` Data []byte `msg:"data" json:"data,omitempty"` - Quota int64 `msg:"quota" json:"quota"` + PoVHeight uint64 `msg:"povHeight" json:"povHeight"` Timestamp int64 `msg:"timestamp" json:"timestamp"` Extra Hash `msg:"extra,extension" json:"extra,omitempty"` Representative Address `msg:"representative,extension" json:"representative"` @@ -28,8 +32,10 @@ type StateBlock struct { func (b *StateBlock) GetHash() Hash { t := []byte{byte(b.Type)} - hash, _ := HashBytes(t, b.Token[:], b.Address[:], b.Balance.Bytes(), b.Previous[:], b.Link[:], b.Sender, - b.Receiver, b.Message[:], b.Data, util.Int2Bytes(b.Quota), util.Int2Bytes(b.Timestamp), b.Extra[:], b.Representative[:]) + hash, _ := HashBytes(t, b.Token[:], b.Address[:], b.Balance.Bytes(), b.Vote.Bytes(), b.Network.Bytes(), + b.Storage.Bytes(), b.Oracle.Bytes(), b.Previous[:], b.Link[:], b.Sender, b.Receiver, b.Message[:], b.Data, + util.Int2Bytes(b.Timestamp), util.Uint64ToBytes(b.PoVHeight), + b.Extra[:], b.Representative[:]) return hash } @@ -144,32 +150,16 @@ func (b *StateBlock) IsContractBlock() bool { } func (b *StateBlock) Clone() *StateBlock { - clone := StateBlock{ - //Type: b.Type, - //Token: b.Token, - //Address: b.Address, - //Balance: b.Balance, - //Previous: b.Previous, - //Link: b.Link, - //Sender: b.Sender, - //Receiver: b.Receiver, - //Message: b.Message, - //Data: b.Data, - //Quota: b.Quota, - //Timestamp: b.Timestamp, - //Extra: b.Extra, - //Representative: b.Representative, - //Work: b.Work, - //Signature: b.Signature, - } + clone := StateBlock{} bytes, _ := b.Serialize() _ = clone.Deserialize(bytes) return &clone } -//go:generate msgp -type BlockExtra struct { - KeyHash Hash `msg:"key,extension" json:"key"` - Abi []byte `msg:"abi" json:"abi"` - Issuer Address `msg:"issuer,extension" json:"issuer"` -} +// +////go:generate msgp +//type BlockExtra struct { +// KeyHash Hash `msg:"key,extension" json:"key"` +// Abi []byte `msg:"abi" json:"abi"` +// Issuer Address `msg:"issuer,extension" json:"issuer"` +//} diff --git a/common/types/block_state_gen.go b/common/types/block_state_gen.go index 1f07bd9ca..b30f87550 100644 --- a/common/types/block_state_gen.go +++ b/common/types/block_state_gen.go @@ -7,248 +7,147 @@ import ( ) // DecodeMsg implements msgp.Decodable -func (z *BlockExtra) DecodeMsg(dc *msgp.Reader) (err error) { +func (z *StateBlock) DecodeMsg(dc *msgp.Reader) (err error) { var field []byte _ = field var zb0001 uint32 zb0001, err = dc.ReadMapHeader() if err != nil { + err = msgp.WrapError(err) return } for zb0001 > 0 { zb0001-- field, err = dc.ReadMapKeyPtr() if err != nil { + err = msgp.WrapError(err) return } switch msgp.UnsafeString(field) { - case "key": - err = dc.ReadExtension(&z.KeyHash) - if err != nil { - return - } - case "abi": - z.Abi, err = dc.ReadBytes(z.Abi) - if err != nil { - return - } - case "issuer": - err = dc.ReadExtension(&z.Issuer) - if err != nil { - return - } - default: - err = dc.Skip() - if err != nil { - return - } - } - } - return -} - -// EncodeMsg implements msgp.Encodable -func (z *BlockExtra) EncodeMsg(en *msgp.Writer) (err error) { - // map header, size 3 - // write "key" - err = en.Append(0x83, 0xa3, 0x6b, 0x65, 0x79) - if err != nil { - return - } - err = en.WriteExtension(&z.KeyHash) - if err != nil { - return - } - // write "abi" - err = en.Append(0xa3, 0x61, 0x62, 0x69) - if err != nil { - return - } - err = en.WriteBytes(z.Abi) - if err != nil { - return - } - // write "issuer" - err = en.Append(0xa6, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72) - if err != nil { - return - } - err = en.WriteExtension(&z.Issuer) - if err != nil { - return - } - return -} - -// MarshalMsg implements msgp.Marshaler -func (z *BlockExtra) MarshalMsg(b []byte) (o []byte, err error) { - o = msgp.Require(b, z.Msgsize()) - // map header, size 3 - // string "key" - o = append(o, 0x83, 0xa3, 0x6b, 0x65, 0x79) - o, err = msgp.AppendExtension(o, &z.KeyHash) - if err != nil { - return - } - // string "abi" - o = append(o, 0xa3, 0x61, 0x62, 0x69) - o = msgp.AppendBytes(o, z.Abi) - // string "issuer" - o = append(o, 0xa6, 0x69, 0x73, 0x73, 0x75, 0x65, 0x72) - o, err = msgp.AppendExtension(o, &z.Issuer) - if err != nil { - return - } - return -} - -// UnmarshalMsg implements msgp.Unmarshaler -func (z *BlockExtra) UnmarshalMsg(bts []byte) (o []byte, err error) { - var field []byte - _ = field - var zb0001 uint32 - zb0001, bts, err = msgp.ReadMapHeaderBytes(bts) - if err != nil { - return - } - for zb0001 > 0 { - zb0001-- - field, bts, err = msgp.ReadMapKeyZC(bts) - if err != nil { - return - } - switch msgp.UnsafeString(field) { - case "key": - bts, err = msgp.ReadExtensionBytes(bts, &z.KeyHash) + case "type": + err = z.Type.DecodeMsg(dc) if err != nil { + err = msgp.WrapError(err, "Type") return } - case "abi": - z.Abi, bts, err = msgp.ReadBytesBytes(bts, z.Abi) + case "token": + err = dc.ReadExtension(&z.Token) if err != nil { + err = msgp.WrapError(err, "Token") return } - case "issuer": - bts, err = msgp.ReadExtensionBytes(bts, &z.Issuer) + case "address": + err = dc.ReadExtension(&z.Address) if err != nil { + err = msgp.WrapError(err, "Address") return } - default: - bts, err = msgp.Skip(bts) + case "balance": + err = dc.ReadExtension(&z.Balance) if err != nil { + err = msgp.WrapError(err, "Balance") return } - } - } - o = bts - return -} - -// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message -func (z *BlockExtra) Msgsize() (s int) { - s = 1 + 4 + msgp.ExtensionPrefixSize + z.KeyHash.Len() + 4 + msgp.BytesPrefixSize + len(z.Abi) + 7 + msgp.ExtensionPrefixSize + z.Issuer.Len() - return -} - -// DecodeMsg implements msgp.Decodable -func (z *StateBlock) DecodeMsg(dc *msgp.Reader) (err error) { - var field []byte - _ = field - var zb0001 uint32 - zb0001, err = dc.ReadMapHeader() - if err != nil { - return - } - for zb0001 > 0 { - zb0001-- - field, err = dc.ReadMapKeyPtr() - if err != nil { - return - } - switch msgp.UnsafeString(field) { - case "type": - err = z.Type.DecodeMsg(dc) + case "vote": + err = dc.ReadExtension(&z.Vote) if err != nil { + err = msgp.WrapError(err, "Vote") return } - case "token": - err = dc.ReadExtension(&z.Token) + case "network": + err = dc.ReadExtension(&z.Network) if err != nil { + err = msgp.WrapError(err, "Network") return } - case "address": - err = dc.ReadExtension(&z.Address) + case "storage": + err = dc.ReadExtension(&z.Storage) if err != nil { + err = msgp.WrapError(err, "Storage") return } - case "balance": - err = dc.ReadExtension(&z.Balance) + case "oracle": + err = dc.ReadExtension(&z.Oracle) if err != nil { + err = msgp.WrapError(err, "Oracle") return } case "previous": err = dc.ReadExtension(&z.Previous) if err != nil { + err = msgp.WrapError(err, "Previous") return } case "link": err = dc.ReadExtension(&z.Link) if err != nil { + err = msgp.WrapError(err, "Link") return } case "sender": z.Sender, err = dc.ReadBytes(z.Sender) if err != nil { + err = msgp.WrapError(err, "Sender") return } case "receiver": z.Receiver, err = dc.ReadBytes(z.Receiver) if err != nil { + err = msgp.WrapError(err, "Receiver") return } case "message": err = dc.ReadExtension(&z.Message) if err != nil { + err = msgp.WrapError(err, "Message") return } case "data": z.Data, err = dc.ReadBytes(z.Data) if err != nil { + err = msgp.WrapError(err, "Data") return } - case "quota": - z.Quota, err = dc.ReadInt64() + case "povHeight": + z.PoVHeight, err = dc.ReadUint64() if err != nil { + err = msgp.WrapError(err, "PoVHeight") return } case "timestamp": z.Timestamp, err = dc.ReadInt64() if err != nil { + err = msgp.WrapError(err, "Timestamp") return } case "extra": err = dc.ReadExtension(&z.Extra) if err != nil { + err = msgp.WrapError(err, "Extra") return } case "representative": err = dc.ReadExtension(&z.Representative) if err != nil { + err = msgp.WrapError(err, "Representative") return } case "work": err = dc.ReadExtension(&z.Work) if err != nil { + err = msgp.WrapError(err, "Work") return } case "signature": err = dc.ReadExtension(&z.Signature) if err != nil { + err = msgp.WrapError(err, "Signature") return } default: err = dc.Skip() if err != nil { + err = msgp.WrapError(err) return } } @@ -258,14 +157,15 @@ func (z *StateBlock) DecodeMsg(dc *msgp.Reader) (err error) { // EncodeMsg implements msgp.Encodable func (z *StateBlock) EncodeMsg(en *msgp.Writer) (err error) { - // map header, size 16 + // map header, size 20 // write "type" - err = en.Append(0xde, 0x0, 0x10, 0xa4, 0x74, 0x79, 0x70, 0x65) + err = en.Append(0xde, 0x0, 0x14, 0xa4, 0x74, 0x79, 0x70, 0x65) if err != nil { return } err = z.Type.EncodeMsg(en) if err != nil { + err = msgp.WrapError(err, "Type") return } // write "token" @@ -275,6 +175,7 @@ func (z *StateBlock) EncodeMsg(en *msgp.Writer) (err error) { } err = en.WriteExtension(&z.Token) if err != nil { + err = msgp.WrapError(err, "Token") return } // write "address" @@ -284,6 +185,7 @@ func (z *StateBlock) EncodeMsg(en *msgp.Writer) (err error) { } err = en.WriteExtension(&z.Address) if err != nil { + err = msgp.WrapError(err, "Address") return } // write "balance" @@ -293,6 +195,47 @@ func (z *StateBlock) EncodeMsg(en *msgp.Writer) (err error) { } err = en.WriteExtension(&z.Balance) if err != nil { + err = msgp.WrapError(err, "Balance") + return + } + // write "vote" + err = en.Append(0xa4, 0x76, 0x6f, 0x74, 0x65) + if err != nil { + return + } + err = en.WriteExtension(&z.Vote) + if err != nil { + err = msgp.WrapError(err, "Vote") + return + } + // write "network" + err = en.Append(0xa7, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b) + if err != nil { + return + } + err = en.WriteExtension(&z.Network) + if err != nil { + err = msgp.WrapError(err, "Network") + return + } + // write "storage" + err = en.Append(0xa7, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65) + if err != nil { + return + } + err = en.WriteExtension(&z.Storage) + if err != nil { + err = msgp.WrapError(err, "Storage") + return + } + // write "oracle" + err = en.Append(0xa6, 0x6f, 0x72, 0x61, 0x63, 0x6c, 0x65) + if err != nil { + return + } + err = en.WriteExtension(&z.Oracle) + if err != nil { + err = msgp.WrapError(err, "Oracle") return } // write "previous" @@ -302,6 +245,7 @@ func (z *StateBlock) EncodeMsg(en *msgp.Writer) (err error) { } err = en.WriteExtension(&z.Previous) if err != nil { + err = msgp.WrapError(err, "Previous") return } // write "link" @@ -311,6 +255,7 @@ func (z *StateBlock) EncodeMsg(en *msgp.Writer) (err error) { } err = en.WriteExtension(&z.Link) if err != nil { + err = msgp.WrapError(err, "Link") return } // write "sender" @@ -320,6 +265,7 @@ func (z *StateBlock) EncodeMsg(en *msgp.Writer) (err error) { } err = en.WriteBytes(z.Sender) if err != nil { + err = msgp.WrapError(err, "Sender") return } // write "receiver" @@ -329,6 +275,7 @@ func (z *StateBlock) EncodeMsg(en *msgp.Writer) (err error) { } err = en.WriteBytes(z.Receiver) if err != nil { + err = msgp.WrapError(err, "Receiver") return } // write "message" @@ -338,6 +285,7 @@ func (z *StateBlock) EncodeMsg(en *msgp.Writer) (err error) { } err = en.WriteExtension(&z.Message) if err != nil { + err = msgp.WrapError(err, "Message") return } // write "data" @@ -347,15 +295,17 @@ func (z *StateBlock) EncodeMsg(en *msgp.Writer) (err error) { } err = en.WriteBytes(z.Data) if err != nil { + err = msgp.WrapError(err, "Data") return } - // write "quota" - err = en.Append(0xa5, 0x71, 0x75, 0x6f, 0x74, 0x61) + // write "povHeight" + err = en.Append(0xa9, 0x70, 0x6f, 0x76, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74) if err != nil { return } - err = en.WriteInt64(z.Quota) + err = en.WriteUint64(z.PoVHeight) if err != nil { + err = msgp.WrapError(err, "PoVHeight") return } // write "timestamp" @@ -365,6 +315,7 @@ func (z *StateBlock) EncodeMsg(en *msgp.Writer) (err error) { } err = en.WriteInt64(z.Timestamp) if err != nil { + err = msgp.WrapError(err, "Timestamp") return } // write "extra" @@ -374,6 +325,7 @@ func (z *StateBlock) EncodeMsg(en *msgp.Writer) (err error) { } err = en.WriteExtension(&z.Extra) if err != nil { + err = msgp.WrapError(err, "Extra") return } // write "representative" @@ -383,6 +335,7 @@ func (z *StateBlock) EncodeMsg(en *msgp.Writer) (err error) { } err = en.WriteExtension(&z.Representative) if err != nil { + err = msgp.WrapError(err, "Representative") return } // write "work" @@ -392,6 +345,7 @@ func (z *StateBlock) EncodeMsg(en *msgp.Writer) (err error) { } err = en.WriteExtension(&z.Work) if err != nil { + err = msgp.WrapError(err, "Work") return } // write "signature" @@ -401,6 +355,7 @@ func (z *StateBlock) EncodeMsg(en *msgp.Writer) (err error) { } err = en.WriteExtension(&z.Signature) if err != nil { + err = msgp.WrapError(err, "Signature") return } return @@ -409,41 +364,75 @@ func (z *StateBlock) EncodeMsg(en *msgp.Writer) (err error) { // MarshalMsg implements msgp.Marshaler func (z *StateBlock) MarshalMsg(b []byte) (o []byte, err error) { o = msgp.Require(b, z.Msgsize()) - // map header, size 16 + // map header, size 20 // string "type" - o = append(o, 0xde, 0x0, 0x10, 0xa4, 0x74, 0x79, 0x70, 0x65) + o = append(o, 0xde, 0x0, 0x14, 0xa4, 0x74, 0x79, 0x70, 0x65) o, err = z.Type.MarshalMsg(o) if err != nil { + err = msgp.WrapError(err, "Type") return } // string "token" o = append(o, 0xa5, 0x74, 0x6f, 0x6b, 0x65, 0x6e) o, err = msgp.AppendExtension(o, &z.Token) if err != nil { + err = msgp.WrapError(err, "Token") return } // string "address" o = append(o, 0xa7, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73) o, err = msgp.AppendExtension(o, &z.Address) if err != nil { + err = msgp.WrapError(err, "Address") return } // string "balance" o = append(o, 0xa7, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65) o, err = msgp.AppendExtension(o, &z.Balance) if err != nil { + err = msgp.WrapError(err, "Balance") + return + } + // string "vote" + o = append(o, 0xa4, 0x76, 0x6f, 0x74, 0x65) + o, err = msgp.AppendExtension(o, &z.Vote) + if err != nil { + err = msgp.WrapError(err, "Vote") + return + } + // string "network" + o = append(o, 0xa7, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b) + o, err = msgp.AppendExtension(o, &z.Network) + if err != nil { + err = msgp.WrapError(err, "Network") + return + } + // string "storage" + o = append(o, 0xa7, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65) + o, err = msgp.AppendExtension(o, &z.Storage) + if err != nil { + err = msgp.WrapError(err, "Storage") + return + } + // string "oracle" + o = append(o, 0xa6, 0x6f, 0x72, 0x61, 0x63, 0x6c, 0x65) + o, err = msgp.AppendExtension(o, &z.Oracle) + if err != nil { + err = msgp.WrapError(err, "Oracle") return } // string "previous" o = append(o, 0xa8, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73) o, err = msgp.AppendExtension(o, &z.Previous) if err != nil { + err = msgp.WrapError(err, "Previous") return } // string "link" o = append(o, 0xa4, 0x6c, 0x69, 0x6e, 0x6b) o, err = msgp.AppendExtension(o, &z.Link) if err != nil { + err = msgp.WrapError(err, "Link") return } // string "sender" @@ -456,14 +445,15 @@ func (z *StateBlock) MarshalMsg(b []byte) (o []byte, err error) { o = append(o, 0xa7, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65) o, err = msgp.AppendExtension(o, &z.Message) if err != nil { + err = msgp.WrapError(err, "Message") return } // string "data" o = append(o, 0xa4, 0x64, 0x61, 0x74, 0x61) o = msgp.AppendBytes(o, z.Data) - // string "quota" - o = append(o, 0xa5, 0x71, 0x75, 0x6f, 0x74, 0x61) - o = msgp.AppendInt64(o, z.Quota) + // string "povHeight" + o = append(o, 0xa9, 0x70, 0x6f, 0x76, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74) + o = msgp.AppendUint64(o, z.PoVHeight) // string "timestamp" o = append(o, 0xa9, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70) o = msgp.AppendInt64(o, z.Timestamp) @@ -471,24 +461,28 @@ func (z *StateBlock) MarshalMsg(b []byte) (o []byte, err error) { o = append(o, 0xa5, 0x65, 0x78, 0x74, 0x72, 0x61) o, err = msgp.AppendExtension(o, &z.Extra) if err != nil { + err = msgp.WrapError(err, "Extra") return } // string "representative" o = append(o, 0xae, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65) o, err = msgp.AppendExtension(o, &z.Representative) if err != nil { + err = msgp.WrapError(err, "Representative") return } // string "work" o = append(o, 0xa4, 0x77, 0x6f, 0x72, 0x6b) o, err = msgp.AppendExtension(o, &z.Work) if err != nil { + err = msgp.WrapError(err, "Work") return } // string "signature" o = append(o, 0xa9, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65) o, err = msgp.AppendExtension(o, &z.Signature) if err != nil { + err = msgp.WrapError(err, "Signature") return } return @@ -501,98 +495,141 @@ func (z *StateBlock) UnmarshalMsg(bts []byte) (o []byte, err error) { var zb0001 uint32 zb0001, bts, err = msgp.ReadMapHeaderBytes(bts) if err != nil { + err = msgp.WrapError(err) return } for zb0001 > 0 { zb0001-- field, bts, err = msgp.ReadMapKeyZC(bts) if err != nil { + err = msgp.WrapError(err) return } switch msgp.UnsafeString(field) { case "type": bts, err = z.Type.UnmarshalMsg(bts) if err != nil { + err = msgp.WrapError(err, "Type") return } case "token": bts, err = msgp.ReadExtensionBytes(bts, &z.Token) if err != nil { + err = msgp.WrapError(err, "Token") return } case "address": bts, err = msgp.ReadExtensionBytes(bts, &z.Address) if err != nil { + err = msgp.WrapError(err, "Address") return } case "balance": bts, err = msgp.ReadExtensionBytes(bts, &z.Balance) if err != nil { + err = msgp.WrapError(err, "Balance") + return + } + case "vote": + bts, err = msgp.ReadExtensionBytes(bts, &z.Vote) + if err != nil { + err = msgp.WrapError(err, "Vote") + return + } + case "network": + bts, err = msgp.ReadExtensionBytes(bts, &z.Network) + if err != nil { + err = msgp.WrapError(err, "Network") + return + } + case "storage": + bts, err = msgp.ReadExtensionBytes(bts, &z.Storage) + if err != nil { + err = msgp.WrapError(err, "Storage") + return + } + case "oracle": + bts, err = msgp.ReadExtensionBytes(bts, &z.Oracle) + if err != nil { + err = msgp.WrapError(err, "Oracle") return } case "previous": bts, err = msgp.ReadExtensionBytes(bts, &z.Previous) if err != nil { + err = msgp.WrapError(err, "Previous") return } case "link": bts, err = msgp.ReadExtensionBytes(bts, &z.Link) if err != nil { + err = msgp.WrapError(err, "Link") return } case "sender": z.Sender, bts, err = msgp.ReadBytesBytes(bts, z.Sender) if err != nil { + err = msgp.WrapError(err, "Sender") return } case "receiver": z.Receiver, bts, err = msgp.ReadBytesBytes(bts, z.Receiver) if err != nil { + err = msgp.WrapError(err, "Receiver") return } case "message": bts, err = msgp.ReadExtensionBytes(bts, &z.Message) if err != nil { + err = msgp.WrapError(err, "Message") return } case "data": z.Data, bts, err = msgp.ReadBytesBytes(bts, z.Data) if err != nil { + err = msgp.WrapError(err, "Data") return } - case "quota": - z.Quota, bts, err = msgp.ReadInt64Bytes(bts) + case "povHeight": + z.PoVHeight, bts, err = msgp.ReadUint64Bytes(bts) if err != nil { + err = msgp.WrapError(err, "PoVHeight") return } case "timestamp": z.Timestamp, bts, err = msgp.ReadInt64Bytes(bts) if err != nil { + err = msgp.WrapError(err, "Timestamp") return } case "extra": bts, err = msgp.ReadExtensionBytes(bts, &z.Extra) if err != nil { + err = msgp.WrapError(err, "Extra") return } case "representative": bts, err = msgp.ReadExtensionBytes(bts, &z.Representative) if err != nil { + err = msgp.WrapError(err, "Representative") return } case "work": bts, err = msgp.ReadExtensionBytes(bts, &z.Work) if err != nil { + err = msgp.WrapError(err, "Work") return } case "signature": bts, err = msgp.ReadExtensionBytes(bts, &z.Signature) if err != nil { + err = msgp.WrapError(err, "Signature") return } default: bts, err = msgp.Skip(bts) if err != nil { + err = msgp.WrapError(err) return } } @@ -603,6 +640,6 @@ func (z *StateBlock) UnmarshalMsg(bts []byte) (o []byte, err error) { // Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message func (z *StateBlock) Msgsize() (s int) { - s = 3 + 5 + z.Type.Msgsize() + 6 + msgp.ExtensionPrefixSize + z.Token.Len() + 8 + msgp.ExtensionPrefixSize + z.Address.Len() + 8 + msgp.ExtensionPrefixSize + z.Balance.Len() + 9 + msgp.ExtensionPrefixSize + z.Previous.Len() + 5 + msgp.ExtensionPrefixSize + z.Link.Len() + 7 + msgp.BytesPrefixSize + len(z.Sender) + 9 + msgp.BytesPrefixSize + len(z.Receiver) + 8 + msgp.ExtensionPrefixSize + z.Message.Len() + 5 + msgp.BytesPrefixSize + len(z.Data) + 6 + msgp.Int64Size + 10 + msgp.Int64Size + 6 + msgp.ExtensionPrefixSize + z.Extra.Len() + 15 + msgp.ExtensionPrefixSize + z.Representative.Len() + 5 + msgp.ExtensionPrefixSize + z.Work.Len() + 10 + msgp.ExtensionPrefixSize + z.Signature.Len() + s = 3 + 5 + z.Type.Msgsize() + 6 + msgp.ExtensionPrefixSize + z.Token.Len() + 8 + msgp.ExtensionPrefixSize + z.Address.Len() + 8 + msgp.ExtensionPrefixSize + z.Balance.Len() + 5 + msgp.ExtensionPrefixSize + z.Vote.Len() + 8 + msgp.ExtensionPrefixSize + z.Network.Len() + 8 + msgp.ExtensionPrefixSize + z.Storage.Len() + 7 + msgp.ExtensionPrefixSize + z.Oracle.Len() + 9 + msgp.ExtensionPrefixSize + z.Previous.Len() + 5 + msgp.ExtensionPrefixSize + z.Link.Len() + 7 + msgp.BytesPrefixSize + len(z.Sender) + 9 + msgp.BytesPrefixSize + len(z.Receiver) + 8 + msgp.ExtensionPrefixSize + z.Message.Len() + 5 + msgp.BytesPrefixSize + len(z.Data) + 10 + msgp.Uint64Size + 10 + msgp.Int64Size + 6 + msgp.ExtensionPrefixSize + z.Extra.Len() + 15 + msgp.ExtensionPrefixSize + z.Representative.Len() + 5 + msgp.ExtensionPrefixSize + z.Work.Len() + 10 + msgp.ExtensionPrefixSize + z.Signature.Len() return } diff --git a/common/types/block_state_gen_test.go b/common/types/block_state_gen_test.go index d697777bc..bb8bce6a2 100644 --- a/common/types/block_state_gen_test.go +++ b/common/types/block_state_gen_test.go @@ -9,119 +9,6 @@ import ( "github.com/tinylib/msgp/msgp" ) -func TestMarshalUnmarshalBlockExtra(t *testing.T) { - v := BlockExtra{} - bts, err := v.MarshalMsg(nil) - if err != nil { - t.Fatal(err) - } - left, err := v.UnmarshalMsg(bts) - if err != nil { - t.Fatal(err) - } - if len(left) > 0 { - t.Errorf("%d bytes left over after UnmarshalMsg(): %q", len(left), left) - } - - left, err = msgp.Skip(bts) - if err != nil { - t.Fatal(err) - } - if len(left) > 0 { - t.Errorf("%d bytes left over after Skip(): %q", len(left), left) - } -} - -func BenchmarkMarshalMsgBlockExtra(b *testing.B) { - v := BlockExtra{} - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - v.MarshalMsg(nil) - } -} - -func BenchmarkAppendMsgBlockExtra(b *testing.B) { - v := BlockExtra{} - bts := make([]byte, 0, v.Msgsize()) - bts, _ = v.MarshalMsg(bts[0:0]) - b.SetBytes(int64(len(bts))) - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - bts, _ = v.MarshalMsg(bts[0:0]) - } -} - -func BenchmarkUnmarshalBlockExtra(b *testing.B) { - v := BlockExtra{} - bts, _ := v.MarshalMsg(nil) - b.ReportAllocs() - b.SetBytes(int64(len(bts))) - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, err := v.UnmarshalMsg(bts) - if err != nil { - b.Fatal(err) - } - } -} - -func TestEncodeDecodeBlockExtra(t *testing.T) { - v := BlockExtra{} - var buf bytes.Buffer - msgp.Encode(&buf, &v) - - m := v.Msgsize() - if buf.Len() > m { - t.Logf("WARNING: Msgsize() for %v is inaccurate", v) - } - - vn := BlockExtra{} - err := msgp.Decode(&buf, &vn) - if err != nil { - t.Error(err) - } - - buf.Reset() - msgp.Encode(&buf, &v) - err = msgp.NewReader(&buf).Skip() - if err != nil { - t.Error(err) - } -} - -func BenchmarkEncodeBlockExtra(b *testing.B) { - v := BlockExtra{} - var buf bytes.Buffer - msgp.Encode(&buf, &v) - b.SetBytes(int64(buf.Len())) - en := msgp.NewWriter(msgp.Nowhere) - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - v.EncodeMsg(en) - } - en.Flush() -} - -func BenchmarkDecodeBlockExtra(b *testing.B) { - v := BlockExtra{} - var buf bytes.Buffer - msgp.Encode(&buf, &v) - b.SetBytes(int64(buf.Len())) - rd := msgp.NewEndlessReader(buf.Bytes(), b) - dc := msgp.NewReader(rd) - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - err := v.DecodeMsg(dc) - if err != nil { - b.Fatal(err) - } - } -} - func TestMarshalUnmarshalStateBlock(t *testing.T) { v := StateBlock{} bts, err := v.MarshalMsg(nil) diff --git a/common/types/token.go b/common/types/token.go index ea11b6e99..6a92fe99e 100644 --- a/common/types/token.go +++ b/common/types/token.go @@ -10,12 +10,13 @@ package types import "math/big" type TokenInfo struct { - TokenId Hash `json:"tokenId"` - TokenName string `json:"tokenName"` - TokenSymbol string `json:"tokenSymbol"` - TotalSupply *big.Int `json:"totalSupply"` - Decimals uint8 `json:"decimals"` - Owner Address `json:"owner"` - PledgeAmount *big.Int `json:"pledgeAmount"` - WithdrawTime int64 `json:"withdrawTime"` + TokenId Hash `json:"tokenId"` + TokenName string `json:"tokenName"` + TokenSymbol string `json:"tokenSymbol"` + TotalSupply *big.Int `json:"totalSupply"` + Decimals uint8 `json:"decimals"` + Owner Address `json:"owner"` + PledgeAmount *big.Int `json:"pledgeAmount"` + WithdrawTime int64 `json:"withdrawTime"` + PledgeAddress Address `json:"pledgeAddress"` } diff --git a/ledger/ledger_contract.go b/ledger/ledger_contract.go index 436c2a467..ff572dc85 100644 --- a/ledger/ledger_contract.go +++ b/ledger/ledger_contract.go @@ -1,6 +1,7 @@ package ledger import ( + "bytes" "github.com/dgraph-io/badger" "github.com/qlcchain/go-qlc/ledger/db" ) @@ -41,8 +42,29 @@ func (l *Ledger) SetStorage(prefix, key []byte, value []byte, txns ...db.StoreTx }) if err == nil { return ErrStorageExists - } else if err != nil && err != badger.ErrKeyNotFound { + } else if err != badger.ErrKeyNotFound { return err } return txn.Set(storageKey, value) } + +func (l *Ledger) Iterator(prefix []byte, fn func(key []byte, value []byte) error, txns ...db.StoreTxn) error { + txn, flag := l.getTxn(true, txns...) + defer l.releaseTxn(txn, flag) + + err := txn.Iterator(idPrefixStorage, func(key []byte, val []byte, b byte) error { + if bytes.HasPrefix(key, prefix) { + err := fn(key, val) + if err != nil { + l.logger.Error(err) + } + } + return nil + }) + + if err != nil { + return err + } + + return nil +} diff --git a/ledger/ledger_contract_store.go b/ledger/ledger_contract_store.go index f7124a4dd..e963bc194 100644 --- a/ledger/ledger_contract_store.go +++ b/ledger/ledger_contract_store.go @@ -8,4 +8,5 @@ type contractStore interface { //GetStorage GetStorage(prefix, key []byte, txns ...db.StoreTxn) ([]byte, error) SetStorage(prefix, key []byte, value []byte, txns ...db.StoreTxn) error + Iterator(prefix []byte, fn func(key []byte, value []byte) error, txns ...db.StoreTxn) error } diff --git a/ledger/ledger_sms_store.go b/ledger/ledger_sms_store.go index f2d25b618..7864950bc 100644 --- a/ledger/ledger_sms_store.go +++ b/ledger/ledger_sms_store.go @@ -9,7 +9,8 @@ type smsStore interface { // sender or receiver GetSenderBlocks(sender []byte, txns ...db.StoreTxn) ([]types.Hash, error) GetReceiverBlocks(receiver []byte, txns ...db.StoreTxn) ([]types.Hash, error) - GetMessageBlock(hash types.Hash, txns ...db.StoreTxn) (*types.StateBlock, error) + //GetMessageBlock(hash types.Hash, txns ...db.StoreTxn) (*types.StateBlock, error) AddMessageInfo(mHash types.Hash, message []byte, txns ...db.StoreTxn) error GetMessageInfo(mHash types.Hash, txns ...db.StoreTxn) ([]byte, error) + GetMessageBlocks(mHash types.Hash, txns ...db.StoreTxn) ([]types.Hash, error) } diff --git a/p2p/node.go b/p2p/node.go index e08611a90..9c1969a8e 100644 --- a/p2p/node.go +++ b/p2p/node.go @@ -26,6 +26,9 @@ var ( ErrPeerIsNotConnected = errors.New("peer is not connected") ) +// p2p protocol version +var p2pVersion = 3 + //var logger = log.NewLogger("p2p") type QlcNode struct { diff --git a/p2p/stream.go b/p2p/stream.go index 19b1a3613..29dd399af 100644 --- a/p2p/stream.go +++ b/p2p/stream.go @@ -233,7 +233,7 @@ func (s *Stream) SendMessageToPeers(messageType string, data []byte) error { // SendMessage send msg to peer func (s *Stream) SendMessageToPeer(messageType string, data []byte) error { - version := s.node.cfg.Version + version := p2pVersion message := NewQlcMessage(data, byte(version), messageType) s.messageChan <- message return nil @@ -264,6 +264,10 @@ func (s *Stream) Write(data []byte) error { } func (s *Stream) handleMessage(message *QlcMessage) { + if message.Version() < byte(p2pVersion) { + s.node.logger.Debugf("message Version [%d] is less then p2pVersion [%d]", message.Version(), p2pVersion) + return + } m := NewBaseMessage(message.MessageType(), s.pid.Pretty(), message.MessageData(), message.content) s.node.netService.PutMessage(m) } diff --git a/p2p/streamManager.go b/p2p/streamManager.go index b6cc70c1d..00e2d0456 100644 --- a/p2p/streamManager.go +++ b/p2p/streamManager.go @@ -133,7 +133,7 @@ func (sm *StreamManager) BroadcastMessage(messageName string, v interface{}) { sm.node.logger.Error(err) return } - version := sm.node.cfg.Version + version := p2pVersion message := NewQlcMessage(messageContent, byte(version), messageName) hash, err := types.HashBytes(message) if err != nil { @@ -194,7 +194,7 @@ func (sm *StreamManager) SendMessageToPeers(messageName string, v interface{}, p sm.node.logger.Error(err) return } - version := sm.node.cfg.Version + version := p2pVersion message := NewQlcMessage(messageContent, byte(version), messageName) hash, err := types.HashBytes(message) if err != nil { diff --git a/rpc/api/mintage.go b/rpc/api/mintage.go index c092c8975..241181c7a 100644 --- a/rpc/api/mintage.go +++ b/rpc/api/mintage.go @@ -39,6 +39,7 @@ type MintageParams struct { TokenSymbol string `json:"tokenSymbol"` TotalSupply string `json:"totalSupply"` Decimals uint8 `json:"decimals"` + Beneficial types.Address `json:"beneficial"` } func (m *MintageApi) GetMintageData(param *MintageParams) ([]byte, error) { @@ -56,7 +57,7 @@ func (m *MintageApi) GetMintageBlock(param *MintageParams) (*types.StateBlock, e if err != nil { return nil, err } - data, err := cabi.ABIMintage.PackMethod(cabi.MethodNameMintage, tokenId, param.TokenName, param.TokenSymbol, totalSupply, param.Decimals) + data, err := cabi.ABIMintage.PackMethod(cabi.MethodNameMintage, tokenId, param.TokenName, param.TokenSymbol, totalSupply, param.Decimals, param.Beneficial) if err != nil { return nil, err } diff --git a/vm/contract/abi/abi_mintage.go b/vm/contract/abi/abi_mintage.go index b36aa3b23..a2c28a13b 100644 --- a/vm/contract/abi/abi_mintage.go +++ b/vm/contract/abi/abi_mintage.go @@ -20,9 +20,9 @@ import ( const ( jsonMintage = ` [ - {"type":"function","name":"Mintage","inputs":[{"name":"tokenId","type":"tokenId"},{"name":"tokenName","type":"string"},{"name":"tokenSymbol","type":"string"},{"name":"totalSupply","type":"uint256"},{"name":"decimals","type":"uint8"}]}, + {"type":"function","name":"Mintage","inputs":[{"name":"tokenId","type":"tokenId"},{"name":"tokenName","type":"string"},{"name":"tokenSymbol","type":"string"},{"name":"totalSupply","type":"uint256"},{"name":"decimals","type":"uint8"},{"name":"beneficial","type":"address"}]}, {"type":"function","name":"Withdraw","inputs":[{"name":"tokenId","type":"tokenId"}]}, - {"type":"variable","name":"token","inputs":[{"name":"tokenId","type":"tokenId"},{"name":"tokenName","type":"string"},{"name":"tokenSymbol","type":"string"},{"name":"totalSupply","type":"uint256"},{"name":"decimals","type":"uint8"},{"name":"owner","type":"address"},{"name":"pledgeAmount","type":"uint256"},{"name":"withdrawTime","type":"int64"}]} + {"type":"variable","name":"token","inputs":[{"name":"tokenId","type":"tokenId"},{"name":"tokenName","type":"string"},{"name":"tokenSymbol","type":"string"},{"name":"totalSupply","type":"uint256"},{"name":"decimals","type":"uint8"},{"name":"owner","type":"address"},{"name":"pledgeAmount","type":"uint256"},{"name":"withdrawTime","type":"int64"},{"name":"pledgeAddress","type":"address"}]} ]` MethodNameMintage = "Mintage" @@ -40,6 +40,7 @@ type ParamMintage struct { TokenSymbol string TotalSupply *big.Int Decimals uint8 + Beneficial types.Address } func ParseTokenInfo(data []byte) (*types.TokenInfo, error) { @@ -48,6 +49,9 @@ func ParseTokenInfo(data []byte) (*types.TokenInfo, error) { } tokenInfo := new(types.TokenInfo) err := ABIMintage.UnpackVariable(tokenInfo, VariableNameToken, data) + if err == nil && tokenInfo.PledgeAddress.IsZero() { + tokenInfo.PledgeAddress = tokenInfo.Owner + } return tokenInfo, err } @@ -55,11 +59,3 @@ func NewTokenHash(address types.Address, previous types.Hash, tokenName string) h, _ := types.HashBytes(address[:], previous[:], util.String2Bytes(tokenName)) return h } - -func GetStorageKey(key []byte) []byte { - var tmp []byte - tmp = append(tmp, types.MintageAddress[:]...) - tmp = append(tmp, key...) - - return tmp -} diff --git a/vm/contract/abi/abi_pledge.go b/vm/contract/abi/abi_pledge.go deleted file mode 100644 index a25191b58..000000000 --- a/vm/contract/abi/abi_pledge.go +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2019 QLC Chain Team - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -package abi - -import ( - "github.com/qlcchain/go-qlc/common/types" - "github.com/qlcchain/go-qlc/vm/abi" - "math/big" - "strings" -) - -const ( - jsonPledge = ` - [ - {"type":"function","name":"Pledge", "inputs":[{"name":"beneficial","type":"address"}]}, - {"type":"function","name":"WithdrawPledge","inputs":[{"name":"beneficial","type":"address"},{"name":"amount","type":"uint256"}]}, - {"type":"variable","name":"pledgeInfo","inputs":[{"name":"amount","type":"uint256"},{"name":"withdrawTime","type":"uint64"}]}, - {"type":"variable","name":"pledgeBeneficial","inputs":[{"name":"amount","type":"uint256"}]} - ]` - - MethodNamePledge = "Pledge" - MethodNameWithdrawPledge = "WithdrawPledge" - VariableNamePledgeInfo = "pledgeInfo" - VariableNamePledgeBeneficial = "pledgeBeneficial" -) - -var ( - ABIPledge, _ = abi.JSONToABIContract(strings.NewReader(jsonPledge)) -) - -type VariablePledgeBeneficial struct { - Amount *big.Int -} - -type ParamCancelPledge struct { - Beneficial types.Address - Amount *big.Int -} - -type PledgeInfo struct { - Amount *big.Int - WithdrawTime uint64 - BeneficialAddress types.Address -} - -func GetPledgeBeneficialKey(beneficial types.Address) []byte { - return beneficial.Bytes() -} - -func GetPledgeKey(addr types.Address, pledgeBeneficialKey []byte) []byte { - return append(addr.Bytes(), pledgeBeneficialKey...) -} -func IsPledgeKey(key []byte) bool { - return len(key) == 2*types.AddressSize -} diff --git a/vm/contract/abi/abi_vote_pledge.go b/vm/contract/abi/abi_vote_pledge.go new file mode 100644 index 000000000..6e601806c --- /dev/null +++ b/vm/contract/abi/abi_vote_pledge.go @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2019 QLC Chain Team + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +package abi + +import ( + "github.com/qlcchain/go-qlc/common/types" + "github.com/qlcchain/go-qlc/common/util" + "github.com/qlcchain/go-qlc/vm/abi" + "math/big" + "strings" +) + +const ( + jsonVotePledge = ` + [ + {"type":"function","name":"VotePledge", "inputs":[{"name":"beneficial","type":"address"}]}, + {"type":"function","name":"WithdrawVotePledge","inputs":[{"name":"beneficial","type":"address"},{"name":"amount","type":"uint256"}]}, + {"type":"variable","name":"votePledgeInfo","inputs":[{"name":"amount","type":"uint256"},{"name":"withdrawTime","type":"int64"}]}, + {"type":"variable","name":"votePledgeBeneficial","inputs":[{"name":"amount","type":"uint256"}]} + ]` + + MethodVotePledge = "VotePledge" + MethodWithdrawVotePledge = "WithdrawVotePledge" + VariableVotePledgeInfo = "votePledgeInfo" + VariableVotePledgeBeneficial = "votePledgeBeneficial" +) + +var ( + ABIPledge, _ = abi.JSONToABIContract(strings.NewReader(jsonVotePledge)) +) + +type VariablePledgeBeneficial struct { + Amount *big.Int +} + +type WithdrawPledgeParam struct { + Beneficial types.Address + Amount *big.Int +} + +type VotePledgeInfo struct { + Amount *big.Int + WithdrawTime int64 + BeneficialAddress types.Address +} + +func GetPledgeBeneficialKey(beneficial types.Address) []byte { + return beneficial.Bytes() +} + +func GetPledgeKey(addr types.Address, pledgeBeneficialKey []byte, time int64) []byte { + result := []byte(addr[:]) + tmp := util.Int2Bytes(time) + + result = append(result, pledgeBeneficialKey...) + result = append(result, tmp...) + return result +} + +func GetPledgeKeyPrefix(addr types.Address, pledgeBeneficialKey []byte) []byte { + return append(addr.Bytes(), pledgeBeneficialKey...) +} diff --git a/vm/contract/contract.go b/vm/contract/contract.go index 21d8e2aba..5027ddba3 100644 --- a/vm/contract/contract.go +++ b/vm/contract/contract.go @@ -33,7 +33,6 @@ type ChainContract interface { DoReceive(ledger *ledger.Ledger, block *types.StateBlock, input *types.StateBlock) ([]*ContractBlock, error) // refund data at receive error GetRefundData() []byte - GetQuota() uint64 } type qlcchainContract struct { @@ -51,8 +50,8 @@ var contractCache = map[types.Address]*qlcchainContract{ }, types.PledgeAddress: { map[string]ChainContract{ - cabi.MethodNameMintage: &Pledge{}, - cabi.MethodNameMintageWithdraw: &WithdrawPledge{}, + cabi.MethodNameMintage: &VotePledge{}, + cabi.MethodNameMintageWithdraw: &WithdrawVotePledge{}, }, cabi.ABIPledge, }, diff --git a/vm/contract/mintage.go b/vm/contract/mintage.go index c774dd9cd..c34f95a73 100644 --- a/vm/contract/mintage.go +++ b/vm/contract/mintage.go @@ -25,7 +25,7 @@ var ( MinPledgeAmount = big.NewInt(1e12) // 10K QLC tokenNameLengthMax = 40 // Maximum length of a token name(include) tokenSymbolLengthMax = 10 // Maximum length of a token symbol(include) - minWithdrawTime = time.Duration(24 * 30 * 3) // minWithdrawTime 3 months + minWithdrawTime = time.Duration(24 * 30 * 6) // minWithdrawTime 3 months ) type Mintage struct{} @@ -64,7 +64,8 @@ func (m *Mintage) DoSend(l *l.Ledger, block *types.StateBlock) error { param.TokenName, param.TokenSymbol, param.TotalSupply, - param.Decimals); err != nil { + param.Decimals, + param.Beneficial); err != nil { return err } return nil @@ -103,9 +104,10 @@ func (m *Mintage) DoReceive(ledger *l.Ledger, block *types.StateBlock, input *ty param.TokenSymbol, param.TotalSupply, param.Decimals, - input.Address, + param.Beneficial, MinPledgeAmount, - time.Unix(input.Timestamp, 0).Add(minWithdrawTime).UTC().Unix()) + time.Unix(input.Timestamp, 0).Add(minWithdrawTime).UTC().Unix(), + input.Address) if err != nil { return nil, err } @@ -117,8 +119,10 @@ func (m *Mintage) DoReceive(ledger *l.Ledger, block *types.StateBlock, input *ty totalSupply := types.Balance{Int: new(big.Int).Mul(param.TotalSupply, exp)} block.Type = types.ContractReward + block.Address = param.Beneficial + block.Representative = param.Beneficial block.Token = param.TokenId - block.Link = input.Address.ToHash() + block.Link = input.GetHash() block.Data = tokenInfo block.Previous = types.ZeroHash block.Balance = totalSupply @@ -149,10 +153,6 @@ func (m *Mintage) GetRefundData() []byte { return []byte{1} } -func (m *Mintage) GetQuota() uint64 { - return 0 -} - type WithdrawMintage struct{} func (m *WithdrawMintage) GetFee(ledger *l.Ledger, block *types.StateBlock) (types.Balance, error) { @@ -198,7 +198,24 @@ func (m *WithdrawMintage) DoReceive(ledger *l.Ledger, block *types.StateBlock, i tokenInfo.Decimals, tokenInfo.Owner, big.NewInt(0), - uint64(0)) + uint64(0), + tokenInfo.PledgeAddress) + + b := types.ZeroBalance + if tm, err := ledger.GetTokenMeta(tokenInfo.Owner, common.ChainToken()); err == nil { + b = tm.Balance + } + + block.Type = types.ContractReward + block.Address = tokenInfo.Owner + block.Representative = tokenInfo.Owner + block.Token = common.ChainToken() + block.Link = input.GetHash() + block.Data = newTokenInfo + block.Previous = types.ZeroHash + block.Balance = b.Add(types.Balance{Int: MinPledgeAmount}) + block.Timestamp = time.Now().UTC().Unix() + if err := ledger.SetStorage(types.MintageAddress[:], tokenId[:], newTokenInfo); err != nil { return nil, err } @@ -211,7 +228,7 @@ func (m *WithdrawMintage) DoReceive(ledger *l.Ledger, block *types.StateBlock, i types.ContractRefund, types.Balance{Int: tokenInfo.PledgeAmount}, common.ChainToken(), - []byte{}, + newTokenInfo, }, }, nil } @@ -221,7 +238,3 @@ func (m *WithdrawMintage) DoReceive(ledger *l.Ledger, block *types.StateBlock, i func (m *WithdrawMintage) GetRefundData() []byte { return []byte{2} } - -func (m *WithdrawMintage) GetQuota() uint64 { - return 0 -} diff --git a/vm/contract/pledge.go b/vm/contract/pledge.go deleted file mode 100644 index e833d59ca..000000000 --- a/vm/contract/pledge.go +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2019 QLC Chain Team - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -package contract - -import ( - "errors" - "math/big" - "time" - - "github.com/qlcchain/go-qlc/common/types" - "github.com/qlcchain/go-qlc/ledger" - cabi "github.com/qlcchain/go-qlc/vm/contract/abi" -) - -var ( - minPledgeTime = time.Duration(24 * 30 * 3) // minWithdrawTime 3 months) -) - -type Pledge struct { -} - -func (p *Pledge) GetFee(ledger *ledger.Ledger, block *types.StateBlock) (types.Balance, error) { - return types.ZeroBalance, nil -} - -func (*Pledge) DoSend(ledger *ledger.Ledger, block *types.StateBlock) error { - // check pledge chain coin - // - address is normal user address - // - big than min pledge amount - // transfer quota to beneficial address - return nil -} - -func (*Pledge) DoReceive(ledger *ledger.Ledger, block *types.StateBlock, input *types.StateBlock) ([]*ContractBlock, error) { - beneficialAddr := new(types.Address) - _ = cabi.ABIPledge.UnpackMethod(beneficialAddr, cabi.MethodNamePledge, input.Data) - beneficialKey := cabi.GetPledgeBeneficialKey(*beneficialAddr) - pledgeKey := cabi.GetPledgeKey(input.Address, beneficialKey) - address := block.Address - oldPledgeData, err := ledger.GetStorage(address[:], pledgeKey) - if err != nil { - return nil, err - } - amount := big.NewInt(0) - if len(oldPledgeData) > 0 { - oldPledge := new(cabi.PledgeInfo) - _ = cabi.ABIPledge.UnpackVariable(oldPledge, cabi.VariableNamePledgeInfo, oldPledgeData) - amount = oldPledge.Amount - } - a, _ := ledger.CalculateAmount(input) - amount.Add(amount, a.Int) - - pledgeTime := time.Now().UTC().Add(time.Hour * minPledgeTime).Unix() - pledgeInfo, _ := cabi.ABIPledge.PackVariable(cabi.VariableNamePledgeInfo, amount, pledgeTime) - if err := ledger.SetStorage(nil, pledgeKey, pledgeInfo); err != nil { - return nil, err - } - - address = block.Address - oldBeneficialData, err := ledger.GetStorage(address[:], beneficialKey) - if err != nil { - return nil, err - } - beneficialAmount := big.NewInt(0) - if len(oldBeneficialData) > 0 { - oldBeneficial := new(cabi.VariablePledgeBeneficial) - _ = cabi.ABIPledge.UnpackVariable(oldBeneficial, cabi.VariableNamePledgeBeneficial, oldBeneficialData) - beneficialAmount = oldBeneficial.Amount - } - - beneficialAmount.Add(beneficialAmount, a.Int) - beneficialData, _ := cabi.ABIPledge.PackVariable(cabi.VariableNamePledgeBeneficial, beneficialAmount) - if err = ledger.SetStorage(nil, beneficialKey, beneficialData); err != nil { - return nil, err - } - return nil, nil -} - -func (*Pledge) GetRefundData() []byte { - return []byte{1} -} - -func (*Pledge) GetQuota() uint64 { - return 0 -} - -type WithdrawPledge struct { -} - -func (*WithdrawPledge) GetFee(ledger *ledger.Ledger, block *types.StateBlock) (types.Balance, error) { - return types.ZeroBalance, nil -} - -func (*WithdrawPledge) DoSend(ledger *ledger.Ledger, block *types.StateBlock) (err error) { - if amount, err := ledger.CalculateAmount(block); block.Type != types.Send || amount.Compare(types.ZeroBalance) != types.BalanceCompEqual || err != nil { - return errors.New("invalid block ") - } - param := new(cabi.ParamCancelPledge) - if err := cabi.ABIPledge.UnpackMethod(param, cabi.MethodNameWithdrawPledge, block.Data); err != nil { - return errors.New("invalid input data") - } - - if block.Data, err = cabi.ABIPledge.PackMethod(cabi.MethodNameWithdrawPledge, param.Beneficial, param.Amount); err != nil { - return - } - - return nil -} - -func (*WithdrawPledge) DoReceive(ledger *ledger.Ledger, block *types.StateBlock, input *types.StateBlock) ([]*ContractBlock, error) { - panic("implement me") -} - -func (*WithdrawPledge) GetRefundData() []byte { - return []byte{2} -} - -func (*WithdrawPledge) GetQuota() uint64 { - return 0 -} diff --git a/vm/contract/vote_pledge.go b/vm/contract/vote_pledge.go new file mode 100644 index 000000000..98a487117 --- /dev/null +++ b/vm/contract/vote_pledge.go @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2019 QLC Chain Team + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +package contract + +import ( + "errors" + "github.com/qlcchain/go-qlc/common" + "math/big" + "time" + + "github.com/qlcchain/go-qlc/common/types" + "github.com/qlcchain/go-qlc/ledger" + cabi "github.com/qlcchain/go-qlc/vm/contract/abi" +) + +var ( + minPledgeTime = time.Duration(24 * 30 * 6) // minWithdrawTime 6 months) +) + +type VotePledge struct { +} + +func (p *VotePledge) GetFee(l *ledger.Ledger, block *types.StateBlock) (types.Balance, error) { + return types.ZeroBalance, nil +} + +// check pledge chain coin +// - address is normal user address +// - small than min pledge amount +// transfer quota to beneficial address +func (*VotePledge) DoSend(l *ledger.Ledger, block *types.StateBlock) error { + // check pledge amount + amount, err := l.CalculateAmount(block) + if err != nil { + return err + } + + // check send account is user account + b, err := l.HasAccountMeta(block.Address) + if err != nil { + return err + } + + if block.Token != common.ChainToken() || amount.IsZero() || !b { + return errors.New("invalid block data") + } + + beneficialAddr := new(types.Address) + if err := cabi.ABIPledge.UnpackMethod(beneficialAddr, cabi.MethodVotePledge, block.Data); err != nil { + return errors.New("invalid beneficial address") + } + block.Data, err = cabi.ABIPledge.PackMethod(cabi.MethodVotePledge, *beneficialAddr) + if err != nil { + return err + } + return nil +} + +func (*VotePledge) DoReceive(ledger *ledger.Ledger, block *types.StateBlock, input *types.StateBlock) ([]*ContractBlock, error) { + beneficialAddr := new(types.Address) + _ = cabi.ABIPledge.UnpackMethod(beneficialAddr, cabi.MethodVotePledge, input.Data) + beneficialKey := cabi.GetPledgeBeneficialKey(*beneficialAddr) + pledgeKey := cabi.GetPledgeKey(input.Address, beneficialKey, input.Timestamp) + address := block.Address + oldPledgeData, err := ledger.GetStorage(address[:], pledgeKey) + if err != nil { + return nil, err + } + amount := big.NewInt(0) + if len(oldPledgeData) > 0 { + oldPledge := new(cabi.VotePledgeInfo) + _ = cabi.ABIPledge.UnpackVariable(oldPledge, cabi.VariableVotePledgeInfo, oldPledgeData) + amount = oldPledge.Amount + } + a, _ := ledger.CalculateAmount(input) + amount.Add(amount, a.Int) + + pledgeTime := time.Now().UTC().Add(time.Hour * minPledgeTime).Unix() + pledgeInfo, _ := cabi.ABIPledge.PackVariable(cabi.VariableVotePledgeInfo, amount, pledgeTime) + if err := ledger.SetStorage(nil, pledgeKey, pledgeInfo); err != nil { + return nil, err + } + + address = block.Address + oldBeneficialData, err := ledger.GetStorage(address[:], beneficialKey) + if err != nil { + return nil, err + } + beneficialAmount := big.NewInt(0) + if len(oldBeneficialData) > 0 { + oldBeneficial := new(cabi.VariablePledgeBeneficial) + _ = cabi.ABIPledge.UnpackVariable(oldBeneficial, cabi.VariableVotePledgeBeneficial, oldBeneficialData) + beneficialAmount = oldBeneficial.Amount + } + + beneficialAmount.Add(beneficialAmount, a.Int) + beneficialData, _ := cabi.ABIPledge.PackVariable(cabi.VariableVotePledgeBeneficial, beneficialAmount) + if err = ledger.SetStorage(nil, beneficialKey, beneficialData); err != nil { + return nil, err + } + return nil, nil +} + +func (*VotePledge) GetRefundData() []byte { + return []byte{1} +} + +type WithdrawVotePledge struct { +} + +func (*WithdrawVotePledge) GetFee(ledger *ledger.Ledger, block *types.StateBlock) (types.Balance, error) { + return types.ZeroBalance, nil +} + +func (*WithdrawVotePledge) DoSend(ledger *ledger.Ledger, block *types.StateBlock) (err error) { + if amount, err := ledger.CalculateAmount(block); err != nil { + return err + } else { + if block.Type != types.Send || amount.Compare(types.ZeroBalance) != types.BalanceCompEqual { + return errors.New("invalid block ") + } + } + + param := new(cabi.WithdrawPledgeParam) + if err := cabi.ABIPledge.UnpackMethod(param, cabi.MethodWithdrawVotePledge, block.Data); err != nil { + return errors.New("invalid input data") + } + + if block.Data, err = cabi.ABIPledge.PackMethod(cabi.MethodWithdrawVotePledge, param.Beneficial, param.Amount); err != nil { + return + } + + return nil +} + +func (*WithdrawVotePledge) DoReceive(ledger *ledger.Ledger, block *types.StateBlock, input *types.StateBlock) ([]*ContractBlock, error) { + return nil, nil +} + +func (*WithdrawVotePledge) GetRefundData() []byte { + return []byte{2} +}