Commit 5e474972 authored by Litian's avatar Litian

evm abi init

parents cc7f21d0 08854e25
......@@ -21,10 +21,8 @@ build/main.sh
build/main*
build/para.sh
build/ci
build/tools/autotest/autotest
build/tools/autotest/*.toml
build/tools/autotest/chain33
build/tools/autotest/chain33-cli
build/autotest/*
!build/autotest/build.sh
.DS_Store
logs/
build/wallet
......
......@@ -26,7 +26,15 @@ jobs:
script:
- make test
- stage: auto-test
go: "1.9.x"
install: skip
before_script: make build_ci
script:
- make autotest dapp=all
- stage: coverage
if: branch = master
go: "1.9.x"
before_install:
- go get -t -v ./...
......@@ -35,10 +43,10 @@ jobs:
- make coverage
after_success:
- bash <(curl -s https://codecov.io/bash)
branches:
only: master
- stage: deploy
if: env(DAPP) IS present
sudo: required
services:
- docker
......@@ -55,5 +63,4 @@ jobs:
- sudo mv docker-compose /usr/local/bin
before_script: make build_ci
script:
# - make docker-compose && make docker-compose-down && make docker-compose DAPP=paracross && make docker-compose-down DAPP=paracross && make docker-compose DAPP=relay && make docker-compose-down DAPP=relay
- make docker-compose DAPP=all && make docker-compose-down DAPP=all && make clean
- make docker-compose DAPP=${DAPP} && make docker-compose-down DAPP=${DAPP} && make clean
// ci server: http://39.98.41.13:8080
// user/pass: jenkins/33fuzamei123
pipeline {
agent any
......@@ -14,7 +12,7 @@ pipeline {
retry(1)
timestamps()
gitLabConnection('gitlab33')
gitlabBuilds(builds: ['check', 'build', 'test', 'deploy'])
gitlabBuilds(builds: ['check'])
checkoutToSubdirectory "src/github.com/33cn/plugin"
}
......@@ -23,41 +21,8 @@ pipeline {
steps {
dir("${PROJ_DIR}"){
gitlabCommitStatus(name: 'check'){
sh "git branch;git status"
sh "make auto_ci branch=${env.gitlabSourceBranch}"
}
}
}
}
stage('build') {
steps {
dir("${env.PROJ_DIR}"){
gitlabCommitStatus(name: 'build'){
sh 'make checkgofmt'
sh 'make linter'
}
}
}
}
stage('test'){
agent {
docker{
image 'suyanlong/chain33-run:latest'
}
}
environment {
GOPATH = "${WORKSPACE}"
PROJ_DIR = "${WORKSPACE}/src/github.com/33cn/plugin"
}
steps {
dir("${env.PROJ_DIR}"){
gitlabCommitStatus(name: 'test'){
sh 'make test'
//sh 'export CC=clang-5.0 && make msan'
sh "git branch"
sh "make auto_ci branch=${env.ghprbSourceBranch} originx=${env.ghprbAuthorRepoGitUrl}"
}
}
}
......@@ -92,16 +57,16 @@ pipeline {
success {
echo 'I succeeeded!'
echo "email user: ${gitlabUserEmail}"
mail to: "${gitlabUserEmail}",
echo "email user: ${ghprbActualCommitAuthorEmail}"
mail to: "${ghprbActualCommitAuthorEmail}",
subject: "Successed Pipeline: ${currentBuild.fullDisplayName}",
body: "this is success with ${env.BUILD_URL}"
}
failure {
echo 'I failed '
echo "email user: ${gitlabUserEmail}"
mail to: "${gitlabUserEmail}",
echo "email user: ${ghprbActualCommitAuthorEmail}"
mail to: "${ghprbActualCommitAuthorEmail}",
subject: "Failed Pipeline: ${currentBuild.fullDisplayName}",
body: "Something is wrong with ${env.BUILD_URL}"
}
......
pipeline {
agent any
environment {
GOPATH = "${WORKSPACE}"
PROJ_DIR = "${WORKSPACE}/src/github.com/33cn/plugin"
}
options {
timeout(time: 2,unit: 'HOURS')
retry(1)
timestamps()
gitLabConnection('gitlab33')
gitlabBuilds(builds: ['check', 'build', 'test', 'deploy'])
checkoutToSubdirectory "src/github.com/33cn/plugin"
}
stages {
stage('check') {
steps {
dir("${PROJ_DIR}"){
gitlabCommitStatus(name: 'check'){
sh "git branch;git status"
sh "make auto_ci branch=${env.gitlabSourceBranch}"
}
}
}
}
stage('build') {
steps {
dir("${env.PROJ_DIR}"){
gitlabCommitStatus(name: 'build'){
sh 'make checkgofmt'
sh 'make linter'
}
}
}
}
stage('test'){
agent {
docker{
image 'suyanlong/chain33-run:latest'
}
}
environment {
GOPATH = "${WORKSPACE}"
PROJ_DIR = "${WORKSPACE}/src/github.com/33cn/plugin"
}
steps {
dir("${env.PROJ_DIR}"){
gitlabCommitStatus(name: 'test'){
sh 'make test'
//sh 'export CC=clang-5.0 && make msan'
}
}
}
}
stage('deploy') {
steps {
dir("${PROJ_DIR}"){
gitlabCommitStatus(name: 'deploy'){
sh 'make build_ci'
sh "cd build && mkdir ${env.BUILD_NUMBER} && cp ci/* ${env.BUILD_NUMBER} -r && cp chain33* Dockerfile* docker* *.sh ${env.BUILD_NUMBER}/ && cd ${env.BUILD_NUMBER}/ && ./docker-compose-pre.sh run ${env.BUILD_NUMBER} all "
}
}
}
post {
always {
dir("${PROJ_DIR}"){
sh "cd build/${env.BUILD_NUMBER} && ./docker-compose-pre.sh down ${env.BUILD_NUMBER} all && cd .. && rm -rf ${env.BUILD_NUMBER} && cd .. && make clean "
}
}
}
}
}
post {
always {
echo 'One way or another, I have finished'
// clean up our workspace
deleteDir()
}
success {
echo 'I succeeeded!'
echo "email user: ${gitlabUserEmail}"
mail to: "${gitlabUserEmail}",
subject: "Successed Pipeline: ${currentBuild.fullDisplayName}",
body: "this is success with ${env.BUILD_URL}"
}
failure {
echo 'I failed '
echo "email user: ${gitlabUserEmail}"
mail to: "${gitlabUserEmail}",
subject: "Failed Pipeline: ${currentBuild.fullDisplayName}",
body: "Something is wrong with ${env.BUILD_URL}"
}
}
}
......@@ -10,8 +10,6 @@ SRC_CLI := github.com/33cn/plugin/cli
APP := build/chain33
CHAIN33=github.com/33cn/chain33
CHAIN33_PATH=vendor/${CHAIN33}
AUTO_TEST := build/tools/autotest/autotest
SRC_AUTO_TEST := ${CHAIN33}/cmd/autotest
LDFLAGS := -ldflags "-w -s"
PKG_LIST := `go list ./... | grep -v "vendor" | grep -v "chain33/test" | grep -v "mocks" | grep -v "pbft"`
PKG_LIST_Q := `go list ./... | grep -v "vendor" | grep -v "chain33/test" | grep -v "mocks" | grep -v "blockchain" | grep -v "pbft"`
......@@ -38,12 +36,22 @@ para:
@go build -v -o build/$(NAME) -ldflags "-X $(SRC_CLI)/buildflags.ParaName=user.p.$(NAME). -X $(SRC_CLI)/buildflags.RPCAddr=http://localhost:8901" $(SRC_CLI)
autotest:## build autotest binary
@go build -v -i -o $(AUTO_TEST) $(SRC_AUTO_TEST)
@cp cmd/autotest/*.toml build/tools/autotest/
autotest: ## build autotest binary
@cd build/autotest && bash ./build.sh && cd ../../
@if [ -n "$(dapp)" ]; then \
cd build/tools/autotest && bash ./local-autotest.sh $(dapp) && cd ../../../; \
fi
rm -rf build/autotest/local \
&& cp -r $(CHAIN33_PATH)/build/autotest/local $(CHAIN33_PATH)/build/autotest/*.sh build/autotest/ \
&& cd build/autotest && bash ./copy-autotest.sh local && cd local && bash ./local-autotest.sh $(dapp) && cd ../../../; fi
autotest_ci: autotest ## autotest ci
@rm -rf build/autotest/jerkinsci \
&& cp -r $(CHAIN33_PATH)/build/autotest/jerkinsci $(CHAIN33_PATH)/build/autotest/*.sh build/autotest/ \
&& cd build/autotest && bash ./copy-autotest.sh jerkinsci/temp$(proj) \
&& cd jerkinsci && bash ./jerkins-ci-autotest.sh $(proj) && cd ../../../
autotest_tick: autotest ## run with ticket mining
@rm -rf build/autotest/gitlabci \
&& cp -r $(CHAIN33_PATH)/build/autotest/gitlabci $(CHAIN33_PATH)/build/autotest/*.sh build/autotest/ \
&& cd build/autotest && bash ./copy-autotest.sh gitlabci \
&& cd gitlabci && bash ./gitlab-ci-autotest.sh build && cd ../../../
update:
rm -rf ${CHAIN33_PATH}
......@@ -142,7 +150,7 @@ clean: ## Remove previous build
@rm -rf build/relayd*
@rm -rf build/*.log
@rm -rf build/logs
@rm -rf build/tools/autotest/autotest
@rm -rf build/autotest/autotest
@rm -rf build/ci
@rm -rf tool
@go clean
......@@ -224,7 +232,10 @@ auto_ci: clean fmt_proto fmt_shell protobuf
git add -u; \
git status; \
git commit -a -m "auto ci"; \
git push origin HEAD:$(branch); \
git remote add originx $(originx); \
git remote -v; \
git push --quiet --set-upstream originx HEAD:$(branch); \
git log -n 2; \
exit 1; \
fi;
......
......@@ -70,3 +70,10 @@ make push b=branch_dev_name m="hello world"
```
如果m不设置,那么不会执行 git commit 的命令
#### 测试代码
类似plugin/dapp/relay,在cmd目录下编写自己插件的Makefile和build.sh
在build目录下写testcase和相关的Dockerfile和docker-compose配置文件,
testcase的规则参考plugin/dapp/testcase_compose_rule.md
用户可以在travis自己工程里面设置自己plugin的DAPP变量,如DAPP设置为relay,则travis里面run relay的testcase
#!/usr/bin/env bash
set -e
set -o pipefail
#set -o verbose
#set -o xtrace
sedfix=""
if [ "$(uname)" == "Darwin" ]; then
sedfix=".bak"
fi
AutoTestMain="../../vendor/github.com/33cn/chain33/cmd/autotest/main.go"
ImportPlugin='"github.com/33cn/plugin/plugin"'
function build_auto_test() {
cp "${AutoTestMain}" ./
sed -i $sedfix "/^package/a import _ ${ImportPlugin}" main.go
go build -v -i -o autotest
}
function clean_auto_test() {
rm -f ../autotest/main.go
}
trap "clean_auto_test" INT TERM EXIT
build_auto_test
This diff is collapsed.
......@@ -112,7 +112,7 @@ func TestFilterTxsForPara(t *testing.T) {
Receipts: receipts,
}
para := &ParaClient{}
para := &client{}
rst := para.FilterTxsForPara(detail)
filterTxs := []*types.Transaction{tx3, tx4, tx5, tx6, txA, txB, txC}
assert.Equal(t, filterTxs, rst)
......
......@@ -21,8 +21,8 @@ var (
consensusInterval = 16 //about 1 new block interval
)
type CommitMsgClient struct {
paraClient *ParaClient
type commitMsgClient struct {
paraClient *client
waitMainBlocks int32
commitMsgNotify chan int64
delMsgNotify chan int64
......@@ -33,7 +33,7 @@ type CommitMsgClient struct {
quit chan struct{}
}
func (client *CommitMsgClient) handler() {
func (client *commitMsgClient) handler() {
var isSync bool
var notification []int64 //记录每次系统重启后 min and current height
var finishHeight int64
......@@ -185,7 +185,7 @@ out:
client.paraClient.wg.Done()
}
func (client *CommitMsgClient) calcCommitMsgTxs(notifications []*pt.ParacrossNodeStatus) (*types.Transaction, int64, error) {
func (client *commitMsgClient) calcCommitMsgTxs(notifications []*pt.ParacrossNodeStatus) (*types.Transaction, int64, error) {
txs, count, err := client.batchCalcTxGroup(notifications)
if err != nil {
txs, err = client.singleCalcTx((notifications)[0])
......@@ -199,7 +199,7 @@ func (client *CommitMsgClient) calcCommitMsgTxs(notifications []*pt.ParacrossNod
return txs, int64(count), nil
}
func (client *CommitMsgClient) getTxsGroup(txsArr *types.Transactions) (*types.Transaction, error) {
func (client *commitMsgClient) getTxsGroup(txsArr *types.Transactions) (*types.Transaction, error) {
if len(txsArr.Txs) < 2 {
tx := txsArr.Txs[0]
tx.Sign(types.SECP256K1, client.privateKey)
......@@ -224,7 +224,7 @@ func (client *CommitMsgClient) getTxsGroup(txsArr *types.Transactions) (*types.T
return newtx, nil
}
func (client *CommitMsgClient) batchCalcTxGroup(notifications []*pt.ParacrossNodeStatus) (*types.Transaction, int, error) {
func (client *commitMsgClient) batchCalcTxGroup(notifications []*pt.ParacrossNodeStatus) (*types.Transaction, int, error) {
var rawTxs types.Transactions
for _, status := range notifications {
tx, err := paracross.CreateRawCommitTx4MainChain(status, pt.ParaX, 0)
......@@ -242,7 +242,7 @@ func (client *CommitMsgClient) batchCalcTxGroup(notifications []*pt.ParacrossNod
return txs, len(notifications), nil
}
func (client *CommitMsgClient) singleCalcTx(status *pt.ParacrossNodeStatus) (*types.Transaction, error) {
func (client *commitMsgClient) singleCalcTx(status *pt.ParacrossNodeStatus) (*types.Transaction, error) {
tx, err := paracross.CreateRawCommitTx4MainChain(status, pt.ParaX, 0)
if err != nil {
plog.Error("para get commit tx", "block height", status.Height)
......@@ -258,7 +258,7 @@ func (client *CommitMsgClient) singleCalcTx(status *pt.ParacrossNodeStatus) (*ty
// if sendCommitMsgTx block quite long, write channel will be block in handle(), addBlock will not send new msg until rpc send over
// if sendCommitMsgTx block quite long, if delMsg occur, after send over, ignore previous tx succ or fail, new msg will be rcv and sent
// if sendCommitMsgTx fail, wait 1s resend the failed tx, if new tx rcv from ch, send the new one.
func (client *CommitMsgClient) sendCommitMsg(ch chan *types.Transaction) {
func (client *commitMsgClient) sendCommitMsg(ch chan *types.Transaction) {
var err error
var tx *types.Transaction
resendTimer := time.After(time.Second * 1)
......@@ -286,7 +286,7 @@ out:
client.paraClient.wg.Done()
}
func (client *CommitMsgClient) sendCommitMsgTx(tx *types.Transaction) error {
func (client *commitMsgClient) sendCommitMsgTx(tx *types.Transaction) error {
if tx == nil {
return nil
}
......@@ -319,7 +319,7 @@ func checkTxInMainBlock(targetTx *types.Transaction, detail *types.BlockDetail)
//当前未考虑获取key非常多失败的场景, 如果获取height非常多,block模块会比较大,但是使用完了就释放了
//如果有必要也可以考虑每次最多取20个一个txgroup,发送共识部分循环获取发送也没问题
func (client *CommitMsgClient) getNodeStatus(start, end int64) ([]*pt.ParacrossNodeStatus, error) {
func (client *commitMsgClient) getNodeStatus(start, end int64) ([]*pt.ParacrossNodeStatus, error) {
var ret []*pt.ParacrossNodeStatus
if start == 0 {
geneStatus, err := client.getGenesisNodeStatus()
......@@ -402,7 +402,7 @@ func (client *CommitMsgClient) getNodeStatus(start, end int64) ([]*pt.ParacrossN
}
func (client *CommitMsgClient) getGenesisNodeStatus() (*pt.ParacrossNodeStatus, error) {
func (client *commitMsgClient) getGenesisNodeStatus() (*pt.ParacrossNodeStatus, error) {
var status pt.ParacrossNodeStatus
req := &types.ReqBlocks{Start: 0, End: 0}
msg := client.paraClient.GetQueueClient().NewMessage("blockchain", types.EventGetBlocks, req)
......@@ -425,7 +425,7 @@ func (client *CommitMsgClient) getGenesisNodeStatus() (*pt.ParacrossNodeStatus,
return &status, nil
}
func (client *CommitMsgClient) onBlockAdded(height int64) error {
func (client *commitMsgClient) onBlockAdded(height int64) error {
select {
case client.commitMsgNotify <- height:
case <-client.quit:
......@@ -434,14 +434,14 @@ func (client *CommitMsgClient) onBlockAdded(height int64) error {
return nil
}
func (client *CommitMsgClient) onBlockDeleted(height int64) {
func (client *commitMsgClient) onBlockDeleted(height int64) {
select {
case client.delMsgNotify <- height:
case <-client.quit:
}
}
func (client *CommitMsgClient) onMainBlockAdded(block *types.BlockDetail) {
func (client *commitMsgClient) onMainBlockAdded(block *types.BlockDetail) {
select {
case client.mainBlockAdd <- block:
case <-client.quit:
......@@ -449,7 +449,7 @@ func (client *CommitMsgClient) onMainBlockAdded(block *types.BlockDetail) {
}
//only sync once, as main usually sync, here just need the first sync status after start up
func (client *CommitMsgClient) mainSync() error {
func (client *commitMsgClient) mainSync() error {
req := &types.ReqNil{}
reply, err := client.paraClient.grpcClient.IsSync(context.Background(), req)
if err != nil {
......@@ -466,7 +466,7 @@ func (client *CommitMsgClient) mainSync() error {
}
func (client *CommitMsgClient) getConsensusHeight(consensusRst chan *pt.ParacrossStatus) {
func (client *commitMsgClient) getConsensusHeight(consensusRst chan *pt.ParacrossStatus) {
ticker := time.NewTicker(time.Second * time.Duration(consensusInterval))
isSync := false
defer ticker.Stop()
......@@ -486,7 +486,7 @@ out:
}
ret, err := client.paraClient.paraClient.GetTitle(context.Background(),
&types.ReqString{types.GetTitle()})
&types.ReqString{Data: types.GetTitle()})
if err != nil {
plog.Error("getConsensusHeight ", "err", err.Error())
continue
......@@ -499,7 +499,7 @@ out:
client.paraClient.wg.Done()
}
func (client *CommitMsgClient) fetchPrivacyKey(ch chan crypto.PrivKey) {
func (client *commitMsgClient) fetchPrivacyKey(ch chan crypto.PrivKey) {
defer client.paraClient.wg.Done()
if client.paraClient.authAccount == "" {
close(ch)
......@@ -544,7 +544,7 @@ out:
}
func CheckMinerTx(current *types.BlockDetail) error {
func checkMinerTx(current *types.BlockDetail) error {
//检查第一个笔交易的execs, 以及执行状态
if len(current.Block.Txs) == 0 {
return types.ErrEmptyTx
......
......@@ -42,7 +42,7 @@ func init() {
type suiteParaCommitMsg struct {
// Include our basic suite logic.
suite.Suite
para *ParaClient
para *client
grpcCli *typesmocks.Chain33Client
q queue.Queue
block *blockchain.BlockChain
......@@ -70,7 +70,7 @@ func (s *suiteParaCommitMsg) initEnv(cfg *types.Config, sub *types.ConfigSubModu
s.store = store.New(cfg.Store, sub.Store)
s.store.SetQueueClient(q.Client())
s.para = New(cfg.Consensus, sub.Consensus["para"]).(*ParaClient)
s.para = New(cfg.Consensus, sub.Consensus["para"]).(*client)
s.grpcCli = &typesmocks.Chain33Client{}
//data := &types.Int64{1}
s.grpcCli.On("GetLastBlockSequence", mock.Anything, mock.Anything).Return(nil, errors.New("nil"))
......@@ -97,7 +97,7 @@ func (s *suiteParaCommitMsg) initEnv(cfg *types.Config, sub *types.ConfigSubModu
}
func walletProcess(q queue.Queue, para *ParaClient) {
func walletProcess(q queue.Queue, para *client) {
defer para.wg.Done()
client := q.Client()
......@@ -109,7 +109,7 @@ func walletProcess(q queue.Queue, para *ParaClient) {
return
case msg := <-client.Recv():
if msg.Ty == types.EventDumpPrivkey {
msg.Reply(client.NewMessage("", types.EventHeader, &types.ReplyString{"6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b"}))
msg.Reply(client.NewMessage("", types.EventHeader, &types.ReplyString{Data: "6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b"}))
}
}
}
......
......@@ -16,37 +16,44 @@ import (
func init() {
drivers.Reg("pbft", NewPbft)
drivers.QueryData.Register("pbft", &PbftClient{})
drivers.QueryData.Register("pbft", &Client{})
}
type PbftClient struct {
// Client Pbft implementation
type Client struct {
*drivers.BaseClient
replyChan chan *types.ClientReply
requestChan chan *types.Request
isPrimary bool
}
func NewBlockstore(cfg *types.Consensus, replyChan chan *types.ClientReply, requestChan chan *types.Request, isPrimary bool) *PbftClient {
// NewBlockstore create Pbft Client
func NewBlockstore(cfg *types.Consensus, replyChan chan *types.ClientReply, requestChan chan *types.Request, isPrimary bool) *Client {
c := drivers.NewBaseClient(cfg)
client := &PbftClient{BaseClient: c, replyChan: replyChan, requestChan: requestChan, isPrimary: isPrimary}
client := &Client{BaseClient: c, replyChan: replyChan, requestChan: requestChan, isPrimary: isPrimary}
c.SetChild(client)
return client
}
func (client *PbftClient) ProcEvent(msg queue.Message) bool {
// ProcEvent method
func (client *Client) ProcEvent(msg queue.Message) bool {
return false
}
func (client *PbftClient) Propose(block *types.Block) {
op := &types.Operation{block}
// Propose method
func (client *Client) Propose(block *types.Block) {
op := &types.Operation{Value: block}
req := ToRequestClient(op, types.Now().String(), clientAddr)
client.requestChan <- req
}
func (client *PbftClient) CheckBlock(parent *types.Block, current *types.BlockDetail) error {
// CheckBlock method
func (client *Client) CheckBlock(parent *types.Block, current *types.BlockDetail) error {
return nil
}
func (client *PbftClient) SetQueueClient(c queue.Client) {
// SetQueueClient method
func (client *Client) SetQueueClient(c queue.Client) {
plog.Info("Enter SetQueue method of pbft consensus")
client.InitClient(c, func() {
......@@ -57,7 +64,8 @@ func (client *PbftClient) SetQueueClient(c queue.Client) {
go client.CreateBlock()
}
func (client *PbftClient) CreateBlock() {
// CreateBlock method
func (client *Client) CreateBlock() {
issleep := true
if !client.isPrimary {
return
......@@ -95,11 +103,13 @@ func (client *PbftClient) CreateBlock() {
}
}
func (client *PbftClient) GetGenesisBlockTime() int64 {
// GetGenesisBlockTime get genesis blocktime
func (client *Client) GetGenesisBlockTime() int64 {
return genesisBlockTime
}
func (client *PbftClient) CreateGenesisTx() (ret []*types.Transaction) {
// CreateGenesisTx get genesis tx
func (client *Client) CreateGenesisTx() (ret []*types.Transaction) {
var tx types.Transaction
tx.Execer = []byte("coins")
tx.To = genesis
......@@ -112,7 +122,7 @@ func (client *PbftClient) CreateGenesisTx() (ret []*types.Transaction) {
return
}
func (client *PbftClient) readReply() {
func (client *Client) readReply() {
data := <-client.replyChan
if data == nil {
......
......@@ -89,7 +89,7 @@ powLimitBits = "0x1f2fffff"
[consensus.sub.pbft]
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
genesisBlockTime=1514533394
nodeId=1
nodeID=1
peersURL="127.0.0.1:8890"
clientAddr="127.0.0.1:8890"
......
......@@ -22,11 +22,12 @@ var (
type subConfig struct {
Genesis string `json:"genesis"`
GenesisBlockTime int64 `json:"genesisBlockTime"`
NodeId int64 `json:"nodeId"`
NodeID int64 `json:"nodeID"`
PeersURL string `json:"peersURL"`
ClientAddr string `json:"clientAddr"`
}
// NewPbft create pbft cluster
func NewPbft(cfg *pb.Consensus, sub []byte) queue.Module {
plog.Info("start to creat pbft node")
var subcfg subConfig
......@@ -40,14 +41,14 @@ func NewPbft(cfg *pb.Consensus, sub []byte) queue.Module {
if subcfg.GenesisBlockTime > 0 {
genesisBlockTime = subcfg.GenesisBlockTime
}
if int(subcfg.NodeId) == 0 || strings.Compare(subcfg.PeersURL, "") == 0 || strings.Compare(subcfg.ClientAddr, "") == 0 {
if int(subcfg.NodeID) == 0 || strings.Compare(subcfg.PeersURL, "") == 0 || strings.Compare(subcfg.ClientAddr, "") == 0 {
plog.Error("The nodeId, peersURL or clientAddr is empty!")
return nil
}
clientAddr = subcfg.ClientAddr
var c *PbftClient
replyChan, requestChan, isPrimary := NewReplica(uint32(subcfg.NodeId), subcfg.PeersURL, subcfg.ClientAddr)
var c *Client
replyChan, requestChan, isPrimary := NewReplica(uint32(subcfg.NodeID), subcfg.PeersURL, subcfg.ClientAddr)
c = NewBlockstore(cfg, replyChan, requestChan, isPrimary)
return c
}
......@@ -15,8 +15,7 @@ import (
"github.com/golang/protobuf/proto"
)
// Digest
// EQ Digest
func EQ(d1 []byte, d2 []byte) bool {
if len(d1) != len(d2) {
return false
......@@ -29,90 +28,91 @@ func EQ(d1 []byte, d2 []byte) bool {
return true
}
// Checkpoint
// ToCheckpoint method
func ToCheckpoint(sequence uint32, digest []byte) *types.Checkpoint {
return &types.Checkpoint{sequence, digest}
return &types.Checkpoint{Sequence: sequence, Digest: digest}
}
// Entry
// ToEntry method
func ToEntry(sequence uint32, digest []byte, view uint32) *types.Entry {
return &types.Entry{sequence, digest, view}
return &types.Entry{Sequence: sequence, Digest: digest, View: view}
}
// ViewChange
// ToViewChange method
func ToViewChange(viewchanger uint32, digest []byte) *types.ViewChange {
return &types.ViewChange{viewchanger, digest}
return &types.ViewChange{Viewchanger: viewchanger, Digest: digest}
}
// Summary
// ToSummary method
func ToSummary(sequence uint32, digest []byte) *types.Summary {
return &types.Summary{sequence, digest}
return &types.Summary{Sequence: sequence, Digest: digest}
}
// Request
// ToRequestClient method
func ToRequestClient(op *types.Operation, timestamp, client string) *types.Request {
return &types.Request{
Value: &types.Request_Client{
&types.RequestClient{op, timestamp, client}},
Client: &types.RequestClient{Op: op, Timestamp: timestamp, Client: client}},
}
}
// ToRequestPreprepare method
func ToRequestPreprepare(view, sequence uint32, digest []byte, replica uint32) *types.Request {
return &types.Request{
Value: &types.Request_Preprepare{
&types.RequestPrePrepare{view, sequence, digest, replica}},
Preprepare: &types.RequestPrePrepare{View: view, Sequence: sequence, Digest: digest, Replica: replica}},
}
}
// ToRequestPrepare method
func ToRequestPrepare(view, sequence uint32, digest []byte, replica uint32) *types.Request {
return &types.Request{
Value: &types.Request_Prepare{
&types.RequestPrepare{view, sequence, digest, replica}},
Prepare: &types.RequestPrepare{View: view, Sequence: sequence, Digest: digest, Replica: replica}},
}
}
// ToRequestCommit method
func ToRequestCommit(view, sequence, replica uint32) *types.Request {
return &types.Request{
Value: &types.Request_Commit{
&types.RequestCommit{view, sequence, replica}},
Commit: &types.RequestCommit{View: view, Sequence: sequence, Replica: replica}},
}
}
// ToRequestCheckpoint method
func ToRequestCheckpoint(sequence uint32, digest []byte, replica uint32) *types.Request {
return &types.Request{
Value: &types.Request_Checkpoint{
&types.RequestCheckpoint{sequence, digest, replica}},
Checkpoint: &types.RequestCheckpoint{Sequence: sequence, Digest: digest, Replica: replica}},
}
}
// ToRequestViewChange method
func ToRequestViewChange(view, sequence uint32, checkpoints []*types.Checkpoint, preps, prePreps []*types.Entry, replica uint32) *types.Request {
return &types.Request{
Value: &types.Request_Viewchange{
&types.RequestViewChange{view, sequence, checkpoints, preps, prePreps, replica}},
Viewchange: &types.RequestViewChange{View: view, Sequence: sequence, Checkpoints: checkpoints, Preps: preps, Prepreps: prePreps, Replica: replica}},
}
}
// ToRequestAck method
func ToRequestAck(view, replica, viewchanger uint32, digest []byte) *types.Request {
return &types.Request{
Value: &types.Request_Ack{
&types.RequestAck{view, replica, viewchanger, digest}},
Ack: &types.RequestAck{View: view, Replica: replica, Viewchanger: viewchanger, Digest: digest}},
}
}
// ToRequestNewView method
func ToRequestNewView(view uint32, viewChanges []*types.ViewChange, summaries []*types.Summary, replica uint32) *types.Request {
return &types.Request{
Value: &types.Request_Newview{
&types.RequestNewView{view, viewChanges, summaries, replica}},
Newview: &types.RequestNewView{View: view, Viewchanges: viewChanges, Summaries: summaries, Replica: replica}},
}
}
// Request Methods
// ReqDigest method
func ReqDigest(req *types.Request) []byte {
if req == nil {
return nil
......@@ -130,14 +130,12 @@ func ReqDigest(req *types.Request) []byte {
return lwm
}*/
// Reply
// ToReply method
func ToReply(view uint32, timestamp, client string, replica uint32, result *types.Result) *types.ClientReply {
return &types.ClientReply{view, timestamp, client, replica, result}
return &types.ClientReply{View: view, Timestamp: timestamp, Client: client, Replica: replica, Result: result}
}
// Reply Methods
// RepDigest method
func RepDigest(reply fmt.Stringer) []byte {
if reply == nil {
return nil
......@@ -146,8 +144,7 @@ func RepDigest(reply fmt.Stringer) []byte {
return bytes[:]
}
// Write proto message
// WriteMessage write proto message
func WriteMessage(addr string, msg proto.Message) error {
conn, err := net.Dial("tcp", addr)
defer conn.Close()
......@@ -163,8 +160,7 @@ func WriteMessage(addr string, msg proto.Message) error {
return err
}
// Read proto message
// ReadMessage read proto message
func ReadMessage(conn io.Reader, msg proto.Message) error {
var buf bytes.Buffer
n, err := io.Copy(&buf, conn)
......
......@@ -13,11 +13,13 @@ import (
"github.com/golang/protobuf/proto"
)
// constant
const (
CHECKPOINT_PERIOD uint32 = 128
CONSTANT_FACTOR uint32 = 2
CheckPointPeriod uint32 = 128
ConstantFactor uint32 = 2
)
// Replica struct
type Replica struct {
ID uint32
replicas map[uint32]string
......@@ -36,6 +38,7 @@ type Replica struct {
checkpoints []*pb.Checkpoint
}
// NewReplica create Replica instance
func NewReplica(id uint32, PeersURL string, addr string) (chan *pb.ClientReply, chan *pb.Request, bool) {
replyChan := make(chan *pb.ClientReply)
requestChan := make(chan *pb.Request)
......@@ -65,6 +68,7 @@ func NewReplica(id uint32, PeersURL string, addr string) (chan *pb.ClientReply,
}
// Startnode method
func (rep *Replica) Startnode(addr string) {
rep.acceptConnections(addr)
}
......@@ -104,7 +108,7 @@ func (rep *Replica) lowWaterMark() uint32 {
}
func (rep *Replica) highWaterMark() uint32 {
return rep.lowWaterMark() + CHECKPOINT_PERIOD*CONSTANT_FACTOR
return rep.lowWaterMark() + CheckPointPeriod*ConstantFactor
}
func (rep *Replica) sequenceInRange(sequence uint32) bool {
......@@ -133,9 +137,8 @@ func (rep *Replica) theLastReply() *pb.ClientReply {
func (rep *Replica) lastReplyToClient(client string) *pb.ClientReply {
if v, ok := rep.replies[client]; ok {
return v[len(rep.replies[client])-1]
} else {
return nil
}
return nil
}
func (rep *Replica) stateDigest() []byte {
......@@ -143,7 +146,7 @@ func (rep *Replica) stateDigest() []byte {
}
func (rep *Replica) isCheckpoint(sequence uint32) bool {
return sequence%CHECKPOINT_PERIOD == 0
return sequence%CheckPointPeriod == 0
}
func (rep *Replica) addCheckpoint(checkpoint *pb.Checkpoint) {
......@@ -735,7 +738,7 @@ func (rep *Replica) handleRequestCommit(REQ *pb.Request) {
op := req.GetClient().Op
timestamp := req.GetClient().Timestamp
client := req.GetClient().Client
result := &pb.Result{op.Value}
result := &pb.Result{Value: op.Value}
rep.executed = append(rep.executed, sequence)
reply := ToReply(view, timestamp, client, rep.ID, result)
......@@ -1036,7 +1039,7 @@ func (rep *Replica) correctSummaries(requests []*pb.Request, summaries []*pb.Sum
return
}
end := start + CHECKPOINT_PERIOD*CONSTANT_FACTOR
end := start + CheckPointPeriod*ConstantFactor
for seq := start; seq <= end; seq++ {
......@@ -1516,7 +1519,7 @@ FOR_LOOP_1:
summaries = append(summaries, summary)
start = summary.Sequence
end = start + CHECKPOINT_PERIOD*CONSTANT_FACTOR
end = start + CheckPointPeriod*ConstantFactor
// select summaries
// TODO: optimize
......
......@@ -96,7 +96,7 @@ func sendReplyList(q queue.Queue) {
count++
createReplyList("test" + strconv.Itoa(count))
msg.Reply(client.NewMessage("consensus", types.EventReplyTxList,
&types.ReplyTxList{transactions}))
&types.ReplyTxList{Txs: transactions}))
if count == 5 {
time.Sleep(5 * time.Second)
break
......@@ -125,7 +125,7 @@ func createReplyList(account string) {
var result []*types.Transaction
for j := 0; j < txSize; j++ {
//tx := &types.Transaction{}
val := &cty.CoinsAction_Transfer{&types.AssetsTransfer{Amount: 10}}
val := &cty.CoinsAction_Transfer{Transfer: &types.AssetsTransfer{Amount: 10}}
action := &cty.CoinsAction{Value: val, Ty: cty.CoinsActionTransfer}
tx := &types.Transaction{Execer: []byte("coins"), Payload: types.Encode(action), Fee: 0}
tx.To = "14qViLJfdGaP4EeHnDyJbEGQysnCpwn1gZ"
......
......@@ -24,10 +24,11 @@ var (
func init() {
drivers.Reg("raft", NewRaftCluster)
drivers.QueryData.Register("raft", &RaftClient{})
drivers.QueryData.Register("raft", &Client{})
}
type RaftClient struct {
// Client Raft implementation
type Client struct {
*drivers.BaseClient
proposeC chan<- *types.Block
commitC <-chan *types.Block
......@@ -38,18 +39,21 @@ type RaftClient struct {
once sync.Once
}
func NewBlockstore(cfg *types.Consensus, snapshotter *snap.Snapshotter, proposeC chan<- *types.Block, commitC <-chan *types.Block, errorC <-chan error, validatorC <-chan bool, stopC chan<- struct{}) *RaftClient {
// NewBlockstore create Raft Client
func NewBlockstore(cfg *types.Consensus, snapshotter *snap.Snapshotter, proposeC chan<- *types.Block, commitC <-chan *types.Block, errorC <-chan error, validatorC <-chan bool, stopC chan<- struct{}) *Client {
c := drivers.NewBaseClient(cfg)
client := &RaftClient{BaseClient: c, proposeC: proposeC, snapshotter: snapshotter, validatorC: validatorC, commitC: commitC, errorC: errorC, stopC: stopC}
client := &Client{BaseClient: c, proposeC: proposeC, snapshotter: snapshotter, validatorC: validatorC, commitC: commitC, errorC: errorC, stopC: stopC}
c.SetChild(client)
return client
}
func (client *RaftClient) GetGenesisBlockTime() int64 {
// GetGenesisBlockTime get genesis blocktime
func (client *Client) GetGenesisBlockTime() int64 {
return genesisBlockTime
}
func (client *RaftClient) CreateGenesisTx() (ret []*types.Transaction) {
// CreateGenesisTx get genesis tx
func (client *Client) CreateGenesisTx() (ret []*types.Transaction) {
var tx types.Transaction
tx.Execer = []byte(cty.CoinsX)
tx.To = genesis
......@@ -62,20 +66,22 @@ func (client *RaftClient) CreateGenesisTx() (ret []*types.Transaction) {
return
}
func (client *RaftClient) ProcEvent(msg queue.Message) bool {
// ProcEvent method
func (client *Client) ProcEvent(msg queue.Message) bool {
return false
}
func (client *RaftClient) CheckBlock(parent *types.Block, current *types.BlockDetail) error {
// CheckBlock method
func (client *Client) CheckBlock(parent *types.Block, current *types.BlockDetail) error {
return nil
}
func (client *RaftClient) getSnapshot() ([]byte, error) {
func (client *Client) getSnapshot() ([]byte, error) {
//这里可能导致死锁
return proto.Marshal(client.GetCurrentBlock())
}
func (client *RaftClient) recoverFromSnapshot(snapshot []byte) error {
func (client *Client) recoverFromSnapshot(snapshot []byte) error {
var block types.Block
if err := proto.Unmarshal(snapshot, &block); err != nil {
return err
......@@ -84,7 +90,8 @@ func (client *RaftClient) recoverFromSnapshot(snapshot []byte) error {
return nil
}
func (client *RaftClient) SetQueueClient(c queue.Client) {
// SetQueueClient method
func (client *Client) SetQueueClient(c queue.Client) {
rlog.Info("Enter SetQueue method of raft consensus")
client.InitClient(c, func() {
})
......@@ -93,12 +100,14 @@ func (client *RaftClient) SetQueueClient(c queue.Client) {
go client.pollingTask(c)
}
func (client *RaftClient) Close() {
// Close method
func (client *Client) Close() {
client.stopC <- struct{}{}
rlog.Info("consensus raft closed")
}
func (client *RaftClient) CreateBlock() {
// CreateBlock method
func (client *Client) CreateBlock() {
issleep := true
retry := 0
infoflag := 0
......@@ -187,12 +196,12 @@ func (client *RaftClient) CreateBlock() {
}
// 向raft底层发送block
func (client *RaftClient) propose(block *types.Block) {
func (client *Client) propose(block *types.Block) {
client.proposeC <- block
}
// 从receive channel中读leader发来的block
func (client *RaftClient) readCommits(commitC <-chan *types.Block, errorC <-chan error) {
func (client *Client) readCommits(commitC <-chan *types.Block, errorC <-chan error) {
var data *types.Block
var ok bool
for {
......@@ -216,7 +225,7 @@ func (client *RaftClient) readCommits(commitC <-chan *types.Block, errorC <-chan
}
//轮询任务,去检测本机器是否为validator节点,如果是,则执行打包任务
func (client *RaftClient) pollingTask(c queue.Client) {
func (client *Client) pollingTask(c queue.Client) {
ticker := time.NewTicker(100 * time.Millisecond)
defer ticker.Stop()
for {
......
......@@ -95,9 +95,9 @@ genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
genesisBlockTime=1514533394
# =============== raft共识配置参数 ===========================
# 共识节点ID,raft共识用到,不同的节点设置不同的nodeId(目前只支持1,2,3这种设置)
nodeId=1
nodeID=1
# raft共识用到,通过这个端口进行节点的增加和删除
raftApiPort=9121
raftAPIPort=9121
# raft共识用到,指示这个节点是否新增加节点
isNewJoinNode=false
# raft共识用到,指示raft集群中的服务器IP和端口
......
......@@ -20,17 +20,17 @@ var (
defaultSnapCount uint64 = 1000
snapshotCatchUpEntriesN uint64 = 1000
writeBlockSeconds int64 = 1
heartbeatTick int = 1
isLeader bool = false
heartbeatTick = 1
isLeader = false
confChangeC chan raftpb.ConfChange
)
type subConfig struct {
Genesis string `json:"genesis"`
GenesisBlockTime int64 `json:"genesisBlockTime"`
NodeId int64 `json:"nodeId"`
NodeID int64 `json:"nodeID"`
PeersURL string `json:"peersURL"`
RaftApiPort int64 `json:"raftApiPort"`
RaftAPIPort int64 `json:"raftAPIPort"`
IsNewJoinNode bool `json:"isNewJoinNode"`
ReadOnlyPeersURL string `json:"readOnlyPeersURL"`
AddPeersURL string `json:"addPeersURL"`
......@@ -39,6 +39,7 @@ type subConfig struct {
HeartbeatTick int32 `json:"heartbeatTick"`
}
// NewRaftCluster create raft cluster
func NewRaftCluster(cfg *types.Consensus, sub []byte) queue.Module {
rlog.Info("Start to create raft cluster")
var subcfg subConfig
......@@ -52,7 +53,7 @@ func NewRaftCluster(cfg *types.Consensus, sub []byte) queue.Module {
if subcfg.GenesisBlockTime > 0 {
genesisBlockTime = subcfg.GenesisBlockTime
}
if int(subcfg.NodeId) == 0 || strings.Compare(subcfg.PeersURL, "") == 0 {
if int(subcfg.NodeID) == 0 || strings.Compare(subcfg.PeersURL, "") == 0 {
rlog.Error("Please check whether the configuration of nodeId and peersURL is empty!")
//TODO 当传入的参数异常时,返回给主函数的是个nil,这时候需要做异常处理
return nil
......@@ -74,7 +75,7 @@ func NewRaftCluster(cfg *types.Consensus, sub []byte) queue.Module {
proposeC := make(chan *types.Block)
confChangeC = make(chan raftpb.ConfChange)
var b *RaftClient
var b *Client
getSnapshot := func() ([]byte, error) { return b.getSnapshot() }
// raft集群的建立,1. 初始化两条channel: propose channel用于客户端和raft底层交互, commit channel用于获取commit消息
// 2. raft集群中的节点之间建立http连接
......@@ -90,9 +91,9 @@ func NewRaftCluster(cfg *types.Consensus, sub []byte) queue.Module {
if len(addPeers) == 1 && addPeers[0] == "" {
addPeers = []string{}
}
commitC, errorC, snapshotterReady, validatorC, stopC := NewRaftNode(int(subcfg.NodeId), subcfg.IsNewJoinNode, peers, readOnlyPeers, addPeers, getSnapshot, proposeC, confChangeC)
commitC, errorC, snapshotterReady, validatorC, stopC := NewRaftNode(int(subcfg.NodeID), subcfg.IsNewJoinNode, peers, readOnlyPeers, addPeers, getSnapshot, proposeC, confChangeC)
//启动raft删除节点操作监听
go serveHttpRaftAPI(int(subcfg.RaftApiPort), confChangeC, errorC)
go serveHTTPRaftAPI(int(subcfg.RaftAPIPort), confChangeC, errorC)
// 监听commit channel,取block
b = NewBlockstore(cfg, <-snapshotterReady, proposeC, commitC, errorC, validatorC, stopC)
return b
......
......@@ -30,7 +30,7 @@ func (h *httpRaftAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}
nodeId, err := strconv.ParseUint(key[1:], 0, 64)
nodeID, err := strconv.ParseUint(key[1:], 0, 64)
if err != nil {
rlog.Error(fmt.Sprintf("Failed to convert ID for conf change (%v)", err.Error()))
http.Error(w, "Failed on POST", http.StatusBadRequest)
......@@ -39,14 +39,14 @@ func (h *httpRaftAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {
cc := raftpb.ConfChange{
Type: raftpb.ConfChangeAddNode,
NodeID: nodeId,
NodeID: nodeID,
Context: url,
}
h.confChangeC <- cc
// As above, optimistic that raft will apply the conf change
w.WriteHeader(http.StatusCreated)
case r.Method == "DELETE":
nodeId, err := strconv.ParseUint(key[1:], 0, 64)
nodeID, err := strconv.ParseUint(key[1:], 0, 64)
if err != nil {
rlog.Error(fmt.Sprintf("Failed to convert ID for conf change (%v)", err.Error()))
http.Error(w, "Failed on DELETE", http.StatusBadRequest)
......@@ -54,7 +54,7 @@ func (h *httpRaftAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
cc := raftpb.ConfChange{
Type: raftpb.ConfChangeRemoveNode,
NodeID: nodeId,
NodeID: nodeID,
}
h.confChangeC <- cc
// As above, optimistic that raft will apply the conf change
......@@ -66,7 +66,7 @@ func (h *httpRaftAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
}
func serveHttpRaftAPI(port int, confChangeC chan<- raftpb.ConfChange, errorC <-chan error) {
func serveHTTPRaftAPI(port int, confChangeC chan<- raftpb.ConfChange, errorC <-chan error) {
srv := http.Server{
Addr: "localhost:" + strconv.Itoa(port),
Handler: &httpRaftAPI{
......
......@@ -64,6 +64,7 @@ type raftNode struct {
restartC chan struct{}
}
// NewRaftNode create raft node
func NewRaftNode(id int, join bool, peers []string, readOnlyPeers []string, addPeers []string, getSnapshot func() ([]byte, error), proposeC <-chan *types.Block,
confChangeC <-chan raftpb.ConfChange) (<-chan *types.Block, <-chan error, <-chan *snap.Snapshotter, <-chan bool, chan<- struct{}) {
......@@ -212,7 +213,7 @@ func (rc *raftNode) serveChannels() {
defer ticker.Stop()
go func() {
var confChangeCount uint64 = 0
var confChangeCount uint64
// 通过propose和proposeConfchange方法往RaftNode发通知
for rc.proposeC != nil && rc.confChangeC != nil {
select {
......@@ -231,7 +232,7 @@ func (rc *raftNode) serveChannels() {
if !ok {
rc.confChangeC = nil
} else {
confChangeCount += 1
confChangeCount++
cc.ID = confChangeCount
rc.node.ProposeConfChange(context.TODO(), cc)
}
......
......@@ -34,8 +34,8 @@ import (
var (
random *rand.Rand
txNumber int = 10
loopCount int = 10
txNumber = 10
loopCount = 10
)
func init() {
......@@ -132,7 +132,7 @@ func sendReplyList(q queue.Queue) {
if msg.Ty == types.EventTxList {
count++
msg.Reply(client.NewMessage("consensus", types.EventReplyTxList,
&types.ReplyTxList{getReplyList(txNumber)}))
&types.ReplyTxList{Txs: getReplyList(txNumber)}))
if count >= loopCount {
time.Sleep(4 * time.Second)
break
......@@ -149,7 +149,7 @@ func prepareTxList() *types.Transaction {
key = generateKey(i, 32)
value = generateValue(i, 180)
nput := &pty.NormAction_Nput{&pty.NormPut{Key: key, Value: []byte(value)}}
nput := &pty.NormAction_Nput{Nput: &pty.NormPut{Key: key, Value: []byte(value)}}
action := &pty.NormAction{Value: nput, Ty: pty.NormActionPut}
tx := &types.Transaction{Execer: []byte("norm"), Payload: types.Encode(action), Fee: 0}
tx.To = address.ExecAddress("norm")
......
......@@ -45,7 +45,7 @@ func main() {
if isIndex {
fmt.Printf("Start dumping log entries from index %s.\n", *index)
walsnap.Index, err = strconv.ParseUint(*index, 10, 64)
walsnap.Index, _ = strconv.ParseUint(*index, 10, 64)
} else {
if *snapfile == "" {
ss := raftsnap.New(snapDir(dataDir))
......@@ -133,6 +133,7 @@ func genIDSlice(a []uint64) []types.ID {
return ids
}
// Block struct
type Block struct {
Version int64 `protobuf:"varint,1,opt,name=version" json:"version,omitempty"`
ParentHash []byte `protobuf:"bytes,2,opt,name=parentHash,proto3" json:"parentHash,omitempty"`
......@@ -144,6 +145,9 @@ type Block struct {
//Txs []*Transaction `protobuf:"bytes,7,rep,name=txs" json:"txs,omitempty"`
}
// Reset method
func (m *Block) Reset() { *m = Block{} }
func (m *Block) String() string { return proto.CompactTextString(m) }
// ProtoMessage method
func (*Block) ProtoMessage() {}
......@@ -98,6 +98,7 @@ func main() {
}
}
// LoadHelp show available commands
func LoadHelp() {
fmt.Println("Available Commands:")
fmt.Println("[ip] transferperf [from, to, amount, txNum, duration] : 转账性能测试")
......@@ -108,6 +109,7 @@ func LoadHelp() {
fmt.Println("[ip] normreadperf [num, interval, duration] : 常规读数据性能测试")
}
// TransferPerf run transfer performance
func TransferPerf(from string, to string, amount string, txNum string, duration string) {
txNumInt, err := strconv.Atoi(txNum)
if err != nil {
......@@ -139,6 +141,7 @@ func TransferPerf(from string, to string, amount string, txNum string, duration
}
}
// SendToAddress run transfer
func SendToAddress(from string, to string, amount string, note string) {
amountFloat64, err := strconv.ParseFloat(amount, 64)
if err != nil {
......@@ -162,6 +165,7 @@ func SendToAddress(from string, to string, amount string, note string) {
fmt.Println(string(data))
}
// NormPerf run norm performance
func NormPerf(size string, num string, interval string, duration string) {
var key string
var value string
......@@ -197,7 +201,7 @@ func NormPerf(size string, num string, interval string, duration string) {
ch := make(chan struct{}, numThread)
for i := 0; i < numThread; i++ {
go func() {
var result int64 = 0
var result int64
totalCount := 0
txCount := 0
_, priv := genaddress()
......@@ -228,7 +232,7 @@ func NormPerf(size string, num string, interval string, duration string) {
}
}
//zzh
// NormReadPerf run read performance
func NormReadPerf(num string, interval string, duration string) {
var numThread int
numInt, err := strconv.Atoi(num)
......@@ -260,7 +264,6 @@ func NormReadPerf(num string, interval string, duration string) {
f, err := os.Open("normperf.log")
if err != nil {
panic("open file failed.")
return
}
buf := bufio.NewReader(f)
cnt := 0
......@@ -277,7 +280,6 @@ func NormReadPerf(num string, interval string, duration string) {
f, err := os.Open("normperf.log")
if err != nil {
panic("open file failed.")
return
}
buf = bufio.NewReader(f)
}
......@@ -315,6 +317,7 @@ func NormReadPerf(num string, interval string, duration string) {
}
}
// RandStringBytes create random string
func RandStringBytes(n int) string {
b := make([]byte, n)
rand.Seed(types.Now().UnixNano())
......@@ -324,9 +327,10 @@ func RandStringBytes(n int) string {
return string(b)
}
// NormPut run put action
func NormPut(privkey string, key string, value string) {
fmt.Println(key, "=", value)
nput := &pty.NormAction_Nput{&pty.NormPut{Key: key, Value: []byte(value)}}
nput := &pty.NormAction_Nput{Nput: &pty.NormPut{Key: key, Value: []byte(value)}}
action := &pty.NormAction{Value: nput, Ty: pty.NormActionPut}
tx := &types.Transaction{Execer: []byte("norm"), Payload: types.Encode(action), Fee: fee}
tx.To = address.ExecAddress("norm")
......@@ -344,6 +348,7 @@ func NormPut(privkey string, key string, value string) {
}
}
// NormGet run query action
func NormGet(key string) {
in := &pty.NormGetKey{Key: key}
data, err := proto.Marshal(in)
......
......@@ -25,25 +25,28 @@ import (
var configPath = flag.String("f", "servers.toml", "configfile")
// ScpInfo struct
type ScpInfo struct {
UserName string
PassWord string
HostIp string
HostIP string
Port int
LocalFilePath string
RemoteDir string
}
// CmdInfo struct
type CmdInfo struct {
userName string
passWord string
hostIp string
hostIP string
port int
cmd string
remoteDir string
}
type tomlConfig struct {
// TomlConfig struct
type TomlConfig struct {
Title string
Servers map[string]ScpInfo
}
......@@ -117,8 +120,9 @@ func sftpconnect(user, password, host string, port int) (*sftp.Client, error) {
return sftpClient, nil
}
// ScpFileFromLocalToRemote copy local file to remote
func ScpFileFromLocalToRemote(si *ScpInfo) {
sftpClient, err := sftpconnect(si.UserName, si.PassWord, si.HostIp, si.Port)
sftpClient, err := sftpconnect(si.UserName, si.PassWord, si.HostIP, si.Port)
if err != nil {
fmt.Println("sftconnect have a err!")
log.Fatal(err)
......@@ -157,9 +161,10 @@ func ScpFileFromLocalToRemote(si *ScpInfo) {
fmt.Println("copy file to remote server finished!")
}
// RemoteExec run cmd in remote
func RemoteExec(cmdInfo *CmdInfo) error {
//A Session only accepts one call to Run, Start or Shell.
session, err := sshconnect(cmdInfo.userName, cmdInfo.passWord, cmdInfo.hostIp, cmdInfo.port)
session, err := sshconnect(cmdInfo.userName, cmdInfo.passWord, cmdInfo.hostIP, cmdInfo.port)
if err != nil {
return err
}
......@@ -180,8 +185,9 @@ func remoteScp(si *ScpInfo, reqnum chan struct{}) {
}
func InitCfg(path string) *tomlConfig {
var cfg tomlConfig
// InitCfg init config
func InitCfg(path string) *TomlConfig {
var cfg TomlConfig
if _, err := tml.DecodeFile(path, &cfg); err != nil {
fmt.Println(err)
os.Exit(0)
......@@ -243,6 +249,7 @@ func main() {
log.Printf("read common cost time %v\n", timeCommon.Sub(start))
}
// LoadHelp show available commands
func LoadHelp() {
fmt.Println("Available Commands:")
fmt.Println(" start : 启动服务 ")
......@@ -250,14 +257,14 @@ func LoadHelp() {
fmt.Println(" clear : 清空数据")
}
func startAll(conf *tomlConfig) {
func startAll(conf *TomlConfig) {
//fmt.Println(getCurrentDirectory())
arrMap := make(map[string]*CmdInfo)
//多协程启动部署
reqC := make(chan struct{}, len(conf.Servers))
for index, sc := range conf.Servers {
cmdInfo := &CmdInfo{}
cmdInfo.hostIp = sc.HostIp
cmdInfo.hostIP = sc.HostIP
cmdInfo.userName = sc.UserName
cmdInfo.port = sc.Port
cmdInfo.passWord = sc.PassWord
......@@ -276,11 +283,11 @@ func startAll(conf *tomlConfig) {
}
}
func stopAll(conf *tomlConfig) {
func stopAll(conf *TomlConfig) {
//执行速度快,不需要多起多协程工作
for _, sc := range conf.Servers {
cmdInfo := &CmdInfo{}
cmdInfo.hostIp = sc.HostIp
cmdInfo.hostIP = sc.HostIP
cmdInfo.userName = sc.UserName
cmdInfo.port = sc.Port
cmdInfo.passWord = sc.PassWord
......@@ -290,10 +297,10 @@ func stopAll(conf *tomlConfig) {
}
}
func clearAll(conf *tomlConfig) {
func clearAll(conf *TomlConfig) {
for _, sc := range conf.Servers {
cmdInfo := &CmdInfo{}
cmdInfo.hostIp = sc.HostIp
cmdInfo.hostIP = sc.HostIP
cmdInfo.userName = sc.UserName
cmdInfo.port = sc.Port
cmdInfo.passWord = sc.PassWord
......
......@@ -36,6 +36,7 @@ func init() {
drivers.QueryData.Register("ticket", &Client{})
}
// Client export ticket client struct
type Client struct {
*drivers.BaseClient
//ticket list for miner
......@@ -57,6 +58,7 @@ type subConfig struct {
Genesis []*genesisTicket `json:"genesis"`
}
// New ticket's init env
func New(cfg *types.Consensus, sub []byte) queue.Module {
c := drivers.NewBaseClient(cfg)
var subcfg subConfig
......@@ -86,12 +88,14 @@ Loop:
}
}
// Close ticket close
func (client *Client) Close() {
close(client.done)
client.BaseClient.Close()
tlog.Info("consensus ticket closed")
}
// CreateGenesisTx ticket create genesis tx
func (client *Client) CreateGenesisTx() (ret []*types.Transaction) {
for _, genesis := range client.subcfg.Genesis {
tx1 := createTicket(genesis.MinerAddr, genesis.ReturnAddr, genesis.Count, 0)
......@@ -119,7 +123,7 @@ func createTicket(minerAddr, returnAddr string, count int32, height int64) (ret
tx2.To = driver.ExecAddress("ticket")
//gen payload
g = &cty.CoinsAction_Genesis{}
g.Genesis = &types.AssetsGenesis{int64(count) * types.GetP(height).TicketPrice, returnAddr}
g.Genesis = &types.AssetsGenesis{Amount: int64(count) * types.GetP(height).TicketPrice, ReturnAddress: returnAddr}
tx2.Payload = types.Encode(&cty.CoinsAction{Value: g, Ty: cty.CoinsActionGenesis})
ret = append(ret, &tx2)
......@@ -127,26 +131,29 @@ func createTicket(minerAddr, returnAddr string, count int32, height int64) (ret
tx3.Execer = []byte("ticket")
tx3.To = driver.ExecAddress("ticket")
gticket := &ty.TicketAction_Genesis{}
gticket.Genesis = &ty.TicketGenesis{minerAddr, returnAddr, count}
gticket.Genesis = &ty.TicketGenesis{MinerAddress: minerAddr, ReturnAddress: returnAddr, Count: count}
tx3.Payload = types.Encode(&ty.TicketAction{Value: gticket, Ty: ty.TicketActionGenesis})
ret = append(ret, &tx3)
return ret
}
// Query_GetTicketCount ticket query ticket count function
func (client *Client) Query_GetTicketCount(req *types.ReqNil) (types.Message, error) {
var ret types.Int64
ret.Data = client.getTicketCount()
return &ret, nil
}
// Query_FlushTicket ticket query flush ticket function
func (client *Client) Query_FlushTicket(req *types.ReqNil) (types.Message, error) {
err := client.flushTicket()
if err != nil {
return nil, err
}
return &types.Reply{true, []byte("OK")}, nil
return &types.Reply{IsOk: true, Msg: []byte("OK")}, nil
}
// ProcEvent ticket reply not support action err
func (client *Client) ProcEvent(msg queue.Message) bool {
msg.ReplyErr("Client", types.ErrActionNotSupport)
return true
......@@ -207,7 +214,7 @@ func (client *Client) flushTicket() error {
tlog.Error("flushTicket error", "err", err)
return err
}
client.setTicket(&ty.ReplyTicketList{tickets}, getPrivMap(privs))
client.setTicket(&ty.ReplyTicketList{Tickets: tickets}, getPrivMap(privs))
return nil
}
......@@ -242,7 +249,7 @@ func (client *Client) getMinerTx(current *types.Block) (*ty.TicketAction, error)
return &ticketAction, nil
}
func (client *Client) getModify(block *types.Block) ([]byte, error) {
func (client *Client) getMinerModify(block *types.Block) ([]byte, error) {
ticketAction, err := client.getMinerTx(block)
if err != nil {
return defaultModify, err
......@@ -250,7 +257,7 @@ func (client *Client) getModify(block *types.Block) ([]byte, error) {
return ticketAction.GetMiner().GetModify(), nil
}
func (client *Client) GetModify(beg, end int64) ([]byte, error) {
func (client *Client) getModify(beg, end int64) ([]byte, error) {
//通过某个区间计算modify
timeSource := int64(0)
total := int64(0)
......@@ -280,6 +287,7 @@ func (client *Client) GetModify(beg, end int64) ([]byte, error) {
return []byte(modify), nil
}
// CheckBlock ticket implete checkblock func
func (client *Client) CheckBlock(parent *types.Block, current *types.BlockDetail) error {
cfg := types.GetP(current.Block.Height)
if current.Block.BlockTime-types.Now().Unix() > cfg.FutureBlockTime {
......@@ -348,7 +356,7 @@ func (client *Client) getNextTarget(block *types.Block, bits uint32) (*big.Int,
powLimit := difficulty.CompactToBig(types.GetP(0).PowLimitBits)
return powLimit, defaultModify, nil
}
targetBits, modify, err := client.GetNextRequiredDifficulty(block, bits)
targetBits, modify, err := client.getNextRequiredDifficulty(block, bits)
if err != nil {
return nil, nil, err
}
......@@ -370,7 +378,7 @@ func (client *Client) getCurrentTarget(blocktime int64, id string, modify []byte
// This function differs from the exported CalcNextRequiredDifficulty in that
// the exported version uses the current best chain as the previous block node
// while this function accepts any block node.
func (client *Client) GetNextRequiredDifficulty(block *types.Block, bits uint32) (uint32, []byte, error) {
func (client *Client) getNextRequiredDifficulty(block *types.Block, bits uint32) (uint32, []byte, error) {
// Genesis block.
if block == nil {
return types.GetP(0).PowLimitBits, defaultModify, nil
......@@ -382,7 +390,7 @@ func (client *Client) GetNextRequiredDifficulty(block *types.Block, bits uint32)
if (block.Height+1) <= blocksPerRetarget || (block.Height+1)%blocksPerRetarget != 0 {
// For the main network (or any unrecognized networks), simply
// return the previous block's difficulty requirements.
modify, err := client.getModify(block)
modify, err := client.getMinerModify(block)
if err != nil {
return bits, defaultModify, err
}
......@@ -399,7 +407,7 @@ func (client *Client) GetNextRequiredDifficulty(block *types.Block, bits uint32)
return cfg.PowLimitBits, defaultModify, types.ErrBlockNotFound
}
modify, err := client.GetModify(block.Height+1-blocksPerRetarget, block.Height)
modify, err := client.getModify(block.Height+1-blocksPerRetarget, block.Height)
if err != nil {
return cfg.PowLimitBits, defaultModify, err
}
......@@ -443,7 +451,7 @@ func (client *Client) GetNextRequiredDifficulty(block *types.Block, bits uint32)
tlog.Info("Timespan", "Actual timespan", time.Duration(actualTimespan)*time.Second,
"adjusted timespan", time.Duration(adjustedTimespan)*time.Second,
"target timespan", cfg.TargetTimespan)
prevmodify, err := client.getModify(block)
prevmodify, err := client.getMinerModify(block)
if err != nil {
panic(err)
}
......@@ -511,6 +519,7 @@ func (client *Client) delTicket(ticket *ty.Ticket, index int) {
}
}
// Miner ticket miner function
func (client *Client) Miner(parent, block *types.Block) bool {
//add miner address
ticket, priv, diff, modify, index, err := client.searchTargetTicket(parent, block)
......@@ -577,7 +586,7 @@ func (client *Client) addMinerTx(parent, block *types.Block, diff *big.Int, priv
return err
}
miner.PrivHash = privHash
ticketAction.Value = &ty.TicketAction_Miner{miner}
ticketAction.Value = &ty.TicketAction_Miner{Miner: miner}
ticketAction.Ty = ty.TicketActionMiner
//构造transaction
tx := client.createMinerTx(&ticketAction, priv)
......@@ -648,6 +657,7 @@ func (client *Client) updateBlock(newblock *types.Block, txHashList [][]byte) (*
return lastBlock, txHashList
}
// CreateBlock ticket create block func
func (client *Client) CreateBlock() {
for {
if !client.IsMining() || !(client.IsCaughtUp() || client.Cfg.ForceMining) {
......
......@@ -19,43 +19,47 @@ import (
)
const (
ECDSA_RPIVATEKEY_LENGTH = 32
ECDSA_PUBLICKEY_LENGTH = 65
privateKeyECDSALength = 32
publicKeyECDSALength = 65
)
// Driver driver
type Driver struct{}
// Ctypto
// GenKey create private key
func (d Driver) GenKey() (crypto.PrivKey, error) {
privKeyBytes := [ECDSA_RPIVATEKEY_LENGTH]byte{}
copy(privKeyBytes[:], crypto.CRandBytes(ECDSA_RPIVATEKEY_LENGTH))
privKeyBytes := [privateKeyECDSALength]byte{}
copy(privKeyBytes[:], crypto.CRandBytes(privateKeyECDSALength))
priv, _ := privKeyFromBytes(elliptic.P256(), privKeyBytes[:])
copy(privKeyBytes[:], SerializePrivateKey(priv))
return PrivKeyECDSA(privKeyBytes), nil
}
// PrivKeyFromBytes create private key from bytes
func (d Driver) PrivKeyFromBytes(b []byte) (privKey crypto.PrivKey, err error) {
if len(b) != ECDSA_RPIVATEKEY_LENGTH {
if len(b) != privateKeyECDSALength {
return nil, errors.New("invalid priv key byte")
}
privKeyBytes := new([ECDSA_RPIVATEKEY_LENGTH]byte)
copy(privKeyBytes[:], b[:ECDSA_RPIVATEKEY_LENGTH])
privKeyBytes := new([privateKeyECDSALength]byte)
copy(privKeyBytes[:], b[:privateKeyECDSALength])
priv, _ := privKeyFromBytes(elliptic.P256(), privKeyBytes[:])
copy(privKeyBytes[:], SerializePrivateKey(priv))
return PrivKeyECDSA(*privKeyBytes), nil
}
// PubKeyFromBytes create public key from bytes
func (d Driver) PubKeyFromBytes(b []byte) (pubKey crypto.PubKey, err error) {
if len(b) != ECDSA_PUBLICKEY_LENGTH {
if len(b) != publicKeyECDSALength {
return nil, errors.New("invalid pub key byte")
}
pubKeyBytes := new([ECDSA_PUBLICKEY_LENGTH]byte)
pubKeyBytes := new([publicKeyECDSALength]byte)
copy(pubKeyBytes[:], b[:])
return PubKeyECDSA(*pubKeyBytes), nil
}
// SignatureFromBytes create signature from bytes
func (d Driver) SignatureFromBytes(b []byte) (sig crypto.Signature, err error) {
var certSignature crypto.CertSignature
_, err = asn1.Unmarshal(b, &certSignature)
......@@ -70,15 +74,17 @@ func (d Driver) SignatureFromBytes(b []byte) (sig crypto.Signature, err error) {
return SignatureECDSA(certSignature.Signature), nil
}
// PrivKey
type PrivKeyECDSA [ECDSA_RPIVATEKEY_LENGTH]byte
// PrivKeyECDSA PrivKey
type PrivKeyECDSA [privateKeyECDSALength]byte
// Bytes convert to bytes
func (privKey PrivKeyECDSA) Bytes() []byte {
s := make([]byte, ECDSA_RPIVATEKEY_LENGTH)
s := make([]byte, privateKeyECDSALength)
copy(s, privKey[:])
return s
}
// Sign create signature
func (privKey PrivKeyECDSA) Sign(msg []byte) crypto.Signature {
priv, pub := privKeyFromBytes(elliptic.P256(), privKey[:])
r, s, err := ecdsa.Sign(rand.Reader, priv, crypto.Sha256(msg))
......@@ -91,6 +97,7 @@ func (privKey PrivKeyECDSA) Sign(msg []byte) crypto.Signature {
return SignatureECDSA(ecdsaSigByte)
}
// PubKey convert to public key
func (privKey PrivKeyECDSA) PubKey() crypto.PubKey {
_, pub := privKeyFromBytes(elliptic.P256(), privKey[:])
var pubECDSA PubKeyECDSA
......@@ -98,6 +105,7 @@ func (privKey PrivKeyECDSA) PubKey() crypto.PubKey {
return pubECDSA
}
// Equals check privkey is equal
func (privKey PrivKeyECDSA) Equals(other crypto.PrivKey) bool {
if otherSecp, ok := other.(PrivKeyECDSA); ok {
return bytes.Equal(privKey[:], otherSecp[:])
......@@ -106,20 +114,23 @@ func (privKey PrivKeyECDSA) Equals(other crypto.PrivKey) bool {
return false
}
// String convert to string
func (privKey PrivKeyECDSA) String() string {
return fmt.Sprintf("PrivKeyECDSA{*****}")
}
// PubKey
// PubKeyECDSA PubKey
// prefixed with 0x02 or 0x03, depending on the y-cord.
type PubKeyECDSA [ECDSA_PUBLICKEY_LENGTH]byte
type PubKeyECDSA [publicKeyECDSALength]byte
// Bytes convert to bytes
func (pubKey PubKeyECDSA) Bytes() []byte {
s := make([]byte, ECDSA_PUBLICKEY_LENGTH)
s := make([]byte, publicKeyECDSALength)
copy(s, pubKey[:])
return s
}
// VerifyBytes verify signature
func (pubKey PubKeyECDSA) VerifyBytes(msg []byte, sig crypto.Signature) bool {
// unwrap if needed
if wrap, ok := sig.(SignatureS); ok {
......@@ -148,43 +159,48 @@ func (pubKey PubKeyECDSA) VerifyBytes(msg []byte, sig crypto.Signature) bool {
return ecdsa.Verify(pub, crypto.Sha256(msg), r, s)
}
// String convert to string
func (pubKey PubKeyECDSA) String() string {
return fmt.Sprintf("PubKeyECDSA{%X}", pubKey[:])
}
// Must return the full bytes in hex.
// KeyString Must return the full bytes in hex.
// Used for map keying, etc.
func (pubKey PubKeyECDSA) KeyString() string {
return fmt.Sprintf("%X", pubKey[:])
}
// Equals check public key is equal
func (pubKey PubKeyECDSA) Equals(other crypto.PubKey) bool {
if otherSecp, ok := other.(PubKeyECDSA); ok {
return bytes.Equal(pubKey[:], otherSecp[:])
} else {
return false
}
return false
}
type ECDSASignature struct {
type signatureECDSA struct {
R, S *big.Int
}
// Signature
// SignatureECDSA Signature
type SignatureECDSA []byte
// SignatureS signature struct
type SignatureS struct {
crypto.Signature
}
// Bytes convert signature to bytes
func (sig SignatureECDSA) Bytes() []byte {
s := make([]byte, len(sig))
copy(s, sig[:])
return s
}
// IsZero check signature is zero
func (sig SignatureECDSA) IsZero() bool { return len(sig) == 0 }
// String convert signature to string
func (sig SignatureECDSA) String() string {
fingerprint := make([]byte, len(sig[:]))
copy(fingerprint, sig[:])
......@@ -192,6 +208,7 @@ func (sig SignatureECDSA) String() string {
}
// Equals check signature equals
func (sig SignatureECDSA) Equals(other crypto.Signature) bool {
if otherEd, ok := other.(SignatureECDSA); ok {
return bytes.Equal(sig[:], otherEd[:])
......@@ -199,7 +216,10 @@ func (sig SignatureECDSA) Equals(other crypto.Signature) bool {
return false
}
// Name name
const Name = "auth_ecdsa"
// ID id
const ID = 257
func init() {
......
......@@ -13,12 +13,14 @@ import (
"math/big"
)
// MarshalECDSASignature marshal ECDSA signature
func MarshalECDSASignature(r, s *big.Int) ([]byte, error) {
return asn1.Marshal(ECDSASignature{r, s})
return asn1.Marshal(signatureECDSA{r, s})
}
// UnmarshalECDSASignature unmarshal ECDSA signature
func UnmarshalECDSASignature(raw []byte) (*big.Int, *big.Int, error) {
sig := new(ECDSASignature)
sig := new(signatureECDSA)
_, err := asn1.Unmarshal(raw, sig)
if err != nil {
return nil, nil, fmt.Errorf("failed unmashalling signature [%s]", err)
......@@ -41,6 +43,7 @@ func UnmarshalECDSASignature(raw []byte) (*big.Int, *big.Int, error) {
return sig.R, sig.S, nil
}
// ToLowS convert to low int
func ToLowS(k *ecdsa.PublicKey, s *big.Int) *big.Int {
lowS := IsLowS(s)
if !lowS {
......@@ -52,6 +55,7 @@ func ToLowS(k *ecdsa.PublicKey, s *big.Int) *big.Int {
return s
}
// IsLowS check is low int
func IsLowS(s *big.Int) bool {
return s.Cmp(new(big.Int).Rsh(elliptic.P256().Params().N, 1)) != 1
}
......@@ -78,16 +82,18 @@ func parsePubKey(pubKeyStr []byte, curve elliptic.Curve) (key *ecdsa.PublicKey,
return &pubkey, nil
}
// SerializePublicKey serialize public key
func SerializePublicKey(p *ecdsa.PublicKey) []byte {
b := make([]byte, 0, ECDSA_PUBLICKEY_LENGTH)
b := make([]byte, 0, publicKeyECDSALength)
b = append(b, 0x4)
b = paddedAppend(32, b, p.X.Bytes())
return paddedAppend(32, b, p.Y.Bytes())
}
// SerializePrivateKey serialize private key
func SerializePrivateKey(p *ecdsa.PrivateKey) []byte {
b := make([]byte, 0, ECDSA_RPIVATEKEY_LENGTH)
return paddedAppend(ECDSA_RPIVATEKEY_LENGTH, b, p.D.Bytes())
b := make([]byte, 0, privateKeyECDSALength)
return paddedAppend(privateKeyECDSALength, b, p.D.Bytes())
}
func paddedAppend(size uint, dst, src []byte) []byte {
......
......@@ -13,10 +13,10 @@ type sm2Driver struct {
sm2.Driver
}
const Name = "auth_sm2"
const ID = 258
const name = "auth_sm2"
const id = 258
func init() {
crypto.Register(Name, &sm2Driver{})
crypto.RegisterType(Name, ID)
crypto.Register(name, &sm2Driver{})
crypto.RegisterType(name, id)
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: blackwhite.proto
......
......@@ -23,12 +23,19 @@ import (
var (
alog = log.New("module", "authority")
OrgName = "Chain33"
cpuNum = runtime.NumCPU()
// OrgName 默认证书组织名
OrgName = "Chain33"
// Author 全局证书校验器
Author = &Authority{}
// IsAuthEnable 是否开启全局校验开关
IsAuthEnable = false
)
// Authority 证书校验器主要结构
type Authority struct {
// 证书文件路径
cryptoPath string
......@@ -44,16 +51,14 @@ type Authority struct {
HistoryCertCache *HistoryCertData
}
/** 历史变更记录 **/
// HistoryCertData 历史变更记录
type HistoryCertData struct {
CryptoCfg *core.AuthConfig
CurHeight int64
NxtHeight int64
}
/**
初始化auth
*/
// Init 初始化auth
func (auth *Authority) Init(conf *ty.Authority) error {
if conf == nil || !conf.Enable {
return nil
......@@ -93,9 +98,7 @@ func (auth *Authority) Init(conf *ty.Authority) error {
return nil
}
/**
store数据转成authConfig数据
*/
// newAuthConfig store数据转成authConfig数据
func newAuthConfig(store *types.HistoryCertStore) *core.AuthConfig {
ret := &core.AuthConfig{}
ret.RootCerts = make([][]byte, len(store.Rootcerts))
......@@ -116,9 +119,7 @@ func newAuthConfig(store *types.HistoryCertStore) *core.AuthConfig {
return ret
}
/**
从数据库中的记录数据恢复证书,用于证书回滚
*/
// ReloadCert 从数据库中的记录数据恢复证书,用于证书回滚
func (auth *Authority) ReloadCert(store *types.HistoryCertStore) error {
if !IsAuthEnable {
return nil
......@@ -147,9 +148,7 @@ func (auth *Authority) ReloadCert(store *types.HistoryCertStore) error {
return nil
}
/**
从新的authdir下的文件更新证书,用于证书更新
*/
// ReloadCertByHeght 从新的authdir下的文件更新证书,用于证书更新
func (auth *Authority) ReloadCertByHeght(currentHeight int64) error {
if !IsAuthEnable {
return nil
......@@ -178,9 +177,7 @@ func (auth *Authority) ReloadCertByHeght(currentHeight int64) error {
return nil
}
/**
并发校验证书
*/
// ValidateCerts 并发校验证书
func (auth *Authority) ValidateCerts(task []*types.Signature) bool {
//FIXME 有并发校验的场景需要考虑竞争,暂时没有并发校验的场景
done := make(chan struct{})
......@@ -242,9 +239,7 @@ func (auth *Authority) task(done <-chan struct{}, taskes <-chan *types.Signature
}
}
/**
检验证书
*/
// Validate 检验证书
func (auth *Authority) Validate(signature *types.Signature) error {
// 从proto中解码signature
cert, err := auth.validator.GetCertFromSignature(signature.Signature)
......@@ -270,9 +265,7 @@ func (auth *Authority) Validate(signature *types.Signature) error {
return nil
}
/**
历史数据转成store可存储的历史数据
*/
// ToHistoryCertStore 历史数据转成store可存储的历史数据
func (certdata *HistoryCertData) ToHistoryCertStore(store *types.HistoryCertStore) {
if store == nil {
alog.Error("Convert cert data to cert store failed")
......@@ -298,19 +291,21 @@ func (certdata *HistoryCertData) ToHistoryCertStore(store *types.HistoryCertStor
store.NxtHeight = certdata.NxtHeight
}
// User 用户关联的证书私钥信息
type User struct {
Id string
ID string
Cert []byte
Key crypto.PrivKey
}
//userloader, SKD加载user使用
// UserLoader SKD加载user使用
type UserLoader struct {
configPath string
userMap map[string]*User
signType int
}
// Init userloader初始化
func (loader *UserLoader) Init(configPath string, signType string) error {
loader.configPath = configPath
loader.userMap = make(map[string]*User)
......@@ -381,9 +376,10 @@ func (loader *UserLoader) genCryptoPriv(keyBytes []byte) (crypto.PrivKey, error)
return priv, nil
}
func (load *UserLoader) Get(userName string) (*User, error) {
// Get 根据用户名获取user结构
func (loader *UserLoader) Get(userName string) (*User, error) {
keyvalue := fmt.Sprintf("%s@%s-cert.pem", userName, OrgName)
user, ok := load.userMap[keyvalue]
user, ok := loader.userMap[keyvalue]
if !ok {
return nil, types.ErrInvalidParam
}
......
......@@ -42,7 +42,7 @@ var (
txs = []*types.Transaction{tx1, tx2, tx3, tx4, tx5, tx6, tx7, tx8, tx9, tx10, tx11, tx12}
privRaw, _ = common.FromHex("CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944")
tr = &cty.CoinsAction_Transfer{&types.AssetsTransfer{Amount: int64(1e8)}}
tr = &cty.CoinsAction_Transfer{Transfer: &types.AssetsTransfer{Amount: int64(1e8)}}
secpp256, _ = crypto.New(types.GetSignName("", types.SECP256K1))
privKey, _ = secpp256.PrivKeyFromBytes(privRaw)
tx14 = &types.Transaction{
......@@ -55,7 +55,7 @@ var (
)
var USERNAME = "User"
var SIGNTYPE = ct.AUTH_SM2
var SIGNTYPE = ct.AuthSM2
func signtx(tx *types.Transaction, priv crypto.PrivKey, cert []byte) {
tx.Sign(int32(SIGNTYPE), priv)
......@@ -197,7 +197,7 @@ func TestChckSignWithNoneAuth(t *testing.T) {
TestCase04 不带证书,SM2签名验证
*/
func TestChckSignWithSm2(t *testing.T) {
sm2, err := crypto.New(types.GetSignName("cert", ct.AUTH_SM2))
sm2, err := crypto.New(types.GetSignName("cert", ct.AuthSM2))
assert.Nil(t, err)
privKeysm2, _ := sm2.PrivKeyFromBytes(privRaw)
tx15 := &types.Transaction{Execer: []byte("coins"),
......@@ -213,7 +213,7 @@ func TestChckSignWithSm2(t *testing.T) {
types.SetMinFee(0)
defer types.SetMinFee(prev)
tx15.Sign(ct.AUTH_SM2, privKeysm2)
tx15.Sign(ct.AuthSM2, privKeysm2)
if !tx15.CheckSign() {
t.Error("check signature failed")
return
......@@ -224,7 +224,7 @@ func TestChckSignWithSm2(t *testing.T) {
TestCase05 不带证书,secp256r1签名验证
*/
func TestChckSignWithEcdsa(t *testing.T) {
ecdsacrypto, _ := crypto.New(types.GetSignName("cert", ct.AUTH_ECDSA))
ecdsacrypto, _ := crypto.New(types.GetSignName("cert", ct.AuthECDSA))
privKeyecdsa, _ := ecdsacrypto.PrivKeyFromBytes(privRaw)
tx16 := &types.Transaction{Execer: []byte("coins"),
Payload: types.Encode(&cty.CoinsAction{Value: tr, Ty: cty.CoinsActionTransfer}),
......@@ -239,7 +239,7 @@ func TestChckSignWithEcdsa(t *testing.T) {
types.SetMinFee(0)
defer types.SetMinFee(prev)
tx16.Sign(ct.AUTH_ECDSA, privKeyecdsa)
tx16.Sign(ct.AuthECDSA, privKeyecdsa)
if !tx16.CheckSign() {
t.Error("check signature failed")
return
......
......@@ -44,8 +44,8 @@ type tbsCertificate struct {
Validity validity
Subject asn1.RawValue
PublicKey publicKeyInfo
UniqueId asn1.BitString `asn1:"optional,tag:1"`
SubjectUniqueId asn1.BitString `asn1:"optional,tag:2"`
UniqueID asn1.BitString `asn1:"optional,tag:1"`
SubjectUniqueID asn1.BitString `asn1:"optional,tag:2"`
Extensions []pkix.Extension `asn1:"optional,explicit,tag:3"`
}
......@@ -58,10 +58,10 @@ func isECDSASignedCert(cert *x509.Certificate) bool {
func sanitizeECDSASignedCert(cert *x509.Certificate, parentCert *x509.Certificate) (*x509.Certificate, error) {
if cert == nil {
return nil, errors.New("Certificate must be different from nil.")
return nil, errors.New("Certificate must be different from nil")
}
if parentCert == nil {
return nil, errors.New("Parent certificate must be different from nil.")
return nil, errors.New("Parent certificate must be different from nil")
}
expectedSig, err := signatureToLowS(parentCert.PublicKey.(*ecdsa.PublicKey), cert.Signature)
......@@ -109,11 +109,12 @@ func certFromX509Cert(cert *x509.Certificate) (certificate, error) {
return newCert, nil
}
// ParseECDSAPubKey2SM2PubKey 将ECDSA的公钥转成SM2公钥
func ParseECDSAPubKey2SM2PubKey(key *ecdsa.PublicKey) *sm2.PublicKey {
sm2Key := &sm2.PublicKey{
key.Curve,
key.X,
key.Y,
Curve: key.Curve,
X: key.X,
Y: key.Y,
}
return sm2Key
......
......@@ -54,6 +54,7 @@ const (
crlsfolder = "crls"
)
// GetAuthConfig 获取证书文件配置
func GetAuthConfig(dir string) (*AuthConfig, error) {
cacertDir := filepath.Join(dir, cacerts)
intermediatecertsDir := filepath.Join(dir, intermediatecerts)
......
......@@ -38,6 +38,7 @@ type ecdsaValidator struct {
CRL []*pkix.CertificateList
}
// NewEcdsaValidator 创建ecdsa校验器
func NewEcdsaValidator() Validator {
return &ecdsaValidator{}
}
......@@ -148,7 +149,7 @@ func (validator *ecdsaValidator) Validate(certByte []byte, pubKey []byte) error
}
if !bytes.Equal(pubKey, ecdsa_util.SerializePublicKey(certPubKey)) {
return fmt.Errorf("Invalid public key.")
return fmt.Errorf("Invalid public key")
}
cert, err = validator.sanitizeCert(cert)
......@@ -212,7 +213,7 @@ func (validator *ecdsaValidator) getValidationChain(cert *x509.Certificate, isIn
parentPosition = 0
}
if validator.certificationTreeInternalNodesMap[string(validationChain[parentPosition].Raw)] {
return nil, fmt.Errorf("Invalid validation chain. Parent certificate should be a leaf of the certification tree [%v].", cert.Raw)
return nil, fmt.Errorf("Invalid validation chain. Parent certificate should be a leaf of the certification tree [%v]", cert.Raw)
}
return validationChain, nil
}
......@@ -403,7 +404,7 @@ func (validator *ecdsaValidator) getValidityOptsForCert(cert *x509.Certificate)
return tempOpts
}
func (Validator *ecdsaValidator) GetCertFromSignature(signature []byte) ([]byte, error) {
func (validator *ecdsaValidator) GetCertFromSignature(signature []byte) ([]byte, error) {
cert, _, err := utils.DecodeCertFromSignature(signature)
if err != nil {
authLogger.Error(fmt.Sprintf("unmashal certificate from signature failed. %s", err.Error()))
......
......@@ -10,13 +10,14 @@ import (
ty "github.com/33cn/plugin/plugin/dapp/cert/types"
)
// GetLocalValidator 根据类型获取校验器
func GetLocalValidator(authConfig *AuthConfig, signType int) (Validator, error) {
var lclValidator Validator
var err error
if signType == ty.AUTH_ECDSA {
if signType == ty.AuthECDSA {
lclValidator = NewEcdsaValidator()
} else if signType == ty.AUTH_SM2 {
} else if signType == ty.AuthSM2 {
lclValidator = NewGmValidator()
} else {
return nil, ty.ErrUnknowAuthSignType
......
......@@ -33,6 +33,7 @@ type gmValidator struct {
CRL []*pkix.CertificateList
}
// NewGmValidator 创建国密证书校验器
func NewGmValidator() Validator {
return &gmValidator{}
}
......@@ -90,7 +91,7 @@ func (validator *gmValidator) Validate(certByte []byte, pubKey []byte) error {
}
if !bytes.Equal(pubKey, sm2_util.SerializePublicKey(ParseECDSAPubKey2SM2PubKey(certPubKey))) {
return fmt.Errorf("Invalid public key.")
return fmt.Errorf("Invalid public key")
}
validationChain, err := validator.getCertificationChain(cert)
......@@ -150,7 +151,7 @@ func (validator *gmValidator) getValidationChain(cert *sm2.Certificate, isInterm
parentPosition = 0
}
if validator.certificationTreeInternalNodesMap[string(validationChain[parentPosition].Raw)] {
return nil, fmt.Errorf("Invalid validation chain. Parent certificate should be a leaf of the certification tree [%v].", cert.Raw)
return nil, fmt.Errorf("Invalid validation chain. Parent certificate should be a leaf of the certification tree [%v]", cert.Raw)
}
return validationChain, nil
}
......@@ -335,7 +336,7 @@ func (validator *gmValidator) getValidityOptsForCert(cert *sm2.Certificate) sm2.
return tempOpts
}
func (Validator *gmValidator) GetCertFromSignature(signature []byte) ([]byte, error) {
func (validator *gmValidator) GetCertFromSignature(signature []byte) ([]byte, error) {
// 从proto中解码signature
cert, _, err := utils.DecodeCertFromSignature(signature)
if err != nil {
......
......@@ -7,6 +7,7 @@ package core
type noneValidator struct {
}
// NewNoneValidator 创建none校验器
func NewNoneValidator() (Validator, error) {
return &noneValidator{}, nil
}
......@@ -19,6 +20,6 @@ func (validator *noneValidator) Validate(certByte []byte, pubKey []byte) error {
return nil
}
func (Validator *noneValidator) GetCertFromSignature(signature []byte) ([]byte, error) {
func (validator *noneValidator) GetCertFromSignature(signature []byte) ([]byte, error) {
return []byte(""), nil
}
......@@ -4,6 +4,7 @@
package core
// Validator 证书校验器
type Validator interface {
Setup(config *AuthConfig) error
......@@ -12,6 +13,7 @@ type Validator interface {
GetCertFromSignature(signature []byte) ([]byte, error)
}
// AuthConfig 校验器配置
type AuthConfig struct {
RootCerts [][]byte
IntermediateCerts [][]byte
......
......@@ -17,12 +17,17 @@ import (
)
const (
// CANAME 默认CA名称
CANAME = "ca"
// CONFIGFILENAME 配置文件名
CONFIGFILENAME = "chain33.cryptogen.toml"
// OUTPUTDIR 证书文件输出路径
OUTPUTDIR = "./authdir/crypto"
// ORGNAME 默认组织名
ORGNAME = "Chain33"
)
// Config 证书生成工具配置
type Config struct {
Name []string
SignType string
......
......@@ -7,10 +7,13 @@ package csp
import "crypto"
const (
// ECDSAP256KeyGen ECDSA类型
ECDSAP256KeyGen = 1
// SM2P256KygGen SM2类型
SM2P256KygGen = 2
)
// Key 通用key接口
type Key interface {
Bytes() ([]byte, error)
SKI() []byte
......@@ -19,25 +22,30 @@ type Key interface {
PublicKey() (Key, error)
}
// SignerOpts 签名器参数接口
type SignerOpts interface {
crypto.SignerOpts
}
// CSP 证书生成器接口
type CSP interface {
KeyGen(opts int) (k Key, err error)
Sign(k Key, digest []byte, opts SignerOpts) (signature []byte, err error)
}
// KeyStore key存储接口
type KeyStore interface {
ReadOnly() bool
StoreKey(k Key) (err error)
}
// Signer 签名器接口
type Signer interface {
Sign(k Key, digest []byte, opts SignerOpts) (signature []byte, err error)
}
// KeyGenerator key生成器接口
type KeyGenerator interface {
KeyGen(opts int) (k Key, err error)
}
......@@ -11,6 +11,7 @@ import (
"github.com/pkg/errors"
)
// New 创建新的证书生成结构
func New(keyStore KeyStore) (CSP, error) {
signers := make(map[reflect.Type]Signer)
signers[reflect.TypeOf(&ecdsaPrivateKey{})] = &ecdsaSigner{}
......@@ -58,10 +59,10 @@ func (csp *cspimpl) KeyGen(opts int) (k Key, err error) {
func (csp *cspimpl) Sign(k Key, digest []byte, opts SignerOpts) (signature []byte, err error) {
if k == nil {
return nil, errors.New("Invalid Key. It must not be nil.")
return nil, errors.New("Invalid Key. It must not be nil")
}
if len(digest) == 0 {
return nil, errors.New("Invalid digest. Cannot be empty.")
return nil, errors.New("Invalid digest. Cannot be empty")
}
keyType := reflect.TypeOf(k)
......
......@@ -32,10 +32,12 @@ func signECDSA(k *ecdsa.PrivateKey, digest []byte, opts SignerOpts) (signature [
return MarshalECDSASignature(r, s)
}
// ECDSASignature ECDSA签名结构
type ECDSASignature struct {
R, S *big.Int
}
// MarshalECDSASignature 编码ECDSA类型签名
func MarshalECDSASignature(r, s *big.Int) ([]byte, error) {
return asn1.Marshal(ECDSASignature{r, s})
}
......
......@@ -18,7 +18,7 @@ type ecdsaPrivateKey struct {
}
func (k *ecdsaPrivateKey) Bytes() (raw []byte, err error) {
return nil, errors.New("Not supported.")
return nil, errors.New("Not supported")
}
func (k *ecdsaPrivateKey) SKI() (ski []byte) {
......
......@@ -22,6 +22,7 @@ import (
var logger = log.New("tools", "cryptogen")
// NewFileBasedKeyStore 创建key存储器
func NewFileBasedKeyStore(pwd []byte, path string, readOnly bool) (KeyStore, error) {
ks := &fileBasedKeyStore{}
return ks, ks.Init(pwd, path, readOnly)
......@@ -40,14 +41,14 @@ type fileBasedKeyStore struct {
func (ks *fileBasedKeyStore) Init(pwd []byte, path string, readOnly bool) error {
if len(path) == 0 {
return errors.New("An invalid KeyStore path provided. Path cannot be an empty string.")
return errors.New("An invalid KeyStore path provided. Path cannot be an empty string")
}
ks.m.Lock()
defer ks.m.Unlock()
if ks.isOpen {
return errors.New("KeyStore already initilized.")
return errors.New("KeyStore already initilized")
}
ks.path = path
......@@ -74,11 +75,11 @@ func (ks *fileBasedKeyStore) ReadOnly() bool {
func (ks *fileBasedKeyStore) StoreKey(k Key) (err error) {
if ks.readOnly {
return errors.New("Read only KeyStore.")
return errors.New("Read only KeyStore")
}
if k == nil {
return errors.New("Invalid key. It must be different from nil.")
return errors.New("Invalid key. It must be different from nil")
}
switch k.(type) {
case *ecdsaPrivateKey:
......
......@@ -27,10 +27,12 @@ func signSM2(k *sm2.PrivateKey, digest []byte, opts SignerOpts) (signature []byt
return MarshalSM2Signature(r, s)
}
// SM2Signature SM2签名结构
type SM2Signature struct {
R, S *big.Int
}
// MarshalSM2Signature 编码SM2起签名
func MarshalSM2Signature(r, s *big.Int) ([]byte, error) {
return asn1.Marshal(SM2Signature{r, s})
}
......
......@@ -13,14 +13,17 @@ import (
"github.com/tjfoc/gmsm/sm2"
)
// SM2PrivateKey sm2私钥结构
type SM2PrivateKey struct {
PrivKey *sm2.PrivateKey
}
// Bytes sm2私钥转成byte
func (k *SM2PrivateKey) Bytes() (raw []byte, err error) {
return nil, errors.New("Not supported.")
return nil, errors.New("Not supported")
}
// SKI sm2私钥ski
func (k *SM2PrivateKey) SKI() (ski []byte) {
if k.PrivKey == nil {
return nil
......@@ -33,22 +36,27 @@ func (k *SM2PrivateKey) SKI() (ski []byte) {
return hash.Sum(nil)
}
// Symmetric sm2私钥Symmetric
func (k *SM2PrivateKey) Symmetric() bool {
return false
}
// Private sm2私钥
func (k *SM2PrivateKey) Private() bool {
return true
}
// PublicKey sm2私钥对应公钥
func (k *SM2PrivateKey) PublicKey() (Key, error) {
return &SM2PublicKey{&k.PrivKey.PublicKey}, nil
}
// SM2PublicKey sm2公钥结构
type SM2PublicKey struct {
PubKey *sm2.PublicKey
}
// Bytes sm2公钥转成byte
func (k *SM2PublicKey) Bytes() (raw []byte, err error) {
raw, err = sm2.MarshalSm2PublicKey(k.PubKey)
if err != nil {
......@@ -57,6 +65,7 @@ func (k *SM2PublicKey) Bytes() (raw []byte, err error) {
return
}
// SKI sm2公钥ski
func (k *SM2PublicKey) SKI() (ski []byte) {
if k.PubKey == nil {
return nil
......@@ -69,14 +78,17 @@ func (k *SM2PublicKey) SKI() (ski []byte) {
return hash.Sum(nil)
}
// Symmetric sm2公钥Symmetric
func (k *SM2PublicKey) Symmetric() bool {
return false
}
// Private 是否sm2私钥
func (k *SM2PublicKey) Private() bool {
return false
}
// PublicKey sm2公钥
func (k *SM2PublicKey) PublicKey() (Key, error) {
return k, nil
}
......@@ -20,15 +20,16 @@ type cspCryptoSigner struct {
pk interface{}
}
// New 创建签名器
func New(csp lccsp.CSP, key lccsp.Key) (crypto.Signer, error) {
if csp == nil {
return nil, errors.New("bccsp instance must be different from nil.")
return nil, errors.New("bccsp instance must be different from nil")
}
if key == nil {
return nil, errors.New("key must be different from nil.")
return nil, errors.New("key must be different from nil")
}
if key.Symmetric() {
return nil, errors.New("key must be asymmetric.")
return nil, errors.New("key must be asymmetric")
}
pub, err := key.PublicKey()
......
......@@ -44,18 +44,19 @@ func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) {
return nil, false
}
// PrivateKeyToPEM 私钥转pem
func PrivateKeyToPEM(privateKey interface{}, pwd []byte) ([]byte, error) {
if len(pwd) != 0 {
return privateKeyToEncryptedPEM(privateKey, pwd)
}
if privateKey == nil {
return nil, errors.New("Invalid key. It must be different from nil.")
return nil, errors.New("Invalid key. It must be different from nil")
}
switch k := privateKey.(type) {
case *ecdsa.PrivateKey:
if k == nil {
return nil, errors.New("Invalid ecdsa private key. It must be different from nil.")
return nil, errors.New("Invalid ecdsa private key. It must be different from nil")
}
oidNamedCurve, ok := oidFromNamedCurve(k.Curve)
......@@ -95,7 +96,7 @@ func PrivateKeyToPEM(privateKey interface{}, pwd []byte) ([]byte, error) {
), nil
case *sm2.PrivateKey:
if k == nil {
return nil, errors.New("Invalid sm2 private key. It must be different from nil.")
return nil, errors.New("Invalid sm2 private key. It must be different from nil")
}
return sm2.WritePrivateKeytoMem(k, nil)
default:
......@@ -105,13 +106,13 @@ func PrivateKeyToPEM(privateKey interface{}, pwd []byte) ([]byte, error) {
func privateKeyToEncryptedPEM(privateKey interface{}, pwd []byte) ([]byte, error) {
if privateKey == nil {
return nil, errors.New("Invalid private key. It must be different from nil.")
return nil, errors.New("Invalid private key. It must be different from nil")
}
switch k := privateKey.(type) {
case *ecdsa.PrivateKey:
if k == nil {
return nil, errors.New("Invalid ecdsa private key. It must be different from nil.")
return nil, errors.New("Invalid ecdsa private key. It must be different from nil")
}
raw, err := x509.MarshalECPrivateKey(k)
......@@ -137,19 +138,20 @@ func privateKeyToEncryptedPEM(privateKey interface{}, pwd []byte) ([]byte, error
}
}
// PublicKeyToPEM 公钥转pem
func PublicKeyToPEM(publicKey interface{}, pwd []byte) ([]byte, error) {
if len(pwd) != 0 {
return publicKeyToEncryptedPEM(publicKey, pwd)
}
if publicKey == nil {
return nil, errors.New("Invalid public key. It must be different from nil.")
return nil, errors.New("Invalid public key. It must be different from nil")
}
switch k := publicKey.(type) {
case *ecdsa.PublicKey:
if k == nil {
return nil, errors.New("Invalid ecdsa public key. It must be different from nil.")
return nil, errors.New("Invalid ecdsa public key. It must be different from nil")
}
PubASN1, err := x509.MarshalPKIXPublicKey(k)
if err != nil {
......@@ -164,7 +166,7 @@ func PublicKeyToPEM(publicKey interface{}, pwd []byte) ([]byte, error) {
), nil
case *sm2.PublicKey:
if k == nil {
return nil, errors.New("Invalid sm2 public key. It must be different from nil.")
return nil, errors.New("Invalid sm2 public key. It must be different from nil")
}
return sm2.WritePublicKeytoMem(k, nil)
......@@ -175,16 +177,16 @@ func PublicKeyToPEM(publicKey interface{}, pwd []byte) ([]byte, error) {
func publicKeyToEncryptedPEM(publicKey interface{}, pwd []byte) ([]byte, error) {
if publicKey == nil {
return nil, errors.New("Invalid public key. It must be different from nil.")
return nil, errors.New("Invalid public key. It must be different from nil")
}
if len(pwd) == 0 {
return nil, errors.New("Invalid password. It must be different from nil.")
return nil, errors.New("Invalid password. It must be different from nil")
}
switch k := publicKey.(type) {
case *ecdsa.PublicKey:
if k == nil {
return nil, errors.New("Invalid ecdsa public key. It must be different from nil.")
return nil, errors.New("Invalid ecdsa public key. It must be different from nil")
}
raw, err := x509.MarshalPKIXPublicKey(k)
if err != nil {
......@@ -209,9 +211,10 @@ func publicKeyToEncryptedPEM(publicKey interface{}, pwd []byte) ([]byte, error)
}
}
// DERToPublicKey DER字符转成公钥
func DERToPublicKey(raw []byte) (pub interface{}, err error) {
if len(raw) == 0 {
return nil, errors.New("Invalid DER. It must be different from nil.")
return nil, errors.New("Invalid DER. It must be different from nil")
}
key, err := x509.ParsePKIXPublicKey(raw)
......@@ -222,6 +225,7 @@ func DERToPublicKey(raw []byte) (pub interface{}, err error) {
return key, err
}
// Clone 克隆结构
func Clone(src []byte) []byte {
clone := make([]byte, len(src))
copy(clone, src)
......
......@@ -6,6 +6,7 @@ package generator
import "crypto/x509"
// CAGenerator CA生成器接口
type CAGenerator interface {
SignCertificate(baseDir, name string, sans []string, pub interface{}) (*x509.Certificate, error)
......
......@@ -25,12 +25,14 @@ import (
"github.com/tjfoc/gmsm/sm2"
)
// EcdsaCA ecdsa CA结构
type EcdsaCA struct {
Name string
Signer crypto.Signer
SignCert *x509.Certificate
}
// SM2CA SM2 CA结构
type SM2CA struct {
Name string
Signer crypto.Signer
......@@ -38,10 +40,11 @@ type SM2CA struct {
Sm2Key csp.Key
}
// NewCA 根据类型生成CA生成器
func NewCA(baseDir, name string, signType int) (generator.CAGenerator, error) {
if signType == ty.AUTH_ECDSA {
if signType == ty.AuthECDSA {
return newEcdsaCA(baseDir, name)
} else if signType == ty.AUTH_SM2 {
} else if signType == ty.AuthSM2 {
return newSM2CA(baseDir, name)
} else {
return nil, fmt.Errorf("Invalid sign type")
......@@ -92,6 +95,7 @@ func newEcdsaCA(baseDir, name string) (*EcdsaCA, error) {
return ca, nil
}
// SignCertificate 证书签名
func (ca *EcdsaCA) SignCertificate(baseDir, name string, sans []string, pub interface{}) (*x509.Certificate, error) {
template := x509Template()
template.KeyUsage = x509.KeyUsageDigitalSignature
......@@ -112,6 +116,7 @@ func (ca *EcdsaCA) SignCertificate(baseDir, name string, sans []string, pub inte
return cert, nil
}
// GenerateLocalUser 生成本地用户
func (ca *EcdsaCA) GenerateLocalUser(baseDir, name string) error {
err := createFolderStructure(baseDir, true)
if err != nil {
......@@ -229,6 +234,7 @@ func newSM2CA(baseDir, name string) (*SM2CA, error) {
return ca, nil
}
// SignCertificate 证书签名
func (ca *SM2CA) SignCertificate(baseDir, name string, sans []string, pub interface{}) (*x509.Certificate, error) {
template := x509Template()
template.KeyUsage = x509.KeyUsageDigitalSignature
......@@ -250,6 +256,7 @@ func (ca *SM2CA) SignCertificate(baseDir, name string, sans []string, pub interf
return utils.ParseSm2CertificateToX509(cert), nil
}
// GenerateLocalUser 生成本地用户
func (ca *SM2CA) GenerateLocalUser(baseDir, name string) error {
err := createFolderStructure(baseDir, true)
if err != nil {
......
......@@ -11,6 +11,7 @@ import (
"github.com/tjfoc/gmsm/sm2"
)
// CreateCertificateToMem 证书转mem
func CreateCertificateToMem(template, parent *sm2.Certificate, key csp.Key) (cert []byte, err error) {
pk := key.(*csp.SM2PrivateKey).PrivKey
......@@ -25,6 +26,7 @@ func CreateCertificateToMem(template, parent *sm2.Certificate, key csp.Key) (cer
return
}
// CreateCertificateToPem 证书转pem
func CreateCertificateToPem(FileName string, template, parent *sm2.Certificate, key csp.Key) (bool, error) {
pk := key.(*csp.SM2PrivateKey).PrivKey
......@@ -44,6 +46,7 @@ func CreateCertificateToPem(FileName string, template, parent *sm2.Certificate,
return result, err
}
// ParseX509CertificateToSm2 解析x509格式为sm2格式证书
func ParseX509CertificateToSm2(x509Cert *x509.Certificate) *sm2.Certificate {
sm2cert := &sm2.Certificate{
Raw: x509Cert.Raw,
......@@ -103,6 +106,7 @@ func ParseX509CertificateToSm2(x509Cert *x509.Certificate) *sm2.Certificate {
return sm2cert
}
// ParseSm2CertificateToX509 解析sm2格式证书为x509格式
func ParseSm2CertificateToX509(sm2Cert *sm2.Certificate) *x509.Certificate {
if sm2Cert == nil {
return nil
......
......@@ -19,7 +19,7 @@ import (
func getCSPFromOpts(KeyStorePath string) (csp.CSP, error) {
if KeyStorePath == "" {
return nil, errors.New("Invalid config. It must not be nil.")
return nil, errors.New("Invalid config. It must not be nil")
}
fks, err := csp.NewFileBasedKeyStore(nil, KeyStorePath, false)
......@@ -30,6 +30,7 @@ func getCSPFromOpts(KeyStorePath string) (csp.CSP, error) {
return csp.New(fks)
}
// GeneratePrivateKey 生成私钥
func GeneratePrivateKey(keystorePath string, opt int) (csp.Key, crypto.Signer, error) {
var err error
var priv csp.Key
......@@ -48,6 +49,7 @@ func GeneratePrivateKey(keystorePath string, opt int) (csp.Key, crypto.Signer, e
return priv, s, err
}
// GetECPublicKey 获取ecdsa公钥
func GetECPublicKey(priv csp.Key) (*ecdsa.PublicKey, error) {
pubKey, err := priv.PublicKey()
if err != nil {
......@@ -66,6 +68,7 @@ func GetECPublicKey(priv csp.Key) (*ecdsa.PublicKey, error) {
return ecPubKey.(*ecdsa.PublicKey), nil
}
// GetSM2PublicKey 获取sm2公钥
func GetSM2PublicKey(priv csp.Key) (*sm2.PublicKey, error) {
pubKey, err := priv.PublicKey()
if err != nil {
......
......@@ -5,16 +5,14 @@
package utils
import (
"bufio"
"encoding/pem"
"fmt"
"io"
"io/ioutil"
"os"
"github.com/33cn/chain33/util"
)
// DirMissingOrEmpty 路径是否为空
func DirMissingOrEmpty(path string) (bool, error) {
dirExists, err := DirExists(path)
if err != nil {
......@@ -34,6 +32,7 @@ func DirMissingOrEmpty(path string) (bool, error) {
return false, nil
}
// DirExists 目录是否存在
func DirExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
......@@ -45,6 +44,7 @@ func DirExists(path string) (bool, error) {
return false, err
}
// DirEmpty 目录是否为空
func DirEmpty(path string) (bool, error) {
f, err := os.Open(path)
if err != nil {
......@@ -59,6 +59,7 @@ func DirEmpty(path string) (bool, error) {
return false, err
}
// ReadFile 读取文件
func ReadFile(file string) ([]byte, error) {
fileCont, err := ioutil.ReadFile(file)
if err != nil {
......@@ -68,6 +69,7 @@ func ReadFile(file string) ([]byte, error) {
return fileCont, nil
}
// ReadPemFile 读取pem文件
func ReadPemFile(file string) ([]byte, error) {
bytes, err := ReadFile(file)
if err != nil {
......@@ -82,35 +84,7 @@ func ReadPemFile(file string) ([]byte, error) {
return bytes, nil
}
func CheckFileIsExist(filename string) bool {
var exist = true
if _, err := os.Stat(filename); os.IsNotExist(err) {
exist = false
}
return exist
}
// DeleteFile 删除文件
func DeleteFile(file string) error {
return os.Remove(file)
}
func WriteStringToFile(file, content string) (writeLen int, err error) {
var f *os.File
if err = util.MakeDir(file); err != nil {
return
}
util.DeleteFile(file)
if CheckFileIsExist(file) {
f, err = os.OpenFile(file, os.O_APPEND, 0666)
} else {
f, err = os.Create(file)
}
if err != nil {
return
}
defer f.Close()
w := bufio.NewWriter(f)
writeLen, err = w.WriteString(content)
w.Flush()
return
}
......@@ -25,6 +25,7 @@ import (
"github.com/tjfoc/gmsm/sm2"
)
// SKI 计算ski
func SKI(curve elliptic.Curve, x, y *big.Int) (ski []byte) {
raw := elliptic.Marshal(curve, x, y)
......@@ -33,6 +34,7 @@ func SKI(curve elliptic.Curve, x, y *big.Int) (ski []byte) {
return hash.Sum(nil)
}
// GetPublicKeySKIFromCert 从cert字节中获取公钥ski
func GetPublicKeySKIFromCert(cert []byte, signType int) (string, error) {
dcert, _ := pem.Decode(cert)
if dcert == nil {
......@@ -41,14 +43,14 @@ func GetPublicKeySKIFromCert(cert []byte, signType int) (string, error) {
var ski []byte
switch signType {
case ty.AUTH_ECDSA:
case ty.AuthECDSA:
x509Cert, err := x509.ParseCertificate(dcert.Bytes)
if err != nil {
return "", errors.Errorf("Unable to parse cert from decoded bytes: %s", err)
}
ecdsaPk := x509Cert.PublicKey.(*ecdsa.PublicKey)
ski = SKI(ecdsaPk.Curve, ecdsaPk.X, ecdsaPk.Y)
case ty.AUTH_SM2:
case ty.AuthSM2:
sm2Cert, err := sm2.ParseCertificate(dcert.Bytes)
if err != nil {
return "", errors.Errorf("Unable to parse cert from decoded bytes: %s", err)
......@@ -62,6 +64,7 @@ func GetPublicKeySKIFromCert(cert []byte, signType int) (string, error) {
return hex.EncodeToString(ski), nil
}
// EncodeCertToSignature 证书编码进签名
func EncodeCertToSignature(signByte []byte, cert []byte) ([]byte, error) {
certSign := crypto.CertSignature{}
certSign.Signature = append(certSign.Signature, signByte...)
......@@ -69,6 +72,7 @@ func EncodeCertToSignature(signByte []byte, cert []byte) ([]byte, error) {
return asn1.Marshal(certSign)
}
// DecodeCertFromSignature 从签名中解码证书
func DecodeCertFromSignature(signByte []byte) ([]byte, []byte, error) {
var certSignature crypto.CertSignature
_, err := asn1.Unmarshal(signByte, &certSignature)
......@@ -79,6 +83,7 @@ func DecodeCertFromSignature(signByte []byte) ([]byte, []byte, error) {
return certSignature.Cert, certSignature.Signature, nil
}
// PrivKeyByteFromRaw pem结构转成byte类型私钥
func PrivKeyByteFromRaw(raw []byte, signType int) ([]byte, error) {
block, _ := pem.Decode(raw)
if block == nil {
......@@ -86,13 +91,13 @@ func PrivKeyByteFromRaw(raw []byte, signType int) ([]byte, error) {
}
switch signType {
case ty.AUTH_ECDSA:
case ty.AuthECDSA:
key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
return ecdsa_util.SerializePrivateKey(key.(*ecdsa.PrivateKey)), nil
case ty.AUTH_SM2:
case ty.AuthSM2:
key, err := sm2.ParsePKCS8PrivateKey(block.Bytes, nil)
if err != nil {
return nil, err
......
......@@ -20,6 +20,7 @@ func init() {
ety.InitFuncList(types.ListMethod(&Cert{}))
}
// Init 初始化
func Init(name string, sub []byte) {
driverName = name
var cfg ct.Authority
......@@ -30,10 +31,12 @@ func Init(name string, sub []byte) {
drivers.Register(driverName, newCert, types.GetDappFork(driverName, "Enable"))
}
// GetName 获取cert执行器名
func GetName() string {
return newCert().GetName()
}
// Cert cert执行器
type Cert struct {
drivers.DriverBase
}
......@@ -45,10 +48,12 @@ func newCert() drivers.Driver {
return c
}
// GetDriverName 获取cert执行器名
func (c *Cert) GetDriverName() string {
return driverName
}
// CheckTx cert执行器tx证书校验
func (c *Cert) CheckTx(tx *types.Transaction, index int) error {
// 基类检查
err := c.DriverBase.CheckTx(tx, index)
......@@ -86,7 +91,12 @@ func (c *Cert) CheckTx(tx *types.Transaction, index int) error {
根据前缀查找证书变更记录,cert回滚、重启、同步用到
*/
func (c *Cert) loadHistoryByPrefix() error {
parm := &types.LocalDBList{[]byte("LODB-cert-"), nil, 0, 0}
parm := &types.LocalDBList{
Prefix: []byte("LODB-cert-"),
Key: nil,
Direction: 0,
Count: 0,
}
result, err := c.DriverBase.GetApi().LocalList(parm)
if err != nil {
return err
......@@ -115,7 +125,7 @@ func (c *Cert) loadHistoryByPrefix() error {
*/
func (c *Cert) loadHistoryByHeight() error {
key := calcCertHeightKey(c.GetHeight())
parm := &types.LocalDBGet{[][]byte{key}}
parm := &types.LocalDBGet{Keys: [][]byte{key}}
result, err := c.DriverBase.GetApi().LocalGet(parm)
if err != nil {
return err
......
......@@ -16,6 +16,7 @@ func calcCertHeightKey(height int64) []byte {
return []byte(fmt.Sprintf("LODB-cert-%d", height))
}
// ExecLocal_New 启用证书交易执行
func (c *Cert) ExecLocal_New(payload *ct.CertNew, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
if !authority.IsAuthEnable {
clog.Error("Authority is not available. Please check the authority config or authority initialize error logs.")
......@@ -27,17 +28,24 @@ func (c *Cert) ExecLocal_New(payload *ct.CertNew, tx *types.Transaction, receipt
authority.Author.HistoryCertCache.CurHeight = c.GetHeight()
authority.Author.HistoryCertCache.ToHistoryCertStore(historityCertdata)
key := calcCertHeightKey(c.GetHeight())
set.KV = append(set.KV, &types.KeyValue{key, types.Encode(historityCertdata)})
set.KV = append(set.KV, &types.KeyValue{
Key: key,
Value: types.Encode(historityCertdata),
})
// 构造非证书历史数据
noneCertdata := &types.HistoryCertStore{}
noneCertdata.NxtHeight = historityCertdata.CurHeigth
noneCertdata.CurHeigth = 0
set.KV = append(set.KV, &types.KeyValue{calcCertHeightKey(0), types.Encode(noneCertdata)})
set.KV = append(set.KV, &types.KeyValue{
Key: calcCertHeightKey(0),
Value: types.Encode(noneCertdata),
})
return &set, nil
}
// ExecLocal_Update 更新证书交易执行
func (c *Cert) ExecLocal_Update(payload *ct.CertUpdate, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
if !authority.IsAuthEnable {
clog.Error("Authority is not available. Please check the authority config or authority initialize error logs.")
......@@ -50,17 +58,24 @@ func (c *Cert) ExecLocal_Update(payload *ct.CertUpdate, tx *types.Transaction, r
historityCertdata := &types.HistoryCertStore{}
authority.Author.HistoryCertCache.NxtHeight = c.GetHeight()
authority.Author.HistoryCertCache.ToHistoryCertStore(historityCertdata)
set.KV = append(set.KV, &types.KeyValue{key, types.Encode(historityCertdata)})
set.KV = append(set.KV, &types.KeyValue{
Key: key,
Value: types.Encode(historityCertdata),
})
// 证书更新
historityCertdata = &types.HistoryCertStore{}
authority.Author.ReloadCertByHeght(c.GetHeight())
authority.Author.HistoryCertCache.ToHistoryCertStore(historityCertdata)
setKey := calcCertHeightKey(c.GetHeight())
set.KV = append(set.KV, &types.KeyValue{setKey, types.Encode(historityCertdata)})
set.KV = append(set.KV, &types.KeyValue{
Key: setKey,
Value: types.Encode(historityCertdata),
})
return &set, nil
}
// ExecLocal_Normal 非证书变更交易执行
func (c *Cert) ExecLocal_Normal(payload *ct.CertNormal, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
if !authority.IsAuthEnable {
clog.Error("Authority is not available. Please check the authority config or authority initialize error logs.")
......
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: cert.proto
......
......@@ -5,7 +5,9 @@
package types
var (
// CertX cert执行器名
CertX = "cert"
// ExecerCert cert执行器字节
ExecerCert = []byte(CertX)
actionName = map[string]int32{
"New": CertActionNew,
......
......@@ -7,8 +7,12 @@ package types
import "errors"
var (
// ErrValidateCertFailed cert校验失败
ErrValidateCertFailed = errors.New("ErrValidateCertFailed")
// ErrGetHistoryCertData 获取证书错误
ErrGetHistoryCertData = errors.New("ErrGetHistoryCertData")
// ErrUnknowAuthSignType 无效签名类型
ErrUnknowAuthSignType = errors.New("ErrUnknowAuthSignType")
// ErrInitializeAuthority 初始化校验器失败
ErrInitializeAuthority = errors.New("ErrInitializeAuthority")
)
......@@ -12,10 +12,8 @@ const (
CertActionUpdate = 2
CertActionNormal = 3
SignNameAuthECDSA = "auth_ecdsa"
AUTH_ECDSA = 257
SignNameAuthSM2 = "auth_sm2"
AUTH_SM2 = 258
AuthECDSA = 257
AuthSM2 = 258
)
func init() {
......@@ -25,28 +23,34 @@ func init() {
types.RegisterDappFork(CertX, "Enable", 0)
}
// CertType cert执行器类型结构
type CertType struct {
types.ExecTypeBase
}
// NewType 新建cert类型结构
func NewType() *CertType {
c := &CertType{}
c.SetChild(c)
return c
}
// GetPayload 获取payload
func (b *CertType) GetPayload() types.Message {
return &CertAction{}
}
// GetName 获取执行器名
func (b *CertType) GetName() string {
return CertX
}
// GetLogMap 获取logmap
func (b *CertType) GetLogMap() map[int64]*types.LogInfo {
return nil
}
// GetTypeMap 获取类型map
func (b *CertType) GetTypeMap() map[string]int32 {
return actionName
}
......@@ -25,23 +25,3 @@ type CreateCallTx struct {
// IsCreate 是否创建合约
IsCreate bool `json:"isCreate"`
}
// BindABI 绑定ABI的RPC请求结构
type BindABI struct {
// Data 要绑定的ABI数据
Data string `json:"data"`
// Name 要绑定的EVM合约名称
Name string `json:"name"`
// Note 备注
Note string `json:"note"`
}
// ABICall ABI方式调用的RPC请求结构
type ABICall struct {
// Data ABI调用信息
Data string `json:"data"`
// Name 调用的合约名称
Name string `json:"name"`
// Amount 调用时传递的金额信息
Amount uint64 `json:"amount"`
}
......@@ -6,6 +6,7 @@ package commands
import "github.com/spf13/cobra"
// Cmd The command line is not used.
func Cmd() *cobra.Command {
return nil
}
......@@ -26,3 +26,8 @@ status: Create 1 -> Match 2 -> Cancel 3 -> Close 4
//1. 我的所有赌局,按照状态进行分类 (按照地址查询)
//2. 系统所有正在进行的赌局 (按照时间进行排序)
*/
//game 的状态变化:
// staus == 1 (创建,开始猜拳游戏)
// status == 2 (匹配,参与)
// status == 3 (取消)
// status == 4 (Close的情况)
......@@ -9,21 +9,25 @@ import (
gt "github.com/33cn/plugin/plugin/dapp/game/types"
)
// Exec_Create Create game
func (g *Game) Exec_Create(payload *gt.GameCreate, tx *types.Transaction, index int) (*types.Receipt, error) {
action := NewAction(g, tx, index)
return action.GameCreate(payload)
}
// Exec_Cancel Cancel game
func (g *Game) Exec_Cancel(payload *gt.GameCancel, tx *types.Transaction, index int) (*types.Receipt, error) {
action := NewAction(g, tx, index)
return action.GameCancel(payload)
}
// Exec_Close Close game
func (g *Game) Exec_Close(payload *gt.GameClose, tx *types.Transaction, index int) (*types.Receipt, error) {
action := NewAction(g, tx, index)
return action.GameClose(payload)
}
// Exec_Match Match game
func (g *Game) Exec_Match(payload *gt.GameMatch, tx *types.Transaction, index int) (*types.Receipt, error) {
action := NewAction(g, tx, index)
return action.GameMatch(payload)
......
......@@ -9,6 +9,7 @@ import (
gt "github.com/33cn/plugin/plugin/dapp/game/types"
)
// roll back local db data
func (g *Game) execDelLocal(receiptData *types.ReceiptData) (*types.LocalDBSet, error) {
dbSet := &types.LocalDBSet{}
if receiptData.GetTy() != types.ExecOk {
......@@ -28,18 +29,22 @@ func (g *Game) execDelLocal(receiptData *types.ReceiptData) (*types.LocalDBSet,
return dbSet, nil
}
// ExecDelLocal_Create roll back local db data for create
func (g *Game) ExecDelLocal_Create(payload *gt.GameCreate, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return g.execDelLocal(receiptData)
}
// ExecDelLocal_Cancel roll back local db data for cancel
func (g *Game) ExecDelLocal_Cancel(payload *gt.GameCancel, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return g.execDelLocal(receiptData)
}
// ExecDelLocal_Close roll back local db data for close
func (g *Game) ExecDelLocal_Close(payload *gt.GameClose, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return g.execDelLocal(receiptData)
}
// ExecDelLocal_Match roll back local db data for match
func (g *Game) ExecDelLocal_Match(payload *gt.GameMatch, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return g.execDelLocal(receiptData)
}
......@@ -9,6 +9,7 @@ import (
gt "github.com/33cn/plugin/plugin/dapp/game/types"
)
// save receiptData to local db
func (g *Game) execLocal(receiptData *types.ReceiptData) (*types.LocalDBSet, error) {
dbSet := &types.LocalDBSet{}
if receiptData.GetTy() != types.ExecOk {
......@@ -28,18 +29,22 @@ func (g *Game) execLocal(receiptData *types.ReceiptData) (*types.LocalDBSet, err
return dbSet, nil
}
// ExecLocal_Create save receiptData for create
func (g *Game) ExecLocal_Create(payload *gt.GameCreate, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return g.execLocal(receiptData)
}
// ExecLocal_Cancel save receiptData for cancel
func (g *Game) ExecLocal_Cancel(payload *gt.GameCancel, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return g.execLocal(receiptData)
}
// ExecLocal_Close save receiptData for close
func (g *Game) ExecLocal_Close(payload *gt.GameClose, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return g.execLocal(receiptData)
}
// ExecLocal_Match save receiptData for Match
func (g *Game) ExecLocal_Match(payload *gt.GameMatch, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return g.execLocal(receiptData)
}
......@@ -22,32 +22,36 @@ func init() {
ety.InitFuncList(types.ListMethod(&Game{}))
}
// Init register dapp
func Init(name string, sub []byte) {
drivers.Register(GetName(), newGame, types.GetDappFork(driverName, "Enable"))
}
// Game the game inherits all the attributes of the driverBase.
type Game struct {
drivers.DriverBase
}
func newGame() drivers.Driver {
t := &Game{}
t.SetChild(t)
t.SetExecutorType(types.LoadExecutorType(driverName))
return t
g := &Game{}
g.SetChild(g)
g.SetExecutorType(types.LoadExecutorType(driverName))
return g
}
// GetName get name
func GetName() string {
return newGame().GetName()
}
// GetDriverName get driver name
func (g *Game) GetDriverName() string {
return driverName
}
//更新索引
// update Index
func (g *Game) updateIndex(log *gt.ReceiptGame) (kvs []*types.KeyValue) {
//先保存本次Action产生的索引
// save the index generated by this action first.
kvs = append(kvs, addGameAddrIndex(log.Status, log.GameId, log.Addr, log.Index))
kvs = append(kvs, addGameStatusIndex(log.Status, log.GameId, log.Index))
if log.Status == gt.GameActionMatch {
......@@ -69,9 +73,9 @@ func (g *Game) updateIndex(log *gt.ReceiptGame) (kvs []*types.KeyValue) {
return kvs
}
//回滚索引
// rollback Index
func (g *Game) rollbackIndex(log *gt.ReceiptGame) (kvs []*types.KeyValue) {
//先删除本次Action产生的索引
kvs = append(kvs, delGameAddrIndex(log.Status, log.Addr, log.Index))
kvs = append(kvs, delGameStatusIndex(log.Status, log.Index))
......@@ -112,21 +116,21 @@ func calcGameAddrIndexPrefix(status int32, addr string) []byte {
key := fmt.Sprintf("LODB-game-addr:%d:%s:", status, addr)
return []byte(key)
}
func addGameStatusIndex(status int32, gameId string, index int64) *types.KeyValue {
func addGameStatusIndex(status int32, gameID string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcGameStatusIndexKey(status, index)
record := &gt.GameRecord{
GameId: gameId,
GameId: gameID,
Index: index,
}
kv.Value = types.Encode(record)
return kv
}
func addGameAddrIndex(status int32, gameId, addr string, index int64) *types.KeyValue {
func addGameAddrIndex(status int32, gameID, addr string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcGameAddrIndexKey(status, addr, index)
record := &gt.GameRecord{
GameId: gameId,
GameId: gameID,
Index: index,
}
kv.Value = types.Encode(record)
......@@ -146,19 +150,23 @@ func delGameAddrIndex(status int32, addr string, index int64) *types.KeyValue {
return kv
}
// ReplyGameList the data structure returned when querying the game list.
type ReplyGameList struct {
Games []*Game `json:"games"`
}
// ReplyGame the data structure returned when querying a single game.
type ReplyGame struct {
Game *Game `json:"game"`
}
func (c *Game) GetPayloadValue() types.Message {
// GetPayloadValue get payload value
func (g *Game) GetPayloadValue() types.Message {
return &gt.GameAction{}
}
func (c *Game) GetTypeMap() map[string]int32 {
// GetTypeMap get TypeMap
func (g *Game) GetTypeMap() map[string]int32 {
return map[string]int32{
"Create": gt.GameActionCreate,
"Match": gt.GameActionMatch,
......
This diff is collapsed.
......@@ -9,18 +9,22 @@ import (
gt "github.com/33cn/plugin/plugin/dapp/game/types"
)
// Query_QueryGameListByIds query game list by gameIDs
func (g *Game) Query_QueryGameListByIds(in *gt.QueryGameInfos) (types.Message, error) {
return Infos(g.GetStateDB(), in)
return QueryGameListByIds(g.GetStateDB(), in)
}
// Query_QueryGameListCount query game count by status and addr
func (g *Game) Query_QueryGameListCount(in *gt.QueryGameListCount) (types.Message, error) {
return QueryGameListCount(g.GetStateDB(), in)
}
// Query_QueryGameListByStatusAndAddr query game list by status and addr
func (g *Game) Query_QueryGameListByStatusAndAddr(in *gt.QueryGameListByStatusAndAddr) (types.Message, error) {
return List(g.GetLocalDB(), g.GetStateDB(), in)
}
// Query_QueryGameById query game by gameID
func (g *Game) Query_QueryGameById(in *gt.QueryGameInfo) (types.Message, error) {
game, err := readGame(g.GetStateDB(), in.GetGameId())
if err != nil {
......
......@@ -26,16 +26,18 @@ var (
ExecerGame = []byte(GameX)
)
// action name
const (
Action_CreateGame = "createGame"
Action_MatchGame = "matchGame"
Action_CancelGame = "cancelGame"
Action_CloseGame = "closeGame"
ActionCreateGame = "createGame"
ActionMatchGame = "matchGame"
ActionCancelGame = "cancelGame"
ActionCloseGame = "closeGame"
)
// query func name
const (
FuncName_QueryGameListByIds = "QueryGameListByIds"
FuncName_QueryGameListCount = "QueryGameListCount"
FuncName_QueryGameListByStatusAndAddr = "QueryGameListByStatusAndAddr"
FuncName_QueryGameById = "QueryGameById"
FuncNameQueryGameListByIds = "QueryGameListByIds"
FuncNameQueryGameListCount = "QueryGameListCount"
FuncNameQueryGameListByStatusAndAddr = "QueryGameListByStatusAndAddr"
FuncNameQueryGameByID = "QueryGameById"
)
......@@ -4,15 +4,16 @@
package types
import "errors"
import "fmt"
// some errors definition
var (
ErrGameCreateAmount = errors.New("You fill in more than the maximum number of games.")
ErrGameCancleAddr = errors.New("You don't have permission to cancel someone else's game.")
ErrGameCloseAddr = errors.New("The game time has not yet expired,You don't have permission to call yet.")
ErrGameTimeOut = errors.New("The game has expired.,You don't have permission to call.")
ErrGameMatchStatus = errors.New("can't join the game, the game has matched or finished!")
ErrGameMatch = errors.New("can't join the game, You can't match the game you created!")
ErrGameCancleStatus = errors.New("can't cancle the game, the game has matched!")
ErrGameCloseStatus = errors.New("can't close the game again, the game has finished!")
ErrGameCreateAmount = fmt.Errorf("%s", "You fill in more than the maximum number of games.")
ErrGameCancleAddr = fmt.Errorf("%s", "You don't have permission to cancel someone else's game.")
ErrGameCloseAddr = fmt.Errorf("%s", "The game time has not yet expired,You don't have permission to call yet.")
ErrGameTimeOut = fmt.Errorf("%s", "The game has expired.,You don't have permission to call.")
ErrGameMatchStatus = fmt.Errorf("%s", "can't join the game, the game has matched or finished!")
ErrGameMatch = fmt.Errorf("%s", "can't join the game, You can't match the game you created!")
ErrGameCancleStatus = fmt.Errorf("%s", "can't cancle the game, the game has matched!")
ErrGameCloseStatus = fmt.Errorf("%s", "can't close the game again, the game has finished!")
)
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: game.proto
......
......@@ -4,6 +4,7 @@
package types
// GamePreCreateTx pre create game,unused
type GamePreCreateTx struct {
//Secret string `json:"secret"`
//下注必须时偶数,不能时级数
......@@ -14,59 +15,23 @@ type GamePreCreateTx struct {
Fee int64 `json:"fee"`
}
// GamePreMatchTx pre match game,unused
type GamePreMatchTx struct {
GameId string `json:"gameId"`
GameID string `json:"gameID"`
Guess int32 `json:"guess"`
Fee int64 `json:"fee"`
}
// GamePreCancelTx pre cancel tx,unused
type GamePreCancelTx struct {
GameId string `json:"gameId"`
GameID string `json:"gameID"`
Fee int64 `json:"fee"`
}
// GamePreCloseTx pre close game, unused
type GamePreCloseTx struct {
GameId string `json:"gameId"`
GameID string `json:"gameID"`
Secret string `json:"secret"`
Result int32 `json:"result"`
Fee int64 `json:"fee"`
}
type GameData struct {
// 默认是由创建这局游戏的txHash作为gameId
GameId string `json:"gameId"`
// create 1 -> Match 2 -> Cancel 3 -> Close 4 Pending 5 //表示有人参与游戏,但还未打包
Status int32 `json:"status"`
// 创建时间
CreateTime int64 `json:"createTime"`
// 匹配时间(何时参与对赌)
MatchTime int64 `json:"matchTime"`
// 状态close的时间(包括cancel)
Closetime int64 `json:"closetime"`
// 赌注
Value int64 `json:"value"`
// 发起者账号地址
CreateAddress string `json:"createAddress"`
// 对赌者账号地址
MatchAddress string `json:"matchAddress"`
// hash 类型,预留字段
HashType string `json:"hashType"`
// 庄家创建游戏时,庄家自己出拳结果加密后的hash值
HashValue []byte `json:"hashValue"`
// 用来公布庄家出拳结果的私钥
Secret string `json:"secret"`
// 1平局,2 庄家获胜,3 matcher获胜,4 庄家开奖超时,matcher获胜,并获得本局所有赌资
Result int32 `json:"result"`
// matcher 出拳结果
MatcherGuess int32 `json:"matcherGuess"`
// create txHash
CreateTxHash string `json:"createTxHash"`
// matche交易hash
MatchTxHash string `json:"matchTxHash"`
// close txhash
CloseTxHash string `json:"closeTxHash"`
// cancel txhash
CancelTxHash string `json:"cancelTxHash"`
CreatorGuess int32 `json:"creatorGuess"`
Index int64 `json:"index"`
}
......@@ -30,18 +30,20 @@ func getRealExecName(paraName string) string {
return types.ExecName(paraName + GameX)
}
// NewType new type
func NewType() *GameType {
c := &GameType{}
c.SetChild(c)
return c
}
// exec
// GameType execType
type GameType struct {
types.ExecTypeBase
}
func (at *GameType) GetLogMap() map[int64]*types.LogInfo {
// GetLogMap get log
func (gt *GameType) GetLogMap() map[int64]*types.LogInfo {
return map[int64]*types.LogInfo{
TyLogCreateGame: {reflect.TypeOf(ReceiptGame{}), "LogLotteryCreate"},
TyLogCancleGame: {reflect.TypeOf(ReceiptGame{}), "LogCancleGame"},
......@@ -50,11 +52,13 @@ func (at *GameType) GetLogMap() map[int64]*types.LogInfo {
}
}
func (g *GameType) GetPayload() types.Message {
// GetPayload get payload
func (gt *GameType) GetPayload() types.Message {
return &GameAction{}
}
func (g *GameType) GetTypeMap() map[string]int32 {
// GetTypeMap get typeMap
func (gt *GameType) GetTypeMap() map[string]int32 {
return map[string]int32{
"Create": GameActionCreate,
"Cancel": GameActionCancel,
......@@ -63,11 +67,10 @@ func (g *GameType) GetTypeMap() map[string]int32 {
}
}
// TODO createTx接口暂时没法用,作为一个预留接口
func (game GameType) CreateTx(action string, message json.RawMessage) (*types.Transaction, error) {
// CreateTx unused,just empty implementation
func (gt GameType) CreateTx(action string, message json.RawMessage) (*types.Transaction, error) {
tlog.Debug("Game.CreateTx", "action", action)
var tx *types.Transaction
if action == Action_CreateGame {
if action == ActionCreateGame {
var param GamePreCreateTx
err := json.Unmarshal(message, &param)
if err != nil {
......@@ -76,7 +79,7 @@ func (game GameType) CreateTx(action string, message json.RawMessage) (*types.Tr
}
return CreateRawGamePreCreateTx(&param)
} else if action == Action_MatchGame {
} else if action == ActionMatchGame {
var param GamePreMatchTx
err := json.Unmarshal(message, &param)
if err != nil {
......@@ -85,7 +88,7 @@ func (game GameType) CreateTx(action string, message json.RawMessage) (*types.Tr
}
return CreateRawGamePreMatchTx(&param)
} else if action == Action_CancelGame {
} else if action == ActionCancelGame {
var param GamePreCancelTx
err := json.Unmarshal(message, &param)
if err != nil {
......@@ -94,7 +97,7 @@ func (game GameType) CreateTx(action string, message json.RawMessage) (*types.Tr
}
return CreateRawGamePreCancelTx(&param)
} else if action == Action_CloseGame {
} else if action == ActionCloseGame {
var param GamePreCloseTx
err := json.Unmarshal(message, &param)
if err != nil {
......@@ -103,13 +106,11 @@ func (game GameType) CreateTx(action string, message json.RawMessage) (*types.Tr
}
return CreateRawGamePreCloseTx(&param)
} else {
return nil, types.ErrNotSupport
}
return tx, nil
return nil, types.ErrNotSupport
}
// CreateRawGamePreCreateTx unused,just empty implementation
func CreateRawGamePreCreateTx(parm *GamePreCreateTx) (*types.Transaction, error) {
if parm == nil {
tlog.Error("CreateRawGamePreCreateTx", "parm", parm)
......@@ -139,13 +140,14 @@ func CreateRawGamePreCreateTx(parm *GamePreCreateTx) (*types.Transaction, error)
return tx, nil
}
// CreateRawGamePreMatchTx unused,just empty implementation
func CreateRawGamePreMatchTx(parm *GamePreMatchTx) (*types.Transaction, error) {
if parm == nil {
return nil, types.ErrInvalidParam
}
v := &GameMatch{
GameId: parm.GameId,
GameId: parm.GameID,
Guess: parm.Guess,
}
game := &GameAction{
......@@ -166,12 +168,13 @@ func CreateRawGamePreMatchTx(parm *GamePreMatchTx) (*types.Transaction, error) {
return tx, nil
}
// CreateRawGamePreCancelTx unused,just empty implementation
func CreateRawGamePreCancelTx(parm *GamePreCancelTx) (*types.Transaction, error) {
if parm == nil {
return nil, types.ErrInvalidParam
}
v := &GameCancel{
GameId: parm.GameId,
GameId: parm.GameID,
}
cancel := &GameAction{
Ty: GameActionCancel,
......@@ -191,13 +194,13 @@ func CreateRawGamePreCancelTx(parm *GamePreCancelTx) (*types.Transaction, error)
return tx, nil
}
//CreateRawGamePreCloseTx
// CreateRawGamePreCloseTx unused,just empty implementation
func CreateRawGamePreCloseTx(parm *GamePreCloseTx) (*types.Transaction, error) {
if parm == nil {
return nil, types.ErrInvalidParam
}
v := &GameClose{
GameId: parm.GameId,
GameId: parm.GameID,
Secret: parm.Secret,
}
close := &GameAction{
......
......@@ -15,6 +15,7 @@ import (
"github.com/spf13/cobra"
)
// HashlockCmd cmds
func HashlockCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "hashlock",
......@@ -31,7 +32,7 @@ func HashlockCmd() *cobra.Command {
return cmd
}
// 锁定
// HashlockLockCmd construct lock tx
func HashlockLockCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "lock",
......@@ -96,7 +97,7 @@ func hashlockLockCmd(cmd *cobra.Command, args []string) {
ctx.RunWithoutMarshal()
}
// 解锁
// HashlockUnlockCmd construct unlock tx
func HashlockUnlockCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "unlock",
......@@ -139,7 +140,7 @@ func hashlockUnlockCmd(cmd *cobra.Command, args []string) {
ctx.RunWithoutMarshal()
}
// 发送
// HashlockSendCmd construct send tx
func HashlockSendCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "send",
......
......@@ -11,6 +11,7 @@ import (
pty "github.com/33cn/plugin/plugin/dapp/hashlock/types"
)
// Exec_Hlock Action
func (h *Hashlock) Exec_Hlock(hlock *pty.HashlockLock, tx *types.Transaction, index int) (*types.Receipt, error) {
clog.Debug("hashlocklock action")
if hlock.Amount <= 0 {
......@@ -38,6 +39,7 @@ func (h *Hashlock) Exec_Hlock(hlock *pty.HashlockLock, tx *types.Transaction, in
return actiondb.Hashlocklock(hlock)
}
// Exec_Hsend Action
func (h *Hashlock) Exec_Hsend(transfer *pty.HashlockSend, tx *types.Transaction, index int) (*types.Receipt, error) {
//unlock 有两个条件: 1. 时间已经过期 2. 密码是对的,返回原来的账户
clog.Debug("hashlockunlock action")
......@@ -45,6 +47,7 @@ func (h *Hashlock) Exec_Hsend(transfer *pty.HashlockSend, tx *types.Transaction,
return actiondb.Hashlocksend(transfer)
}
// Exec_Hunlock Action
func (h *Hashlock) Exec_Hunlock(transfer *pty.HashlockUnlock, tx *types.Transaction, index int) (*types.Receipt, error) {
//send 有两个条件:1. 时间没有过期 2. 密码是对的,币转移到 ToAddress
clog.Debug("hashlocksend action")
......
......@@ -10,8 +10,9 @@ import (
pty "github.com/33cn/plugin/plugin/dapp/hashlock/types"
)
// ExecDelLocal_Hlock Action
func (h *Hashlock) ExecDelLocal_Hlock(hlock *pty.HashlockLock, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
info := pty.Hashlockquery{hlock.Time, hashlockLocked, hlock.Amount, h.GetBlockTime(), 0}
info := pty.Hashlockquery{Time: hlock.Time, Status: hashlockLocked, Amount: hlock.Amount, CreateTime: h.GetBlockTime(), CurrentTime: 0}
kv, err := UpdateHashReciver(h.GetLocalDB(), hlock.Hash, info)
if err != nil {
return nil, err
......@@ -19,8 +20,9 @@ func (h *Hashlock) ExecDelLocal_Hlock(hlock *pty.HashlockLock, tx *types.Transac
return &types.LocalDBSet{KV: []*types.KeyValue{kv}}, nil
}
// ExecDelLocal_Hsend Action
func (h *Hashlock) ExecDelLocal_Hsend(hsend *pty.HashlockSend, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
info := pty.Hashlockquery{0, hashlockSent, 0, 0, 0}
info := pty.Hashlockquery{Time: 0, Status: hashlockSent, Amount: 0, CreateTime: 0, CurrentTime: 0}
kv, err := UpdateHashReciver(h.GetLocalDB(), common.Sha256(hsend.Secret), info)
if err != nil {
return nil, err
......@@ -28,8 +30,9 @@ func (h *Hashlock) ExecDelLocal_Hsend(hsend *pty.HashlockSend, tx *types.Transac
return &types.LocalDBSet{KV: []*types.KeyValue{kv}}, nil
}
// ExecDelLocal_Hunlock Action
func (h *Hashlock) ExecDelLocal_Hunlock(hunlock *pty.HashlockUnlock, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
info := pty.Hashlockquery{0, hashlockUnlocked, 0, 0, 0}
info := pty.Hashlockquery{Time: 0, Status: hashlockUnlocked, Amount: 0, CreateTime: 0, CurrentTime: 0}
kv, err := UpdateHashReciver(h.GetLocalDB(), common.Sha256(hunlock.Secret), info)
if err != nil {
return nil, err
......
......@@ -10,8 +10,9 @@ import (
pty "github.com/33cn/plugin/plugin/dapp/hashlock/types"
)
// ExecLocal_Hlock Action
func (h *Hashlock) ExecLocal_Hlock(hlock *pty.HashlockLock, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
info := pty.Hashlockquery{hlock.Time, hashlockLocked, hlock.Amount, h.GetBlockTime(), 0}
info := pty.Hashlockquery{Time: hlock.Time, Status: hashlockLocked, Amount: hlock.Amount, CreateTime: h.GetBlockTime(), CurrentTime: 0}
clog.Error("ExecLocal", "info", info)
kv, err := UpdateHashReciver(h.GetLocalDB(), hlock.Hash, info)
if err != nil {
......@@ -20,8 +21,9 @@ func (h *Hashlock) ExecLocal_Hlock(hlock *pty.HashlockLock, tx *types.Transactio
return &types.LocalDBSet{KV: []*types.KeyValue{kv}}, nil
}
// ExecLocal_Hsend Action
func (h *Hashlock) ExecLocal_Hsend(hsend *pty.HashlockSend, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
info := pty.Hashlockquery{0, hashlockSent, 0, 0, 0}
info := pty.Hashlockquery{Time: 0, Status: hashlockSent, Amount: 0, CreateTime: 0, CurrentTime: 0}
clog.Error("ExecLocal", "info", info)
kv, err := UpdateHashReciver(h.GetLocalDB(), common.Sha256(hsend.Secret), info)
if err != nil {
......@@ -30,8 +32,9 @@ func (h *Hashlock) ExecLocal_Hsend(hsend *pty.HashlockSend, tx *types.Transactio
return &types.LocalDBSet{KV: []*types.KeyValue{kv}}, nil
}
// ExecLocal_Hunlock Action
func (h *Hashlock) ExecLocal_Hunlock(hunlock *pty.HashlockUnlock, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
info := pty.Hashlockquery{0, hashlockUnlocked, 0, 0, 0}
info := pty.Hashlockquery{Time: 0, Status: hashlockUnlocked, Amount: 0, CreateTime: 0, CurrentTime: 0}
clog.Error("ExecLocal", "info", info)
kv, err := UpdateHashReciver(h.GetLocalDB(), common.Sha256(hunlock.Secret), info)
if err != nil {
......
......@@ -21,14 +21,17 @@ func init() {
ety.InitFuncList(types.ListMethod(&Hashlock{}))
}
// Init hashlock
func Init(name string, sub []byte) {
drivers.Register(GetName(), newHashlock, types.GetDappFork(driverName, "Enable"))
}
// GetName for hashlock
func GetName() string {
return newHashlock().GetName()
}
// Hashlock driver
type Hashlock struct {
drivers.DriverBase
}
......@@ -40,10 +43,12 @@ func newHashlock() drivers.Driver {
return h
}
// GetDriverName driverName
func (h *Hashlock) GetDriverName() string {
return driverName
}
// CheckTx nil
func (h *Hashlock) CheckTx(tx *types.Transaction, index int) error {
return nil
}
......@@ -387,7 +387,7 @@ func estHashsend(t *testing.T) {
}
func lock(secret []byte) error {
vlock := &hlt.HashlockAction_Hlock{&hlt.HashlockLock{Amount: lockAmount, Time: int64(locktime), Hash: common.Sha256(secret), ToAddress: addr[accountindexB], ReturnAddress: addr[accountindexA]}}
vlock := &hlt.HashlockAction_Hlock{Hlock: &hlt.HashlockLock{Amount: lockAmount, Time: int64(locktime), Hash: common.Sha256(secret), ToAddress: addr[accountindexB], ReturnAddress: addr[accountindexA]}}
//fmt.Println(vlock)
transfer := &hlt.HashlockAction{Value: vlock, Ty: hlt.HashlockActionLock}
tx := &types.Transaction{Execer: []byte("hashlock"), Payload: types.Encode(transfer), Fee: fee, To: addr[accountindexB]}
......@@ -406,7 +406,7 @@ func lock(secret []byte) error {
}
func unlock(secret []byte) error {
vunlock := &hlt.HashlockAction_Hunlock{&hlt.HashlockUnlock{Secret: secret}}
vunlock := &hlt.HashlockAction_Hunlock{Hunlock: &hlt.HashlockUnlock{Secret: secret}}
transfer := &hlt.HashlockAction{Value: vunlock, Ty: hlt.HashlockActionUnlock}
tx := &types.Transaction{Execer: []byte("hashlock"), Payload: types.Encode(transfer), Fee: fee, To: addr[accountindexB]}
tx.Nonce = r.Int63()
......@@ -424,7 +424,7 @@ func unlock(secret []byte) error {
func send(secret []byte) error {
vsend := &hlt.HashlockAction_Hsend{&hlt.HashlockSend{Secret: secret}}
vsend := &hlt.HashlockAction_Hsend{Hsend: &hlt.HashlockSend{Secret: secret}}
transfer := &hlt.HashlockAction{Value: vsend, Ty: hlt.HashlockActionSend}
tx := &types.Transaction{Execer: []byte("hashlock"), Payload: types.Encode(transfer), Fee: fee, To: addr[accountindexB]}
tx.Nonce = r.Int63()
......@@ -461,11 +461,7 @@ func showOrCheckAcc(c types.Chain33Client, addr string, sorc int, balance int64)
return true
}
}
if sorc != onlyshow {
return false
} else {
return true
}
return sorc == onlyshow
}
func showAccount(c types.Chain33Client, addr string) {
......@@ -520,7 +516,7 @@ func sendtoaddress(c types.Chain33Client, priv crypto.PrivKey, to string, amount
//defer conn.Close()
//fmt.Println("sign key privkey: ", common.ToHex(priv.Bytes()))
if amount > 0 {
v := &cty.CoinsAction_Transfer{&types.AssetsTransfer{Amount: amount}}
v := &cty.CoinsAction_Transfer{Transfer: &types.AssetsTransfer{Amount: amount}}
transfer := &cty.CoinsAction{Value: v, Ty: cty.CoinsActionTransfer}
tx := &types.Transaction{Execer: []byte("coins"), Payload: types.Encode(transfer), Fee: fee, To: to}
tx.Nonce = r.Int63()
......@@ -536,8 +532,9 @@ func sendtoaddress(c types.Chain33Client, priv crypto.PrivKey, to string, amount
return errors.New(string(reply.GetMsg()))
}
return nil
} else {
v := &cty.CoinsAction_Withdraw{&types.AssetsWithdraw{Amount: -amount}}
}
v := &cty.CoinsAction_Withdraw{Withdraw: &types.AssetsWithdraw{Amount: -amount}}
withdraw := &cty.CoinsAction{Value: v, Ty: cty.CoinsActionWithdraw}
tx := &types.Transaction{Execer: []byte("coins"), Payload: types.Encode(withdraw), Fee: fee, To: to}
tx.Nonce = r.Int63()
......@@ -553,7 +550,7 @@ func sendtoaddress(c types.Chain33Client, priv crypto.PrivKey, to string, amount
return errors.New(string(reply.GetMsg()))
}
return nil
}
}
func getAccounts() (*types.WalletAccounts, error) {
......
......@@ -103,7 +103,7 @@ func ConstructLockTx() *types.Transaction {
var locktime int64 = 70
var fee int64 = 1e6
vlock := &pty.HashlockAction_Hlock{&pty.HashlockLock{Amount: lockAmount, Time: locktime, Hash: common.Sha256(secret), ToAddress: toAddr, ReturnAddress: returnAddr}}
vlock := &pty.HashlockAction_Hlock{Hlock: &pty.HashlockLock{Amount: lockAmount, Time: locktime, Hash: common.Sha256(secret), ToAddress: toAddr, ReturnAddress: returnAddr}}
transfer := &pty.HashlockAction{Value: vlock, Ty: pty.HashlockActionLock}
tx := &types.Transaction{Execer: []byte("hashlock"), Payload: types.Encode(transfer), Fee: fee, To: toAddr}
tx.Nonce = r.Int63()
......@@ -116,7 +116,7 @@ func ConstructUnlockTx() *types.Transaction {
var fee int64 = 1e6
vunlock := &pty.HashlockAction_Hunlock{&pty.HashlockUnlock{Secret: secret}}
vunlock := &pty.HashlockAction_Hunlock{Hunlock: &pty.HashlockUnlock{Secret: secret}}
transfer := &pty.HashlockAction{Value: vunlock, Ty: pty.HashlockActionUnlock}
tx := &types.Transaction{Execer: []byte("hashlock"), Payload: types.Encode(transfer), Fee: fee, To: toAddr}
tx.Nonce = r.Int63()
......@@ -128,7 +128,7 @@ func ConstructSendTx() *types.Transaction {
var fee int64 = 1e6
vsend := &pty.HashlockAction_Hsend{&pty.HashlockSend{Secret: secret}}
vsend := &pty.HashlockAction_Hsend{Hsend: &pty.HashlockSend{Secret: secret}}
transfer := &pty.HashlockAction{Value: vsend, Ty: pty.HashlockActionSend}
tx := &types.Transaction{Execer: []byte("hashlock"), Payload: types.Encode(transfer), Fee: fee, To: toAddr}
tx.Nonce = r.Int63()
......@@ -174,11 +174,11 @@ func (e *TestDB) Set(key []byte, value []byte) error {
return nil
}
func (db *TestDB) BatchGet(keys [][]byte) (values [][]byte, err error) {
func (e *TestDB) BatchGet(keys [][]byte) (values [][]byte, err error) {
return nil, types.ErrNotFound
}
//从数据库中查询数据列表,set 中的cache 更新不会影响这个list
func (l *TestDB) List(prefix, key []byte, count, direction int32) ([][]byte, error) {
func (e *TestDB) List(prefix, key []byte, count, direction int32) ([][]byte, error) {
return nil, types.ErrNotFound
}
......@@ -25,10 +25,12 @@ const (
hashlockSent = 3
)
// DB struct
type DB struct {
pty.Hashlock
}
// NewDB instance
func NewDB(id []byte, returnWallet string, toAddress string, blocktime int64, amount int64, time int64) *DB {
h := &DB{}
h.HashlockId = id
......@@ -41,13 +43,15 @@ func NewDB(id []byte, returnWallet string, toAddress string, blocktime int64, am
return h
}
// GetKVSet for hashlock
func (h *DB) GetKVSet() (kvset []*types.KeyValue) {
value := types.Encode(&h.Hashlock)
kvset = append(kvset, &types.KeyValue{Key(h.HashlockId), value})
kvset = append(kvset, &types.KeyValue{Key: Key(h.HashlockId), Value: value})
return kvset
}
// Save KV
func (h *DB) Save(db dbm.KV) {
set := h.GetKVSet()
for i := 0; i < len(set); i++ {
......@@ -55,12 +59,14 @@ func (h *DB) Save(db dbm.KV) {
}
}
// Key for hashlock
func Key(id []byte) (key []byte) {
key = append(key, []byte("mavl-hashlock-")...)
key = append(key, id...)
return key
}
// Action def
type Action struct {
coinsAccount *account.DB
db dbm.KV
......@@ -71,12 +77,14 @@ type Action struct {
execaddr string
}
// NewAction gen action instance
func NewAction(h *Hashlock, tx *types.Transaction, execaddr string) *Action {
hash := tx.Hash()
fromaddr := tx.From()
return &Action{h.GetCoinsAccount(), h.GetStateDB(), hash, fromaddr, h.GetBlockTime(), h.GetHeight(), execaddr}
}
// Hashlocklock Action
func (action *Action) Hashlocklock(hlock *pty.HashlockLock) (*types.Receipt, error) {
var logs []*types.ReceiptLog
......@@ -105,10 +113,11 @@ func (action *Action) Hashlocklock(hlock *pty.HashlockLock) (*types.Receipt, err
//logs = append(logs, h.GetReceiptLog())
kv = append(kv, h.GetKVSet()...)
receipt = &types.Receipt{types.ExecOk, kv, logs}
receipt = &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}
return receipt, nil
}
// Hashlockunlock Action
func (action *Action) Hashlockunlock(unlock *pty.HashlockUnlock) (*types.Receipt, error) {
var logs []*types.ReceiptLog
......@@ -150,10 +159,11 @@ func (action *Action) Hashlockunlock(unlock *pty.HashlockUnlock) (*types.Receipt
//logs = append(logs, t.GetReceiptLog())
kv = append(kv, h.GetKVSet()...)
receipt = &types.Receipt{types.ExecOk, kv, logs}
receipt = &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}
return receipt, nil
}
// Hashlocksend Action
func (action *Action) Hashlocksend(send *pty.HashlockSend) (*types.Receipt, error) {
var logs []*types.ReceiptLog
......@@ -194,7 +204,7 @@ func (action *Action) Hashlocksend(send *pty.HashlockSend) (*types.Receipt, erro
//logs = append(logs, t.GetReceiptLog())
kv = append(kv, h.GetKVSet()...)
receipt = &types.Receipt{types.ExecOk, kv, logs}
receipt = &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}
return receipt, nil
}
......@@ -212,19 +222,20 @@ func readHashlock(db dbm.KV, id []byte) (*pty.Hashlock, error) {
return &hashlock, nil
}
// NewHashlockquery gen query instance
func NewHashlockquery() *pty.Hashlockquery {
q := pty.Hashlockquery{}
return &q
}
func calcHashlockIdKey(id []byte) []byte {
func calcHashlockIDKey(id []byte) []byte {
return append([]byte("LODB-hashlock-"), id...)
}
//将Information转换成byte类型,使输出为kv模式
// GeHashReciverKV gen KV
func GeHashReciverKV(hashlockID []byte, information *pty.Hashlockquery) *types.KeyValue {
clog.Error("GeHashReciverKV action")
infor := pty.Hashlockquery{information.Time, information.Status, information.Amount, information.CreateTime, information.CurrentTime}
infor := pty.Hashlockquery{Time: information.Time, Status: information.Status, Amount: information.Amount, CreateTime: information.CreateTime, CurrentTime: information.CurrentTime}
clog.Error("GeHashReciverKV action", "Status", information.Status)
reciver, err := json.Marshal(infor)
if err == nil {
......@@ -233,12 +244,12 @@ func GeHashReciverKV(hashlockID []byte, information *pty.Hashlockquery) *types.K
fmt.Println(err)
}
clog.Error("GeHashReciverKV action", "reciver", reciver)
kv := &types.KeyValue{calcHashlockIdKey(hashlockID), reciver}
kv := &types.KeyValue{Key: calcHashlockIDKey(hashlockID), Value: reciver}
clog.Error("GeHashReciverKV action", "kv", kv)
return kv
}
//从db里面根据key获取value,期间需要进行解码
// GetHashReciver get hashlock
func GetHashReciver(db dbm.KVDB, hashlockID []byte) (*pty.Hashlockquery, error) {
//reciver := types.Int64{}
clog.Error("GetHashReciver action", "hashlockID", hashlockID)
......@@ -264,14 +275,14 @@ func GetHashReciver(db dbm.KVDB, hashlockID []byte) (*pty.Hashlockquery, error)
return reciver, nil
}
//将hashlockId和information都以key和value形式存入db
// SetHashReciver save hashlock
func SetHashReciver(db dbm.KVDB, hashlockID []byte, information *pty.Hashlockquery) error {
clog.Error("SetHashReciver action")
kv := GeHashReciverKV(hashlockID, information)
return db.Set(kv.Key, kv.Value)
}
//根据状态值对db中存入的数据进行更改
// UpdateHashReciver update status for hashlock
func UpdateHashReciver(cachedb dbm.KVDB, hashlockID []byte, information pty.Hashlockquery) (*types.KeyValue, error) {
clog.Error("UpdateHashReciver", "hashlockId", hashlockID)
recv, err := GetHashReciver(cachedb, hashlockID)
......@@ -315,7 +326,7 @@ func UpdateHashReciver(cachedb dbm.KVDB, hashlockID []byte, information pty.Hash
return GeHashReciverKV(hashlockID, recv), nil
}
//根据hashlockid获取相关信息
// GetTxsByHashlockID get hashlock record
func (n *Hashlock) GetTxsByHashlockID(hashlockID []byte, differTime int64) (types.Message, error) {
clog.Error("GetTxsByHashlockId action")
db := n.GetLocalDB()
......
......@@ -6,6 +6,7 @@ package executor
import "github.com/33cn/chain33/types"
// Query_GetHashlocKById get hashlock instance
func (h *Hashlock) Query_GetHashlocKById(in []byte) (types.Message, error) {
differTime := types.Now().UnixNano()/1e9 - h.GetBlockTime()
clog.Error("Query action")
......
......@@ -6,6 +6,7 @@ package types
import "errors"
// hashlock errors
var (
ErrHashlockAmount = errors.New("ErrHashlockAmount")
ErrHashlockHash = errors.New("ErrHashlockHash")
......
......@@ -23,24 +23,27 @@ func init() {
types.RegisterDappFork(HashlockX, "Enable", 0)
}
// HashlockType def
type HashlockType struct {
types.ExecTypeBase
}
// NewType method
func NewType() *HashlockType {
c := &HashlockType{}
c.SetChild(c)
return c
}
// GetPayload method
func (hashlock *HashlockType) GetPayload() types.Message {
return &HashlockAction{}
}
// TODO 暂时不修改实现, 先完成结构的重构
// CreateTx method
func (hashlock *HashlockType) CreateTx(action string, message json.RawMessage) (*types.Transaction, error) {
hlog.Debug("hashlock.CreateTx", "action", action)
var tx *types.Transaction
if action == "HashlockLock" {
var param HashlockLockTx
err := json.Unmarshal(message, &param)
......@@ -68,9 +71,9 @@ func (hashlock *HashlockType) CreateTx(action string, message json.RawMessage) (
} else {
return nil, types.ErrNotSupport
}
return tx, nil
}
// GetTypeMap method
func (hashlock *HashlockType) GetTypeMap() map[string]int32 {
return map[string]int32{
"Hlock": HashlockActionLock,
......@@ -79,42 +82,12 @@ func (hashlock *HashlockType) GetTypeMap() map[string]int32 {
}
}
func (at *HashlockType) GetLogMap() map[int64]*types.LogInfo {
// GetLogMap method
func (hashlock *HashlockType) GetLogMap() map[int64]*types.LogInfo {
return map[int64]*types.LogInfo{}
}
type CoinsDepositLog struct {
}
func (l CoinsDepositLog) Name() string {
return "LogDeposit"
}
func (l CoinsDepositLog) Decode(msg []byte) (interface{}, error) {
var logTmp types.ReceiptAccountTransfer
err := types.Decode(msg, &logTmp)
if err != nil {
return nil, err
}
return logTmp, err
}
type CoinsGetTxsByAddr struct {
}
func (t *CoinsGetTxsByAddr) JsonToProto(message json.RawMessage) ([]byte, error) {
var req types.ReqAddr
err := json.Unmarshal(message, &req)
if err != nil {
return nil, err
}
return types.Encode(&req), nil
}
func (t *CoinsGetTxsByAddr) ProtoToJson(reply *types.Message) (interface{}, error) {
return reply, nil
}
// CreateRawHashlockLockTx method
func CreateRawHashlockLockTx(parm *HashlockLockTx) (*types.Transaction, error) {
if parm == nil {
hlog.Error("CreateRawHashlockLockTx", "parm", parm)
......@@ -145,6 +118,7 @@ func CreateRawHashlockLockTx(parm *HashlockLockTx) (*types.Transaction, error) {
return tx, nil
}
// CreateRawHashlockUnlockTx method
func CreateRawHashlockUnlockTx(parm *HashlockUnlockTx) (*types.Transaction, error) {
if parm == nil {
hlog.Error("CreateRawHashlockUnlockTx", "parm", parm)
......@@ -173,6 +147,7 @@ func CreateRawHashlockUnlockTx(parm *HashlockUnlockTx) (*types.Transaction, erro
return tx, nil
}
// CreateRawHashlockSendTx method
func CreateRawHashlockSendTx(parm *HashlockSendTx) (*types.Transaction, error) {
if parm == nil {
hlog.Error("CreateRawHashlockSendTx", "parm", parm)
......
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hashlock.proto
......
......@@ -4,6 +4,7 @@
package types
// HashlockLockTx for construction
type HashlockLockTx struct {
Secret string `json:"secret"`
Amount int64 `json:"amount"`
......@@ -13,11 +14,13 @@ type HashlockLockTx struct {
Fee int64 `json:"fee"`
}
// HashlockUnlockTx for construction
type HashlockUnlockTx struct {
Secret string `json:"secret"`
Fee int64 `json:"fee"`
}
// HashlockSendTx for construction
type HashlockSendTx struct {
Secret string `json:"secret"`
Fee int64 `json:"fee"`
......
......@@ -11,4 +11,5 @@ const (
HashlockActionUnlock = 3
)
// HashlockX name
var HashlockX = "hashlock"
......@@ -9,21 +9,25 @@ import (
pty "github.com/33cn/plugin/plugin/dapp/lottery/types"
)
// Exec_Create Action
func (l *Lottery) Exec_Create(payload *pty.LotteryCreate, tx *types.Transaction, index int) (*types.Receipt, error) {
actiondb := NewLotteryAction(l, tx, index)
return actiondb.LotteryCreate(payload)
}
// Exec_Buy Action
func (l *Lottery) Exec_Buy(payload *pty.LotteryBuy, tx *types.Transaction, index int) (*types.Receipt, error) {
actiondb := NewLotteryAction(l, tx, index)
return actiondb.LotteryBuy(payload)
}
// Exec_Draw Action
func (l *Lottery) Exec_Draw(payload *pty.LotteryDraw, tx *types.Transaction, index int) (*types.Receipt, error) {
actiondb := NewLotteryAction(l, tx, index)
return actiondb.LotteryDraw(payload)
}
// Exec_Close Action
func (l *Lottery) Exec_Close(payload *pty.LotteryClose, tx *types.Transaction, index int) (*types.Receipt, error) {
actiondb := NewLotteryAction(l, tx, index)
return actiondb.LotteryClose(payload)
......
......@@ -41,18 +41,22 @@ func (l *Lottery) execDelLocal(tx *types.Transaction, receiptData *types.Receipt
}
// ExecDelLocal_Create Action
func (l *Lottery) ExecDelLocal_Create(payload *pty.LotteryCreate, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return nil, nil
}
// ExecDelLocal_Buy Action
func (l *Lottery) ExecDelLocal_Buy(payload *pty.LotteryBuy, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return nil, nil
}
// ExecDelLocal_Draw Action
func (l *Lottery) ExecDelLocal_Draw(payload *pty.LotteryDraw, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return nil, nil
}
// ExecDelLocal_Close Action
func (l *Lottery) ExecDelLocal_Close(payload *pty.LotteryClose, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return nil, nil
}
......@@ -40,18 +40,22 @@ func (l *Lottery) execLocal(tx *types.Transaction, receipt *types.ReceiptData) (
return set, nil
}
// ExecLocal_Create Action
func (l *Lottery) ExecLocal_Create(payload *pty.LotteryCreate, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return l.execLocal(tx, receiptData)
}
// ExecLocal_Buy Action
func (l *Lottery) ExecLocal_Buy(payload *pty.LotteryBuy, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return l.execLocal(tx, receiptData)
}
// ExecLocal_Draw Action
func (l *Lottery) ExecLocal_Draw(payload *pty.LotteryDraw, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return l.execLocal(tx, receiptData)
}
// ExecLocal_Close Action
func (l *Lottery) ExecLocal_Close(payload *pty.LotteryClose, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return l.execLocal(tx, receiptData)
}
......@@ -6,32 +6,32 @@ package executor
import "fmt"
func calcLotteryBuyPrefix(lotteryId string, addr string) []byte {
key := fmt.Sprintf("LODB-lottery-buy:%s:%s", lotteryId, addr)
func calcLotteryBuyPrefix(lotteryID string, addr string) []byte {
key := fmt.Sprintf("LODB-lottery-buy:%s:%s", lotteryID, addr)
return []byte(key)
}
func calcLotteryBuyRoundPrefix(lotteryId string, addr string, round int64) []byte {
key := fmt.Sprintf("LODB-lottery-buy:%s:%s:%10d", lotteryId, addr, round)
func calcLotteryBuyRoundPrefix(lotteryID string, addr string, round int64) []byte {
key := fmt.Sprintf("LODB-lottery-buy:%s:%s:%10d", lotteryID, addr, round)
return []byte(key)
}
func calcLotteryBuyKey(lotteryId string, addr string, round int64, index int64) []byte {
key := fmt.Sprintf("LODB-lottery-buy:%s:%s:%10d:%18d", lotteryId, addr, round, index)
func calcLotteryBuyKey(lotteryID string, addr string, round int64, index int64) []byte {
key := fmt.Sprintf("LODB-lottery-buy:%s:%s:%10d:%18d", lotteryID, addr, round, index)
return []byte(key)
}
func calcLotteryDrawPrefix(lotteryId string) []byte {
key := fmt.Sprintf("LODB-lottery-draw:%s", lotteryId)
func calcLotteryDrawPrefix(lotteryID string) []byte {
key := fmt.Sprintf("LODB-lottery-draw:%s", lotteryID)
return []byte(key)
}
func calcLotteryDrawKey(lotteryId string, round int64) []byte {
key := fmt.Sprintf("LODB-lottery-draw:%s:%10d", lotteryId, round)
func calcLotteryDrawKey(lotteryID string, round int64) []byte {
key := fmt.Sprintf("LODB-lottery-draw:%s:%10d", lotteryID, round)
return []byte(key)
}
func calcLotteryKey(lotteryId string, status int32) []byte {
key := fmt.Sprintf("LODB-lottery-:%d:%s", status, lotteryId)
func calcLotteryKey(lotteryID string, status int32) []byte {
key := fmt.Sprintf("LODB-lottery-:%d:%s", status, lotteryID)
return []byte(key)
}
......@@ -27,6 +27,7 @@ type subConfig struct {
var cfg subConfig
// Init lottery
func Init(name string, sub []byte) {
driverName := GetName()
if name != driverName {
......@@ -38,10 +39,12 @@ func Init(name string, sub []byte) {
drivers.Register(driverName, newLottery, types.GetDappFork(driverName, "Enable"))
}
// GetName for lottery
func GetName() string {
return newLottery().GetName()
}
// Lottery driver
type Lottery struct {
drivers.DriverBase
}
......@@ -53,7 +56,8 @@ func newLottery() drivers.Driver {
return l
}
func (l *Lottery) GetDriverName() string {
// GetDriverName for lottery
func (lott *Lottery) GetDriverName() string {
return pty.LotteryX
}
......@@ -120,9 +124,8 @@ func (lott *Lottery) findLotteryDrawRecord(key []byte) (*pty.LotteryDrawRecord,
func (lott *Lottery) saveLotteryBuy(lotterylog *pty.ReceiptLottery) (kvs []*types.KeyValue) {
key := calcLotteryBuyKey(lotterylog.LotteryId, lotterylog.Addr, lotterylog.Round, lotterylog.Index)
kv := &types.KeyValue{}
record := &pty.LotteryBuyRecord{lotterylog.Number, lotterylog.Amount, lotterylog.Round, 0, lotterylog.Way, lotterylog.Index, lotterylog.Time, lotterylog.TxHash}
kv = &types.KeyValue{key, types.Encode(record)}
record := &pty.LotteryBuyRecord{Number: lotterylog.Number, Amount: lotterylog.Amount, Round: lotterylog.Round, Type: 0, Way: lotterylog.Way, Index: lotterylog.Index, Time: lotterylog.Time, TxHash: lotterylog.TxHash}
kv := &types.KeyValue{Key: key, Value: types.Encode(record)}
kvs = append(kvs, kv)
return kvs
......@@ -131,7 +134,7 @@ func (lott *Lottery) saveLotteryBuy(lotterylog *pty.ReceiptLottery) (kvs []*type
func (lott *Lottery) deleteLotteryBuy(lotterylog *pty.ReceiptLottery) (kvs []*types.KeyValue) {
key := calcLotteryBuyKey(lotterylog.LotteryId, lotterylog.Addr, lotterylog.Round, lotterylog.Index)
kv := &types.KeyValue{key, nil}
kv := &types.KeyValue{Key: key, Value: nil}
kvs = append(kvs, kv)
return kvs
}
......@@ -158,7 +161,6 @@ func (lott *Lottery) updateLotteryBuy(lotterylog *pty.ReceiptLottery, isAdd bool
if err != nil || record == nil {
return kvs
}
kv := &types.KeyValue{}
if isAdd {
llog.Debug("updateLotteryBuy update key")
......@@ -167,7 +169,7 @@ func (lott *Lottery) updateLotteryBuy(lotterylog *pty.ReceiptLottery, isAdd bool
record.Type = 0
}
kv = &types.KeyValue{key, types.Encode(record)}
kv := &types.KeyValue{Key: key, Value: types.Encode(record)}
kvs = append(kvs, kv)
}
}
......@@ -178,16 +180,15 @@ func (lott *Lottery) updateLotteryBuy(lotterylog *pty.ReceiptLottery, isAdd bool
func (lott *Lottery) saveLotteryDraw(lotterylog *pty.ReceiptLottery) (kvs []*types.KeyValue) {
key := calcLotteryDrawKey(lotterylog.LotteryId, lotterylog.Round)
kv := &types.KeyValue{}
record := &pty.LotteryDrawRecord{lotterylog.LuckyNumber, lotterylog.Round, lotterylog.Time, lotterylog.TxHash}
kv = &types.KeyValue{key, types.Encode(record)}
record := &pty.LotteryDrawRecord{Number: lotterylog.LuckyNumber, Round: lotterylog.Round, Time: lotterylog.Time, TxHash: lotterylog.TxHash}
kv := &types.KeyValue{Key: key, Value: types.Encode(record)}
kvs = append(kvs, kv)
return kvs
}
func (lott *Lottery) deleteLotteryDraw(lotterylog *pty.ReceiptLottery) (kvs []*types.KeyValue) {
key := calcLotteryDrawKey(lotterylog.LotteryId, lotterylog.Round)
kv := &types.KeyValue{key, nil}
kv := &types.KeyValue{Key: key, Value: nil}
kvs = append(kvs, kv)
return kvs
}
......@@ -210,20 +211,21 @@ func (lott *Lottery) deleteLottery(lotterylog *pty.ReceiptLottery) (kvs []*types
return kvs
}
func addlottery(lotteryId string, status int32) *types.KeyValue {
func addlottery(lotteryID string, status int32) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcLotteryKey(lotteryId, status)
kv.Value = []byte(lotteryId)
kv.Key = calcLotteryKey(lotteryID, status)
kv.Value = []byte(lotteryID)
return kv
}
func dellottery(lotteryId string, status int32) *types.KeyValue {
func dellottery(lotteryID string, status int32) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcLotteryKey(lotteryId, status)
kv.Key = calcLotteryKey(lotteryID, status)
kv.Value = nil
return kv
}
// GetPayloadValue lotteryAction
func (lott *Lottery) GetPayloadValue() types.Message {
return &pty.LotteryAction{}
}
......@@ -20,7 +20,7 @@ func (action *Action) getTxActions(height int64, blockNum int64) ([]*tickettypes
var txActions []*tickettypes.TicketAction
llog.Error("getTxActions", "height", height, "blockNum", blockNum)
if !types.IsPara() {
req := &types.ReqBlocks{height - blockNum + 1, height, false, []string{""}}
req := &types.ReqBlocks{Start: height - blockNum + 1, End: height, IsDetail: false, Pid: []string{""}}
blockDetails, err := action.api.GetBlocks(req)
if err != nil {
......@@ -36,7 +36,8 @@ func (action *Action) getTxActions(height int64, blockNum int64) ([]*tickettypes
txActions = append(txActions, ticketAction)
}
return txActions, nil
} else {
}
//block height on main
mainHeight := action.GetMainHeightByTxHash(action.txhash)
if mainHeight < 0 {
......@@ -58,13 +59,13 @@ func (action *Action) getTxActions(height int64, blockNum int64) ([]*tickettypes
txActions = append(txActions, ticketAction)
}
return txActions, nil
}
}
//TransactionDetail
// GetMainHeightByTxHash get Block height
func (action *Action) GetMainHeightByTxHash(txHash []byte) int64 {
for i := 0; i < retryNum; i++ {
req := &types.ReqHash{txHash}
req := &types.ReqHash{Hash: txHash}
txDetail, err := action.grpcClient.QueryTransaction(context.Background(), req)
if err != nil {
time.Sleep(time.Second)
......@@ -76,8 +77,9 @@ func (action *Action) GetMainHeightByTxHash(txHash []byte) int64 {
return -1
}
// GetBlocksOnMain get Block from main chain
func (action *Action) GetBlocksOnMain(start int64, end int64) (*types.BlockDetails, error) {
req := &types.ReqBlocks{start, end, false, []string{""}}
req := &types.ReqBlocks{Start: start, End: end, IsDetail: false, Pid: []string{""}}
getBlockSucc := false
var reply *types.Reply
var err error
......
This diff is collapsed.
......@@ -9,17 +9,19 @@ import (
pty "github.com/33cn/plugin/plugin/dapp/lottery/types"
)
// Query_GetLotteryNormalInfo not changed info
func (l *Lottery) Query_GetLotteryNormalInfo(param *pty.ReqLotteryInfo) (types.Message, error) {
lottery, err := findLottery(l.GetStateDB(), param.GetLotteryId())
if err != nil {
return nil, err
}
return &pty.ReplyLotteryNormalInfo{lottery.CreateHeight,
lottery.PurBlockNum,
lottery.DrawBlockNum,
lottery.CreateAddr}, nil
return &pty.ReplyLotteryNormalInfo{CreateHeight: lottery.CreateHeight,
PurBlockNum: lottery.PurBlockNum,
DrawBlockNum: lottery.DrawBlockNum,
CreateAddr: lottery.CreateAddr}, nil
}
// Query_GetLotteryPurchaseAddr for current round
func (l *Lottery) Query_GetLotteryPurchaseAddr(param *pty.ReqLotteryInfo) (types.Message, error) {
lottery, err := findLottery(l.GetStateDB(), param.GetLotteryId())
if err != nil {
......@@ -33,6 +35,7 @@ func (l *Lottery) Query_GetLotteryPurchaseAddr(param *pty.ReqLotteryInfo) (types
return reply, nil
}
// Query_GetLotteryCurrentInfo state
func (l *Lottery) Query_GetLotteryCurrentInfo(param *pty.ReqLotteryInfo) (types.Message, error) {
lottery, err := findLottery(l.GetStateDB(), param.GetLotteryId())
if err != nil {
......@@ -54,10 +57,12 @@ func (l *Lottery) Query_GetLotteryCurrentInfo(param *pty.ReqLotteryInfo) (types.
return reply, nil
}
// Query_GetLotteryHistoryLuckyNumber for all history
func (l *Lottery) Query_GetLotteryHistoryLuckyNumber(param *pty.ReqLotteryLuckyHistory) (types.Message, error) {
return ListLotteryLuckyHistory(l.GetLocalDB(), l.GetStateDB(), param)
}
// Query_GetLotteryRoundLuckyNumber for each round
func (l *Lottery) Query_GetLotteryRoundLuckyNumber(param *pty.ReqLotteryLuckyInfo) (types.Message, error) {
// var req pty.ReqLotteryLuckyInfo
var records []*pty.LotteryDrawRecord
......@@ -77,10 +82,12 @@ func (l *Lottery) Query_GetLotteryRoundLuckyNumber(param *pty.ReqLotteryLuckyInf
return &pty.LotteryDrawRecords{Records: records}, nil
}
// Query_GetLotteryHistoryBuyInfo for all history
func (l *Lottery) Query_GetLotteryHistoryBuyInfo(param *pty.ReqLotteryBuyHistory) (types.Message, error) {
return ListLotteryBuyRecords(l.GetLocalDB(), l.GetStateDB(), param)
}
// Query_GetLotteryBuyRoundInfo for each round
func (l *Lottery) Query_GetLotteryBuyRoundInfo(param *pty.ReqLotteryBuyInfo) (types.Message, error) {
key := calcLotteryBuyRoundPrefix(param.LotteryId, param.Addr, param.Round)
record, err := l.findLotteryBuyRecords(key)
......
......@@ -6,6 +6,7 @@ package types
import "errors"
// Errors for lottery
var (
ErrNoPrivilege = errors.New("ErrNoPrivilege")
ErrLotteryStatus = errors.New("ErrLotteryStatus")
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment