Skip to content
This repository has been archived by the owner on Mar 21, 2024. It is now read-only.

Commit

Permalink
fix_tracer_in_test (#2110)
Browse files Browse the repository at this point in the history
* fix_tracer_in_test

* remove debug print

* remove fmt

* remove fmt import
  • Loading branch information
shenao78 authored Sep 17, 2021
1 parent 17718f8 commit 14165ad
Show file tree
Hide file tree
Showing 8 changed files with 214 additions and 119 deletions.
15 changes: 11 additions & 4 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"sync"
"time"

"github.com/bytom/bytom/contract"
"github.com/kr/secureheader"
log "github.com/sirupsen/logrus"
cmn "github.com/tendermint/tmlibs/common"
Expand Down Expand Up @@ -52,12 +53,12 @@ type Response struct {
Data interface{} `json:"data,omitempty"`
}

//NewSuccessResponse success response
// NewSuccessResponse success response
func NewSuccessResponse(data interface{}) Response {
return Response{Status: SUCCESS, Data: data}
}

//FormatErrResp format error response
// FormatErrResp format error response
func FormatErrResp(err error) (response Response) {
response = Response{Status: FAIL}
root := errors.Root(err)
Expand All @@ -82,7 +83,7 @@ func FormatErrResp(err error) (response Response) {
return response
}

//NewErrorResponse error response
// NewErrorResponse error response
func NewErrorResponse(err error) Response {
response := FormatErrResp(err)
return response
Expand All @@ -109,6 +110,7 @@ type API struct {
wallet *wallet.Wallet
accessTokens *accesstoken.CredentialStore
chain *protocol.Chain
contractTracer *contract.TraceService
server *http.Server
handler http.Handler
blockProposer *blockproposer.BlockProposer
Expand Down Expand Up @@ -178,11 +180,12 @@ type NetSync interface {
}

// NewAPI create and initialize the API
func NewAPI(sync NetSync, wallet *wallet.Wallet, blockProposer *blockproposer.BlockProposer, chain *protocol.Chain, config *cfg.Config, token *accesstoken.CredentialStore, dispatcher *event.Dispatcher, notificationMgr *websocket.WSNotificationManager) *API {
func NewAPI(sync NetSync, wallet *wallet.Wallet, blockProposer *blockproposer.BlockProposer, chain *protocol.Chain, traceService *contract.TraceService, config *cfg.Config, token *accesstoken.CredentialStore, dispatcher *event.Dispatcher, notificationMgr *websocket.WSNotificationManager) *API {
api := &API{
sync: sync,
wallet: wallet,
chain: chain,
contractTracer: traceService,
accessTokens: token,
blockProposer: blockProposer,
eventDispatcher: dispatcher,
Expand Down Expand Up @@ -297,6 +300,10 @@ func (a *API) buildHandler() {
m.Handle("/get-merkle-proof", jsonHandler(a.getMerkleProof))
m.Handle("/get-vote-result", jsonHandler(a.getVoteResult))

m.Handle("/get-contract-instance", jsonHandler(a.getContractInstance))
m.Handle("/create-contract-instance", jsonHandler(a.createContractInstance))
m.Handle("/remove-contract-instance", jsonHandler(a.removeContractInstance))

m.HandleFunc("/websocket-subscribe", a.websocketHandler)

handler := walletHandler(m, walletEnable)
Expand Down
50 changes: 50 additions & 0 deletions api/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/bytom/bytom/crypto/sha3pool"
chainjson "github.com/bytom/bytom/encoding/json"
"github.com/bytom/bytom/errors"
"github.com/bytom/bytom/protocol/bc"
"github.com/bytom/bytom/protocol/vm/vmutil"
)

Expand Down Expand Up @@ -105,3 +106,52 @@ func (a *API) listContracts(_ context.Context) Response {

return NewSuccessResponse(cs)
}

type ContractInstance struct {
UTXOs []*contract.UTXO `json:"utxos"`
TxHash *bc.Hash `json:"tx_hash"`
Status contract.Status `json:"status"`
Unconfirmed []*contract.TreeNode `json:"unconfirmed"`
}

func (a *API) getContractInstance(_ context.Context, ins struct {
TraceID string `json:"trace_id"`
}) Response {
instance, err := a.contractTracer.GetInstance(ins.TraceID)
if err != nil {
return NewErrorResponse(err)
}

return NewSuccessResponse(&ContractInstance{
UTXOs: instance.UTXOs,
TxHash: instance.TxHash,
Status: instance.Status,
Unconfirmed: instance.Unconfirmed,
})
}

func (a *API) createContractInstance(_ context.Context, ins struct {
TxHash chainjson.HexBytes `json:"tx_hash"`
BlockHash chainjson.HexBytes `json:"block_hash"`
}) Response {
var txHash, blockHash [32]byte
copy(txHash[:], ins.TxHash)
copy(blockHash[:], ins.BlockHash)

traceIDs, err := a.contractTracer.CreateInstance(bc.NewHash(txHash), bc.NewHash(blockHash))
if err != nil {
return NewErrorResponse(err)
}

return NewSuccessResponse(traceIDs)
}

func (a *API) removeContractInstance(_ context.Context, ins struct {
TraceID string `json:"trace_id"`
}) Response {
if err := a.contractTracer.RemoveInstance(ins.TraceID); err != nil {
return NewErrorResponse(err)
}

return NewSuccessResponse(nil)
}
127 changes: 76 additions & 51 deletions contract/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,29 @@ const (
OffChain
)

type treeNode struct {
TxHash bc.Hash
UTXOs []*UTXO
Children []*treeNode
type TreeNode struct {
TxHash bc.Hash `json:"tx_hash"`
UTXOs []*UTXO `json:"utxos"`
Children []*TreeNode `json:"children"`
}

type Instance struct {
TraceID string
UTXOs []*UTXO
Unconfirmed []*treeNode
Status Status
ScannedHash bc.Hash
ScannedHeight uint64
TraceID string `json:"trace_id"`
UTXOs []*UTXO `json:"utxos"`
TxHash *bc.Hash `json:"tx_hash"`
Status Status `json:"status"`
ScannedHash bc.Hash `json:"scanned_hash"`
ScannedHeight uint64 `json:"scanned_height"`
Unconfirmed []*TreeNode
}

func newInstance(inUTXOs, outUTXOs []*UTXO) *Instance {
func newInstance(inUTXOs, outUTXOs []*UTXO, txHash bc.Hash, block *types.Block) *Instance {
inst := &Instance{
TraceID: uuid.New().String(),
UTXOs: outUTXOs,
TraceID: uuid.New().String(),
TxHash: &txHash,
UTXOs: outUTXOs,
ScannedHeight: block.Height,
ScannedHash: block.Hash(),
}
inst.Status = Lagging
if len(outUTXOs) == 0 {
Expand All @@ -43,20 +47,32 @@ func newInstance(inUTXOs, outUTXOs []*UTXO) *Instance {
return inst
}

func (i *Instance) transferTo(newUTXOs []*UTXO) *Instance {
func (i *Instance) transferTo(newUTXOs []*UTXO, txHash bc.Hash) *Instance {
inst := &Instance{
TraceID: i.TraceID,
Status: i.Status,
Unconfirmed: i.Unconfirmed,
UTXOs: newUTXOs,
TxHash: &txHash,
}
if len(newUTXOs) == 0 {
inst.Status = Finalized
inst.UTXOs = i.UTXOs
}
inst.confirmTx(txHash)
return inst
}

func (i *Instance) rollbackTo(newUTXOs []*UTXO) *Instance {
return &Instance{
TraceID: i.TraceID,
Status: InSync,
UTXOs: newUTXOs,
TxHash: nil,
Unconfirmed: nil,
}
}

func (i *Instance) confirmTx(txHash bc.Hash) {
for _, node := range i.Unconfirmed {
if node.TxHash == txHash {
Expand All @@ -67,72 +83,81 @@ func (i *Instance) confirmTx(txHash bc.Hash) {
i.Unconfirmed = nil
}

type instanceTable struct {
type instanceIndex struct {
traceIdToInst map[string]*Instance
utxoHashToInst map[bc.Hash]*Instance
}

func newInstanceTable() *instanceTable {
return &instanceTable{
func newInstanceIndex() *instanceIndex {
return &instanceIndex{
traceIdToInst: make(map[string]*Instance),
utxoHashToInst: make(map[bc.Hash]*Instance),
}
}

func (i *instanceTable) getByID(id string) *Instance {
func (i *instanceIndex) getAll() []*Instance {
var instances []*Instance
for _, inst := range i.traceIdToInst {
instances = append(instances, inst)
}
return instances
}

func (i *instanceIndex) getByID(id string) *Instance {
return i.traceIdToInst[id]
}

func (i *instanceTable) getByUTXO(utxoHash bc.Hash) *Instance {
func (i *instanceIndex) getByUTXO(utxoHash bc.Hash) *Instance {
return i.utxoHashToInst[utxoHash]
}

func (i *instanceTable) save(newInst *Instance) {
func (i *instanceIndex) add(instance *Instance) {
i.traceIdToInst[instance.TraceID] = instance
for _, utxo := range instance.UTXOs {
i.utxoHashToInst[utxo.Hash] = instance
}
}

func (i *instanceIndex) save(newInst *Instance) {
if old, ok := i.traceIdToInst[newInst.TraceID]; ok {
for _, utxo := range old.UTXOs {
delete(i.utxoHashToInst, utxo.hash)
delete(i.utxoHashToInst, utxo.Hash)
}
}
i.add(newInst)
}

func (i *instanceTable) remove(id string) {
func (i *instanceIndex) remove(id string) {
if inst, ok := i.traceIdToInst[id]; ok {
delete(i.traceIdToInst, id)
for _, utxo := range inst.UTXOs {
delete(i.utxoHashToInst, utxo.hash)
delete(i.utxoHashToInst, utxo.Hash)
}
}
}

func (i *instanceTable) add(instance *Instance) {
i.traceIdToInst[instance.TraceID] = instance
for _, utxo := range instance.UTXOs {
i.utxoHashToInst[utxo.hash] = instance
}
}

type UTXO struct {
hash bc.Hash
assetID bc.AssetID
amount uint64
program []byte
sourceID bc.Hash
sourcePos uint64
stateData [][]byte
Hash bc.Hash `json:"hash"`
AssetID bc.AssetID `json:"asset_id"`
Amount uint64 `json:"amount"`
Program []byte `json:"program"`
SourceID bc.Hash `json:"source_id"`
SourcePos uint64 `json:"source_pos"`
StateData [][]byte `json:"state_data"`
}

func inputToUTXO(tx *types.Tx, index int) *UTXO {
input := tx.Inputs[index]
outputID, _ := input.SpentOutputID()
spendInput := input.TypedInput.(*types.SpendInput)
return &UTXO{
hash: tx.InputIDs[index],
assetID: input.AssetID(),
amount: input.Amount(),
program: input.ControlProgram(),
sourceID: spendInput.SourceID,
sourcePos: spendInput.SourcePosition,
stateData: spendInput.StateData,
Hash: outputID,
AssetID: input.AssetID(),
Amount: input.Amount(),
Program: input.ControlProgram(),
SourceID: spendInput.SourceID,
SourcePos: spendInput.SourcePosition,
StateData: spendInput.StateData,
}
}

Expand All @@ -141,12 +166,12 @@ func outputToUTXO(tx *types.Tx, index int) *UTXO {
outputID := tx.OutputID(index)
originalOutput, _ := tx.OriginalOutput(*outputID)
return &UTXO{
hash: *outputID,
assetID: *output.AssetId,
amount: output.Amount,
program: output.ControlProgram,
sourceID: *originalOutput.Source.Ref,
sourcePos: uint64(index),
stateData: originalOutput.StateData,
Hash: *outputID,
AssetID: *output.AssetId,
Amount: output.Amount,
Program: output.ControlProgram,
SourceID: *originalOutput.Source.Ref,
SourcePos: uint64(index),
StateData: originalOutput.StateData,
}
}
Loading

0 comments on commit 14165ad

Please sign in to comment.