From cf5a6622897daeeb4f0af44c4377bf5462ea48a8 Mon Sep 17 00:00:00 2001 From: yuyuanshifu <747342561@qq.com> Date: Tue, 12 Jan 2021 17:55:20 +0800 Subject: [PATCH 1/4] CreateBlockchainAccount&NewRepo --- custom/conf/app.ini.sample | 3 + models/blockchain.go | 23 +++++++ models/models.go | 1 + models/repo.go | 10 +++ models/user.go | 17 ++++- modules/blockchain/blockchain.go | 14 ++++ modules/blockchain/resty.go | 145 +++++++++++++++++++++++++++++++++++++++ modules/setting/setting.go | 6 ++ modules/worker/task.go | 2 +- 9 files changed, 219 insertions(+), 2 deletions(-) create mode 100755 models/blockchain.go create mode 100755 modules/blockchain/blockchain.go create mode 100755 modules/blockchain/resty.go diff --git a/custom/conf/app.ini.sample b/custom/conf/app.ini.sample index d01866078..dcc40e1b1 100755 --- a/custom/conf/app.ini.sample +++ b/custom/conf/app.ini.sample @@ -1065,3 +1065,6 @@ HOST = http://192.168.202.90:3366/ HOST = http://192.168.207.34:39987 USER = cW4cMtH24eoWPE7X PASSWORD = 4BPmgvK2hb2Eywwyp4YZRY4B7yQf4DAC + +[blockchain] +HOST = http://192.168.207.84:3002/ diff --git a/models/blockchain.go b/models/blockchain.go new file mode 100755 index 000000000..df7af729b --- /dev/null +++ b/models/blockchain.go @@ -0,0 +1,23 @@ +package models + +import ( + "code.gitea.io/gitea/modules/timeutil" + "time" +) + +type BlockChain struct { + ID int64 `xorm:"pk autoincr"` + Contributor string `xorm:"INDEX NOT NULL"` + ContractAddress string `xorm:"INDEX NOT NULL"` + Action string `xorm:"INDEX"` + Amount int64 `xorm:"INDEX"` + UserID int64 `xorm:"INDEX"` + RepoID int64 `xorm:"INDEX"` + CreatedUnix timeutil.TimeStamp `xorm:"created"` + UpdatedUnix timeutil.TimeStamp `xorm:"updated"` + DeletedAt time.Time `xorm:"deleted"` + + User *User `xorm:"-"` + Repo *Repository `xorm:"-"` +} + diff --git a/models/models.go b/models/models.go index b709a2d28..4f7683774 100755 --- a/models/models.go +++ b/models/models.go @@ -128,6 +128,7 @@ func init() { new(Dataset), new(Cloudbrain), new(FileChunk), + new(BlockChain), ) gonicNames := []string{"SSL", "UID"} diff --git a/models/repo.go b/models/repo.go index 52a194ab0..862957787 100755 --- a/models/repo.go +++ b/models/repo.go @@ -6,6 +6,7 @@ package models import ( + "code.gitea.io/gitea/modules/blockchain" "context" "crypto/md5" "errors" @@ -195,6 +196,10 @@ type Repository struct { // Avatar: ID(10-20)-md5(32) - must fit into 64 symbols Avatar string `xorm:"VARCHAR(64)"` + //blockchain + ContractAddress string `xorm:"INDEX"` + Balance int64 `xorm:"NOT NULL DEFAULT 0"` + CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` } @@ -1051,6 +1056,11 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository) (err error return err } + _, err = blockchain.NewRepo(string(repo.ID), u.PublicKey, repo.Name) + if err != nil { + log.Error("newRepo failed:", err.Error()) + } + // insert units for repo var units = make([]RepoUnit, 0, len(DefaultRepoUnits)) for _, tp := range DefaultRepoUnits { diff --git a/models/user.go b/models/user.go index 29e1a5d9f..468d42822 100755 --- a/models/user.go +++ b/models/user.go @@ -6,6 +6,7 @@ package models import ( + "code.gitea.io/gitea/modules/blockchain" "container/list" "context" "crypto/md5" @@ -35,6 +36,7 @@ import ( "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" + "github.com/go-resty/resty/v2" "github.com/unknwon/com" "golang.org/x/crypto/argon2" "golang.org/x/crypto/bcrypt" @@ -91,6 +93,8 @@ var ( // Characters prohibited in a user name (anything except A-Za-z0-9_.-) alphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`) + + restyClient *resty.Client ) // User represents the object of individual and member of organization. @@ -167,7 +171,10 @@ type User struct { Theme string `xorm:"NOT NULL DEFAULT ''"` //CloudBrain - Token string `xorm:"VARCHAR(1024)"` + Token string `xorm:"VARCHAR(1024)"` + + //BlockChain + PublicKey string `xorm` } // SearchOrganizationsOptions options to filter organizations @@ -965,6 +972,14 @@ func CreateUser(u *User) (err error) { return err } + result, err := blockchain.CreateBlockchainAccount() + if err != nil { + log.Error("createBlockchainAccount failed:", err.Error()) + return err + } + + u.PublicKey = result.Payload["publickey"].(string) + sess := x.NewSession() defer sess.Close() if err = sess.Begin(); err != nil { diff --git a/modules/blockchain/blockchain.go b/modules/blockchain/blockchain.go new file mode 100755 index 000000000..6ebf701da --- /dev/null +++ b/modules/blockchain/blockchain.go @@ -0,0 +1,14 @@ +package blockchain + +const ( + Command = `pip3 install jupyterlab==2.2.5 -i https://pypi.tuna.tsinghua.edu.cn/simple;service ssh stop;jupyter lab --no-browser --ip=0.0.0.0 --allow-root --notebook-dir="/code" --port=80 --LabApp.token="" --LabApp.allow_origin="self https://cloudbrain.pcl.ac.cn"` + CodeMountPath = "/code" + DataSetMountPath = "/dataset" + ModelMountPath = "/model" + BenchMarkMountPath = "/benchmark" + TaskInfoName = "/taskInfo" + + SubTaskName = "task1" + + +) diff --git a/modules/blockchain/resty.go b/modules/blockchain/resty.go new file mode 100755 index 000000000..d4f06624c --- /dev/null +++ b/modules/blockchain/resty.go @@ -0,0 +1,145 @@ +package blockchain + +import ( + "fmt" + + "code.gitea.io/gitea/modules/setting" + "github.com/go-resty/resty/v2" +) + +var ( + restyClient *resty.Client +) + +const ( + UrlCreateAccount = "createAccount" + UrlGetBalance = "getBalance" + UrlNewRepo = "newRepo" + UrlContribute = "contribute" + + Success = 0 +) + +type CreateAccountResult struct { + Code int `json:"code"` + Msg string `json:"message"` + Payload map[string]interface{} `json:"data"` +} + +type GetBalanceResult struct { + Code int `json:"code"` + Msg string `json:"message"` + Payload map[string]interface{} `json:"data"` +} + +type NewRepoResult struct { + Code int `json:"code"` + Msg string `json:"message"` + Data string `json:"data"` +} + +type ContributeResult struct { + Code int `json:"code"` + Msg string `json:"message"` + Payload map[string]interface{} `json:"data"` +} + +func getRestyClient() *resty.Client { + if restyClient == nil { + restyClient = resty.New() + } + return restyClient +} + +func CreateBlockchainAccount() (*CreateAccountResult, error) { + client := getRestyClient() + var result CreateAccountResult + + res, err := client.R(). + SetHeader("Content-Type", "application/json"). + SetResult(&result). + Get(setting.BlockChainHost + UrlCreateAccount) + + if err != nil { + return nil, fmt.Errorf("resty create account: %s", err) + } + + if result.Code != Success { + return &result, fmt.Errorf("CreateAccount err: %s", res.String()) + } + + return &result, nil +} + +func NewRepo(repoID, publicKey, repoName string) (*NewRepoResult, error) { + client := getRestyClient() + var result NewRepoResult + + res, err := client.R(). + SetHeader("Accept", "application/json"). + SetQueryParams(map[string]string{ + "repoId" : repoID, + "creator" : publicKey, + "repoName" : repoName, + }). + SetResult(&result). + Get(setting.BlockChainHost + UrlNewRepo) + + if err != nil { + return nil, fmt.Errorf("resty newRepo: %v", err) + } + + if result.Code != Success { + return &result, fmt.Errorf("newRepo err: %s", res.String()) + } + + return &result, nil +} + +func GetBalance(contractAddress, contributor string) (*GetBalanceResult, error) { + client := getRestyClient() + var result GetBalanceResult + + res, err := client.R(). + SetHeader("Accept", "application/json"). + SetQueryParams(map[string]string{ + "contractAddress" : contractAddress, + "contributor" : contributor, + }). + SetResult(&result). + Get(setting.BlockChainHost + UrlGetBalance) + + if err != nil { + return nil, fmt.Errorf("resty getBalance: %v", err) + } + + if result.Code != Success { + return &result, fmt.Errorf("getBalance err: %s", res.String()) + } + + return &result, nil +} + +func Contribute(jobID string) (*ContributeResult, error) { + client := getRestyClient() + var result ContributeResult + + res, err := client.R(). + SetHeader("Accept", "application/json"). + SetQueryParams(map[string]string{ + "contractAddress" : "", + "contributor" : "", + }). + SetResult(&result). + Get(setting.BlockChainHost + UrlContribute) + + if err != nil { + return nil, fmt.Errorf("resty contribute: %v", err) + } + + if result.Code != Success { + return &result, fmt.Errorf("contribute err: %s", res.String()) + } + + return &result, nil +} diff --git a/modules/setting/setting.go b/modules/setting/setting.go index a71617e8d..3330e79cc 100755 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -443,6 +443,9 @@ var ( IsBenchmarkEnabled bool BenchmarkCode string BenchmarkServerHost string + + //blockchain config + BlockChainHost string ) // DateLang transforms standard language locale name to corresponding value in datetime plugin. @@ -1123,6 +1126,9 @@ func NewContext() { IsBenchmarkEnabled = sec.Key("ENABLED").MustBool(false) BenchmarkCode = sec.Key("BENCHMARKCODE").MustString("https://yangzhx:justfortest123@git.openi.org.cn/yangzhx/detection_benchmark_script.git") BenchmarkServerHost = sec.Key("HOST").MustString("http://192.168.202.90:3366/") + + sec = Cfg.Section("blockchain") + BlockChainHost = sec.Key("HOST").MustString("http://192.168.136.66:3302/") } func loadInternalToken(sec *ini.Section) string { diff --git a/modules/worker/task.go b/modules/worker/task.go index 073b16b92..48ba32c3e 100755 --- a/modules/worker/task.go +++ b/modules/worker/task.go @@ -14,7 +14,7 @@ const ( ) func SendDecompressTask(ctx context.Context, uuid string) error { - args := []tasks.Arg{{Name: "uuid", Type: "string", Value: uuid}} + args := []tasks.Arg{{Name: "uuid", Type: "string", Value: uuid},{}} task, err := tasks.NewSignature(DecompressTaskName, args) if err != nil { log.Error("NewSignature failed:", err.Error()) From 53279473d7f1421b046dfc28110c8c6d2c5ed53b Mon Sep 17 00:00:00 2001 From: yuyuanshifu <747342561@qq.com> Date: Wed, 13 Jan 2021 18:09:29 +0800 Subject: [PATCH 2/4] add notify interface --- models/blockchain.go | 49 ++++++++++++++++++++- models/repo.go | 8 ++++ modules/blockchain/resty.go | 9 ++-- routers/repo/blockchain.go | 101 ++++++++++++++++++++++++++++++++++++++++++++ routers/routes/routes.go | 5 +++ 5 files changed, 168 insertions(+), 4 deletions(-) create mode 100755 routers/repo/blockchain.go diff --git a/models/blockchain.go b/models/blockchain.go index df7af729b..122f3b218 100755 --- a/models/blockchain.go +++ b/models/blockchain.go @@ -2,14 +2,22 @@ package models import ( "code.gitea.io/gitea/modules/timeutil" + "fmt" "time" ) +type BlockChainCommitStatus int +const ( + BlockChainCommitInit BlockChainCommitStatus = iota + BlockChainCommitReady + BlockChainCommitFailed +) type BlockChain struct { ID int64 `xorm:"pk autoincr"` + CommitID string `xorm:"INDEX NOT NULL"` Contributor string `xorm:"INDEX NOT NULL"` ContractAddress string `xorm:"INDEX NOT NULL"` - Action string `xorm:"INDEX"` + Status BlockChainCommitStatus `xorm:"INDEX NOT NULL DEFAULT 0"` Amount int64 `xorm:"INDEX"` UserID int64 `xorm:"INDEX"` RepoID int64 `xorm:"INDEX"` @@ -21,3 +29,42 @@ type BlockChain struct { Repo *Repository `xorm:"-"` } +func getBlockChainByID(e Engine, id int64) (*BlockChain, error) { + blockChain := new(BlockChain) + has, err := e.ID(id).Get(blockChain) + if err != nil { + return nil, err + } else if !has { + return nil, fmt.Errorf("get block_chain by id failed(%d)", id) + } + return blockChain, nil +} + +func GetBlockChainByID(id int64) (*BlockChain, error) { + return getBlockChainByID(x, id) +} + +func getBlockChainByCommitID(e Engine, commitID string) (*BlockChain, error) { + blockChain := new(BlockChain) + has, err := e.Where("commit_id = ?", commitID).Get(blockChain) + if err != nil { + return nil, err + } else if !has { + return nil, fmt.Errorf("get block_chain by commitID failed(%s)", commitID) + } + return blockChain, nil +} + +func GetBlockChainByCommitID(commitID string) (*BlockChain, error) { + return getBlockChainByCommitID(x, commitID) +} + +func updateBlockChainCols(e Engine, blockChain *BlockChain, cols ...string) error { + _, err := e.ID(blockChain.ID).Cols(cols...).Update(blockChain) + return err +} + +func UpdateBlockChainCols(blockChain *BlockChain, cols ...string) error { + return updateBlockChainCols(x, blockChain, cols...) +} + diff --git a/models/repo.go b/models/repo.go index 862957787..d21b8ae80 100755 --- a/models/repo.go +++ b/models/repo.go @@ -135,6 +135,7 @@ func NewRepoContext() { // RepositoryStatus defines the status of repository type RepositoryStatus int +type RepoBlockChainStatus int // all kinds of RepositoryStatus const ( @@ -142,6 +143,12 @@ const ( RepositoryBeingMigrated // repository is migrating ) +const ( + RepoBlockChainInit RepoBlockChainStatus = iota + RepoBlockChainReady + RepoBlockChainFailed +) + // Repository represents a git repository. type Repository struct { ID int64 `xorm:"pk autoincr"` @@ -199,6 +206,7 @@ type Repository struct { //blockchain ContractAddress string `xorm:"INDEX"` Balance int64 `xorm:"NOT NULL DEFAULT 0"` + BlockChainStatus RepoBlockChainStatus `xorm:"NOT NULL DEFAULT 0"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` diff --git a/modules/blockchain/resty.go b/modules/blockchain/resty.go index d4f06624c..0f288b91a 100755 --- a/modules/blockchain/resty.go +++ b/modules/blockchain/resty.go @@ -120,15 +120,18 @@ func GetBalance(contractAddress, contributor string) (*GetBalanceResult, error) return &result, nil } -func Contribute(jobID string) (*ContributeResult, error) { +func Contribute(contractAddress, contributor, action, commitId string, codeLine int) (*ContributeResult, error) { client := getRestyClient() var result ContributeResult res, err := client.R(). SetHeader("Accept", "application/json"). SetQueryParams(map[string]string{ - "contractAddress" : "", - "contributor" : "", + "contractAddress" : contractAddress, + "contributor" : contributor, + "action" : action, + "commitId": commitId, + "amount": string(codeLine), }). SetResult(&result). Get(setting.BlockChainHost + UrlContribute) diff --git a/routers/repo/blockchain.go b/routers/repo/blockchain.go new file mode 100755 index 000000000..293167d2f --- /dev/null +++ b/routers/repo/blockchain.go @@ -0,0 +1,101 @@ +package repo + +import ( + "encoding/json" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" +) + +type BlockChainInitNotify struct { + RepoId int64 `json:"repoId"` + ContractAddress string `json:"contractAddress"` +} + +type BlockChainCommitNotify struct { + CommitID string `json:"commitId"` +} + +func HandleBlockChainInitNotify(ctx *context.Context) { + var req BlockChainInitNotify + data, _ := ctx.Req.Body().Bytes() + json.Unmarshal(data, &req) + + repo, err := models.GetRepositoryByID(req.RepoId) + if err != nil { + log.Error("GetRepositoryByID failed:", err.Error()) + ctx.JSON(200, map[string]string{ + "result_code" : "-1", + "message" : "internal error", + }) + return + } + + if repo.BlockChainStatus == models.RepoBlockChainReady && len(repo.ContractAddress) != 0 { + log.Error("the repo has been RepoBlockChainReady:", req.RepoId) + ctx.JSON(200, map[string]string{ + "result_code" : "-1", + "message" : "the repo has been RepoBlockChainReady", + }) + return + } + + repo.BlockChainStatus = models.RepoBlockChainReady + repo.ContractAddress = req.ContractAddress + + if err = models.UpdateRepositoryCols(repo, "block_chain_status", "contract_address"); err != nil { + log.Error("UpdateRepositoryCols failed:", err.Error()) + ctx.JSON(200, map[string]string{ + "result_code" : "-1", + "message" : "internal error", + }) + return + } + + ctx.JSON(200, map[string]string{ + "result_code": "0", + }) +} + +func HandleBlockChainCommitNotify(ctx *context.Context) { + //contributor := ctx.Query("contributor") + //contractAddress := ctx.Query("contractAddress") + var req BlockChainCommitNotify + data, _ := ctx.Req.Body().Bytes() + json.Unmarshal(data, &req) + + blockChain, err := models.GetBlockChainByCommitID(req.CommitID) + if err != nil { + log.Error("GetRepositoryByID failed:", err.Error()) + ctx.JSON(200, map[string]string{ + "result_code" : "-1", + "message" : "internal error", + }) + return + } + + if blockChain.Status == models.BlockChainCommitReady { + log.Error("the commit has been BlockChainCommitReady:", blockChain.RepoID) + ctx.JSON(200, map[string]string{ + "result_code" : "-1", + "message" : "the commit has been BlockChainCommitReady", + }) + return + } + + blockChain.Status = models.BlockChainCommitReady + + if err = models.UpdateBlockChainCols(blockChain, "status"); err != nil { + log.Error("UpdateBlockChainCols failed:", err.Error()) + ctx.JSON(200, map[string]string{ + "result_code" : "-1", + "message" : "internal error", + }) + return + } + + ctx.JSON(200, map[string]string{ + "result_code": "0", + }) +} diff --git a/routers/routes/routes.go b/routers/routes/routes.go index f40b55e2b..3d797a1e7 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -544,6 +544,11 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/action/:action", user.Action) }, reqSignIn) + m.Group("/blockchain", func() { + m.Post("/init_notify", repo.HandleBlockChainInitNotify) + m.Post("/commit_notify", repo.HandleBlockChainCommitNotify) + }) + if macaron.Env == macaron.DEV { m.Get("/template/*", dev.TemplatePreview) } From 909786315382d5c5efa5c2b5c40bc467c2c15e02 Mon Sep 17 00:00:00 2001 From: yuyuanshifu <747342561@qq.com> Date: Fri, 15 Jan 2021 08:57:38 +0800 Subject: [PATCH 3/4] cron check blockchain --- models/blockchain.go | 9 +++- models/repo.go | 9 +++- models/user.go | 10 ++++ modules/blockchain/resty.go | 4 +- modules/timer/timer.go | 6 +++ routers/repo/blockchain.go | 115 +++++++++++++++++++++++++++++++++++++------- 6 files changed, 132 insertions(+), 21 deletions(-) diff --git a/models/blockchain.go b/models/blockchain.go index 122f3b218..bd0bd95b9 100755 --- a/models/blockchain.go +++ b/models/blockchain.go @@ -9,7 +9,7 @@ import ( type BlockChainCommitStatus int const ( BlockChainCommitInit BlockChainCommitStatus = iota - BlockChainCommitReady + BlockChainCommitSuccess BlockChainCommitFailed ) type BlockChain struct { @@ -21,6 +21,7 @@ type BlockChain struct { Amount int64 `xorm:"INDEX"` UserID int64 `xorm:"INDEX"` RepoID int64 `xorm:"INDEX"` + TransactionHash string `xorm:"INDEX"` CreatedUnix timeutil.TimeStamp `xorm:"created"` UpdatedUnix timeutil.TimeStamp `xorm:"updated"` DeletedAt time.Time `xorm:"deleted"` @@ -68,3 +69,9 @@ func UpdateBlockChainCols(blockChain *BlockChain, cols ...string) error { return updateBlockChainCols(x, blockChain, cols...) } +func GetBlockChainUnSuccessCommits() ([]*BlockChain, error) { + blockChains := make([]*BlockChain, 0, 10) + return blockChains, x. + Where("status != ?", BlockChainCommitSuccess). + Find(&blockChains) +} diff --git a/models/repo.go b/models/repo.go index d21b8ae80..7cda4ce8a 100755 --- a/models/repo.go +++ b/models/repo.go @@ -145,7 +145,7 @@ const ( const ( RepoBlockChainInit RepoBlockChainStatus = iota - RepoBlockChainReady + RepoBlockChainSuccess RepoBlockChainFailed ) @@ -2406,3 +2406,10 @@ func updateRepositoryCols(e Engine, repo *Repository, cols ...string) error { func UpdateRepositoryCols(repo *Repository, cols ...string) error { return updateRepositoryCols(x, repo, cols...) } + +func GetBlockChainUnSuccessRepos() ([]*Repository, error) { + repos := make([]*Repository, 0, 10) + return repos, x. + Where("block_chain_status != ?", RepoBlockChainSuccess). + Find(&repos) +} diff --git a/models/user.go b/models/user.go index 468d42822..2b1195179 100755 --- a/models/user.go +++ b/models/user.go @@ -175,6 +175,7 @@ type User struct { //BlockChain PublicKey string `xorm` + PrivateKey string `xorm` } // SearchOrganizationsOptions options to filter organizations @@ -979,6 +980,7 @@ func CreateUser(u *User) (err error) { } u.PublicKey = result.Payload["publickey"].(string) + u.PrivateKey = result.Payload["privatekey"].(string) sess := x.NewSession() defer sess.Close() @@ -2040,3 +2042,11 @@ func SyncExternalUsers(ctx context.Context, updateExisting bool) error { } return nil } + +func GetBlockChainUnSuccessUsers() ([]*User, error) { + users := make([]*User, 0, 10) + err := x.Where("public_key is null"). + Or("private_key is null"). + Find(&users) + return users, err +} diff --git a/modules/blockchain/resty.go b/modules/blockchain/resty.go index 0f288b91a..060d63144 100755 --- a/modules/blockchain/resty.go +++ b/modules/blockchain/resty.go @@ -17,6 +17,8 @@ const ( UrlNewRepo = "newRepo" UrlContribute = "contribute" + ActionCommit = "commit" + Success = 0 ) @@ -35,7 +37,7 @@ type GetBalanceResult struct { type NewRepoResult struct { Code int `json:"code"` Msg string `json:"message"` - Data string `json:"data"` + //Data string `json:"data"` } type ContributeResult struct { diff --git a/modules/timer/timer.go b/modules/timer/timer.go index d0a850bca..3de4ee49c 100755 --- a/modules/timer/timer.go +++ b/modules/timer/timer.go @@ -10,5 +10,11 @@ func init() { c := cron.New() spec := "*/10 * * * *" c.AddFunc(spec, repo.HandleUnDecompressAttachment) + specCheckBlockChainUserSuccess := "*/10 * * * *" + c.AddFunc(specCheckBlockChainUserSuccess, repo.HandleBlockChainUnSuccessUsers) + specCheckRepoBlockChainSuccess := "*/5 * * * *" + c.AddFunc(specCheckRepoBlockChainSuccess, repo.HandleBlockChainUnSuccessRepos) + specCheckBlockChainCommitSuccess := "*/3 * * * *" + c.AddFunc(specCheckBlockChainCommitSuccess, repo.HandleBlockChainUnSuccessCommits) c.Start() } diff --git a/routers/repo/blockchain.go b/routers/repo/blockchain.go index 293167d2f..1fa376fd8 100755 --- a/routers/repo/blockchain.go +++ b/routers/repo/blockchain.go @@ -2,8 +2,10 @@ package repo import ( "encoding/json" + "strconv" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/blockchain" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" ) @@ -15,6 +17,7 @@ type BlockChainInitNotify struct { type BlockChainCommitNotify struct { CommitID string `json:"commitId"` + TransactionHash string `json:"txHash"` } func HandleBlockChainInitNotify(ctx *context.Context) { @@ -26,76 +29,152 @@ func HandleBlockChainInitNotify(ctx *context.Context) { if err != nil { log.Error("GetRepositoryByID failed:", err.Error()) ctx.JSON(200, map[string]string{ - "result_code" : "-1", + "code" : "-1", "message" : "internal error", }) return } - if repo.BlockChainStatus == models.RepoBlockChainReady && len(repo.ContractAddress) != 0 { - log.Error("the repo has been RepoBlockChainReady:", req.RepoId) + if repo.BlockChainStatus == models.RepoBlockChainSuccess && len(repo.ContractAddress) != 0 { + log.Error("the repo has been RepoBlockChainSuccess:", req.RepoId) ctx.JSON(200, map[string]string{ - "result_code" : "-1", - "message" : "the repo has been RepoBlockChainReady", + "code" : "-1", + "message" : "the repo has been RepoBlockChainSuccess", }) return } - repo.BlockChainStatus = models.RepoBlockChainReady + repo.BlockChainStatus = models.RepoBlockChainSuccess repo.ContractAddress = req.ContractAddress if err = models.UpdateRepositoryCols(repo, "block_chain_status", "contract_address"); err != nil { log.Error("UpdateRepositoryCols failed:", err.Error()) ctx.JSON(200, map[string]string{ - "result_code" : "-1", + "code" : "-1", "message" : "internal error", }) return } ctx.JSON(200, map[string]string{ - "result_code": "0", + "code": "0", + "message": "", }) } func HandleBlockChainCommitNotify(ctx *context.Context) { - //contributor := ctx.Query("contributor") - //contractAddress := ctx.Query("contractAddress") var req BlockChainCommitNotify data, _ := ctx.Req.Body().Bytes() - json.Unmarshal(data, &req) + if err := json.Unmarshal(data, &req); err != nil { + log.Error("json.Unmarshal failed:", err.Error()) + ctx.JSON(200, map[string]string{ + "code" : "-1", + "message" : "response data error", + }) + return + } blockChain, err := models.GetBlockChainByCommitID(req.CommitID) if err != nil { log.Error("GetRepositoryByID failed:", err.Error()) ctx.JSON(200, map[string]string{ - "result_code" : "-1", + "code" : "-1", "message" : "internal error", }) return } - if blockChain.Status == models.BlockChainCommitReady { + if blockChain.Status == models.BlockChainCommitSuccess { log.Error("the commit has been BlockChainCommitReady:", blockChain.RepoID) ctx.JSON(200, map[string]string{ - "result_code" : "-1", + "code" : "-1", "message" : "the commit has been BlockChainCommitReady", }) return } - blockChain.Status = models.BlockChainCommitReady + blockChain.Status = models.BlockChainCommitSuccess + blockChain.TransactionHash = req.TransactionHash - if err = models.UpdateBlockChainCols(blockChain, "status"); err != nil { + if err = models.UpdateBlockChainCols(blockChain, "status", "transaction_hash"); err != nil { log.Error("UpdateBlockChainCols failed:", err.Error()) ctx.JSON(200, map[string]string{ - "result_code" : "-1", + "code" : "-1", "message" : "internal error", }) return } ctx.JSON(200, map[string]string{ - "result_code": "0", + "code": "0", + "message": "", }) } + +func HandleBlockChainUnSuccessRepos() { + repos, err := models.GetBlockChainUnSuccessRepos() + if err != nil { + log.Error("GetBlockChainUnSuccessRepos failed:", err.Error()) + return + } + + for _, repo := range repos { + err = repo.GetOwner() + if err != nil { + log.Error("GetOwner(%s) failed:%s", repo.Name, err.Error()) + continue + } + if len(repo.Owner.PrivateKey) == 0 || len(repo.Owner.PublicKey) == 0 { + log.Error("the user has not been init in block_chain:", repo.Owner.Name) + continue + } + strRepoID := strconv.FormatInt(repo.ID, 10) + log.Info(strRepoID) + _, err = blockchain.NewRepo(strRepoID, repo.Owner.PublicKey, repo.Name) + if err != nil { + log.Error("blockchain.NewRepo(%s) failed:%s", strRepoID, err.Error()) + } + } + + return +} + +func HandleBlockChainUnSuccessCommits() { + blockChains, err := models.GetBlockChainUnSuccessCommits() + if err != nil { + log.Error("GetBlockChainUnSuccessCommits failed:", err.Error()) + return + } + + for _, block_chain := range blockChains { + _, err = blockchain.Contribute(block_chain.ContractAddress, block_chain.Contributor, blockchain.ActionCommit, block_chain.CommitID, int(block_chain.Amount)) + if err != nil { + log.Error("blockchain.Contribute(%s) failed:%s", block_chain.CommitID, err.Error()) + } + } + + return +} + +func HandleBlockChainUnSuccessUsers() { + users, err := models.GetBlockChainUnSuccessUsers() + if err != nil { + log.Error("GetBlockChainUnSuccessUsers failed:", err.Error()) + return + } + + for _, user := range users { + result, err := blockchain.CreateBlockchainAccount() + if err != nil { + log.Error("blockchain.CreateBlockchainAccount(%s) failed:%s", user.Name, err.Error()) + continue + } + + user.PublicKey = result.Payload["publickey"].(string) + user.PrivateKey = result.Payload["privatekey"].(string) + + models.UpdateUser(user) + } + + return +} From c427335bf9553fb9cca3c0fd15fbf0542c28dee2 Mon Sep 17 00:00:00 2001 From: yuyuanshifu <747342561@qq.com> Date: Fri, 15 Jan 2021 15:41:13 +0800 Subject: [PATCH 4/4] commit interface --- custom/conf/app.ini.sample | 1 + models/action.go | 11 +++++++ models/blockchain.go | 9 ++++++ modules/setting/setting.go | 2 ++ modules/timer/timer.go | 7 +++++ routers/repo/blockchain.go | 78 +++++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 104 insertions(+), 4 deletions(-) mode change 100644 => 100755 models/action.go diff --git a/custom/conf/app.ini.sample b/custom/conf/app.ini.sample index dcc40e1b1..13a3d4aeb 100755 --- a/custom/conf/app.ini.sample +++ b/custom/conf/app.ini.sample @@ -1068,3 +1068,4 @@ PASSWORD = 4BPmgvK2hb2Eywwyp4YZRY4B7yQf4DAC [blockchain] HOST = http://192.168.207.84:3002/ +COMMIT_VALID_DATE = 2021-01-15 diff --git a/models/action.go b/models/action.go old mode 100644 new mode 100755 index fd49c6d4e..a29ed343d --- a/models/action.go +++ b/models/action.go @@ -67,6 +67,7 @@ type Action struct { IsDeleted bool `xorm:"INDEX NOT NULL DEFAULT false"` RefName string IsPrivate bool `xorm:"INDEX NOT NULL DEFAULT false"` + IsTransformed bool `xorm:"INDEX NOT NULL DEFAULT false"` Content string `xorm:"TEXT"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` } @@ -344,3 +345,13 @@ func GetFeeds(opts GetFeedsOptions) ([]*Action, error) { return actions, nil } + +func GetUnTransformedActions() ([]*Action, error) { + actions := make([]*Action, 0, 10) + err := x.Where("op_type = ?", ActionCommitRepo). + And("content != ''"). + And("is_transformed = ?", false). + And("to_timestamp(created_unix) >= ?", setting.CommitValidDate). + Find(&actions) + return actions, err +} diff --git a/models/blockchain.go b/models/blockchain.go index bd0bd95b9..a84636a5b 100755 --- a/models/blockchain.go +++ b/models/blockchain.go @@ -75,3 +75,12 @@ func GetBlockChainUnSuccessCommits() ([]*BlockChain, error) { Where("status != ?", BlockChainCommitSuccess). Find(&blockChains) } + +func InsertBlockChain(blockChain *BlockChain) (_ *BlockChain, err error) { + + if _, err := x.Insert(blockChain); err != nil { + return nil, err + } + + return blockChain, nil +} diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 3330e79cc..f3888b9e7 100755 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -446,6 +446,7 @@ var ( //blockchain config BlockChainHost string + CommitValidDate string ) // DateLang transforms standard language locale name to corresponding value in datetime plugin. @@ -1129,6 +1130,7 @@ func NewContext() { sec = Cfg.Section("blockchain") BlockChainHost = sec.Key("HOST").MustString("http://192.168.136.66:3302/") + CommitValidDate = sec.Key("COMMIT_VALID_DATE").MustString("2021-01-15") } func loadInternalToken(sec *ini.Section) string { diff --git a/modules/timer/timer.go b/modules/timer/timer.go index 3de4ee49c..60aaa7498 100755 --- a/modules/timer/timer.go +++ b/modules/timer/timer.go @@ -8,12 +8,19 @@ import ( func init() { c := cron.New() + spec := "*/10 * * * *" c.AddFunc(spec, repo.HandleUnDecompressAttachment) + specCheckBlockChainUserSuccess := "*/10 * * * *" c.AddFunc(specCheckBlockChainUserSuccess, repo.HandleBlockChainUnSuccessUsers) + specCheckRepoBlockChainSuccess := "*/5 * * * *" c.AddFunc(specCheckRepoBlockChainSuccess, repo.HandleBlockChainUnSuccessRepos) + + specCheckUnTransformedActions := "*/1 * * * *" + c.AddFunc(specCheckUnTransformedActions, repo.HandleUnTransformedActions) + specCheckBlockChainCommitSuccess := "*/3 * * * *" c.AddFunc(specCheckBlockChainCommitSuccess, repo.HandleBlockChainUnSuccessCommits) c.Start() diff --git a/routers/repo/blockchain.go b/routers/repo/blockchain.go index 1fa376fd8..9aa705574 100755 --- a/routers/repo/blockchain.go +++ b/routers/repo/blockchain.go @@ -1,6 +1,7 @@ package repo import ( + "code.gitea.io/gitea/modules/repository" "encoding/json" "strconv" @@ -121,7 +122,7 @@ func HandleBlockChainUnSuccessRepos() { for _, repo := range repos { err = repo.GetOwner() if err != nil { - log.Error("GetOwner(%s) failed:%s", repo.Name, err.Error()) + log.Error("GetOwner(%s) failed:%v", repo.Name, err) continue } if len(repo.Owner.PrivateKey) == 0 || len(repo.Owner.PublicKey) == 0 { @@ -132,7 +133,7 @@ func HandleBlockChainUnSuccessRepos() { log.Info(strRepoID) _, err = blockchain.NewRepo(strRepoID, repo.Owner.PublicKey, repo.Name) if err != nil { - log.Error("blockchain.NewRepo(%s) failed:%s", strRepoID, err.Error()) + log.Error("blockchain.NewRepo(%s) failed:%v", strRepoID, err) } } @@ -149,7 +150,7 @@ func HandleBlockChainUnSuccessCommits() { for _, block_chain := range blockChains { _, err = blockchain.Contribute(block_chain.ContractAddress, block_chain.Contributor, blockchain.ActionCommit, block_chain.CommitID, int(block_chain.Amount)) if err != nil { - log.Error("blockchain.Contribute(%s) failed:%s", block_chain.CommitID, err.Error()) + log.Error("blockchain.Contribute(%s) failed:%v", block_chain.CommitID, err) } } @@ -166,7 +167,7 @@ func HandleBlockChainUnSuccessUsers() { for _, user := range users { result, err := blockchain.CreateBlockchainAccount() if err != nil { - log.Error("blockchain.CreateBlockchainAccount(%s) failed:%s", user.Name, err.Error()) + log.Error("blockchain.CreateBlockchainAccount(%s) failed:%v", user.Name, err) continue } @@ -178,3 +179,72 @@ func HandleBlockChainUnSuccessUsers() { return } + +func HandleUnTransformedActions() { + actions, err := models.GetUnTransformedActions() + if err != nil { + log.Error("GetUnTransformedActions failed:", err.Error()) + return + } + + isTransformed := true + + for _, action := range actions { + var content repository.PushCommits + err = json.Unmarshal([]byte(action.Content), &content) + if err != nil { + isTransformed = false + log.Error("json.Unmarshal action.Content(%s) failed:%v", action.Content, err) + break + } + + repo, err := models.GetRepositoryByID(action.RepoID) + if err != nil { + isTransformed = false + log.Error("GetRepositoryByID(%d) failed:%v", action.RepoID, err) + break + } + + if repo.ContractAddress == "" { + isTransformed = false + log.Error("the repo(%s) has not been initialized in block_chain", repo.Name) + break + } + + for _, commit := range content.Commits { + _, err = models.GetBlockChainByCommitID(commit.Sha1) + if err == nil { + log.Info("the commit(%s) has been transformed", commit.Sha1) + continue + } + + user, err := models.GetUserByName(commit.CommitterName) + if err != nil { + isTransformed = false + log.Error("GetUserByName(%s) failed:%v", commit.CommitterName, err) + break + } + + blockChain := models.BlockChain{ + CommitID : commit.Sha1, + Contributor : user.PublicKey, + ContractAddress : repo.ContractAddress, + Status : models.BlockChainCommitInit, + Amount : 1, + UserID : action.UserID, + RepoID : action.RepoID, + } + _, err = models.InsertBlockChain(&blockChain) + if err != nil { + isTransformed = false + log.Error("InsertBlockChain(%s) failed:%v", commit.Sha1, err) + break + } + } + + } + + log.Info("", isTransformed) + + return +}