diff --git a/action/protocol/execution/testdata-istanbul/iip15-manager.json b/action/protocol/execution/testdata-istanbul/iip15-manager.json index 8851533f20..0842398cfa 100644 --- a/action/protocol/execution/testdata-istanbul/iip15-manager.json +++ b/action/protocol/execution/testdata-istanbul/iip15-manager.json @@ -12,12 +12,12 @@ "rawPrivateKey": "febab1e4efeeeb87ce19da49f2648aa824da34f7f7f2688a7fcd45d1f61f0ce6" }], "deployments": [{ - "rawByteCode": "608060405234801561001057600080fd5b5061002d61002261003260201b60201c565b61003a60201b60201c565b6100fe565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61108f8061010d6000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063a0ee93181161005b578063a0ee931814610101578063c375c2ef1461011d578063d7e5fbf314610139578063f2fde38b1461015557610088565b806307f7aafb1461008d5780630ad1c2fa146100a9578063715018a6146100d95780638da5cb5b146100e3575b600080fd5b6100a760048036038101906100a29190610bb9565b610171565b005b6100c360048036038101906100be9190610bb9565b6102fa565b6040516100d09190610e93565b60405180910390f35b6100e16103c4565b005b6100eb6103d8565b6040516100f89190610d6f565b60405180910390f35b61011b60048036038101906101169190610bb9565b610401565b005b61013760048036038101906101329190610bb9565b610589565b005b610153600480360381019061014e9190610be2565b610720565b005b61016f600480360381019061016a9190610bb9565b6109a4565b005b610179610a28565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610250576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024790610dd3565b60405180910390fd5b8060000160149054906101000a900460ff16156102a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161029990610e73565b60405180910390fd5b60018160000160146101000a81548160ff0219169083151502179055507faf42961ad755cade79794d4122cb0afedc32bf55a0c716dd085fbee2afc6ac55826040516102ee9190610d6f565b60405180910390a15050565b610302610b72565b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900460ff1615151515815250509050919050565b6103cc610a28565b6103d66000610aa6565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610409610a28565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156104e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d790610dd3565b60405180910390fd5b8060000160149054906101000a900460ff16610531576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052890610df3565b60405180910390fd5b60008160000160146101000a81548160ff0219169083151502179055507f97fd609c50722d17887170f33e7e8ae86421f650c02b82d6fe1e4ac9ef2842d48260405161057d9190610d6f565b60405180910390a15050565b610591610a28565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610668576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161065f90610dd3565b60405180910390fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a81549060ff021916905550507f8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b565826040516107149190610d6f565b60405180910390a15050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610790576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161078790610e53565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610800576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f790610e13565b60405180910390fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160149054906101000a900460ff1615610890576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088790610e73565b60405180910390fd5b60405180604001604052808273ffffffffffffffffffffffffffffffffffffffff16815260200160001515815250600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548160ff0219169083151502179055509050507f768fb430a0d4b201cb764ab221c316dd14d8babf2e4b2348e05964c6565318b68282604051610998929190610d8a565b60405180910390a15050565b6109ac610a28565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610a1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1390610db3565b60405180910390fd5b610a2581610aa6565b50565b610a30610b6a565b73ffffffffffffffffffffffffffffffffffffffff16610a4e6103d8565b73ffffffffffffffffffffffffffffffffffffffff1614610aa4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9b90610e33565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020016000151581525090565b600081359050610bb381611042565b92915050565b600060208284031215610bcb57600080fd5b6000610bd984828501610ba4565b91505092915050565b60008060408385031215610bf557600080fd5b6000610c0385828601610ba4565b9250506020610c1485828601610ba4565b9150509250929050565b610c2781610ebf565b82525050565b610c3681610ebf565b82525050565b610c4581610ed1565b82525050565b6000610c58602683610eae565b9150610c6382610efd565b604082019050919050565b6000610c7b601a83610eae565b9150610c8682610f4c565b602082019050919050565b6000610c9e601883610eae565b9150610ca982610f75565b602082019050919050565b6000610cc1602083610eae565b9150610ccc82610f9e565b602082019050919050565b6000610ce4602083610eae565b9150610cef82610fc7565b602082019050919050565b6000610d07601f83610eae565b9150610d1282610ff0565b602082019050919050565b6000610d2a601c83610eae565b9150610d3582611019565b602082019050919050565b604082016000820151610d566000850182610c1e565b506020820151610d696020850182610c3c565b50505050565b6000602082019050610d846000830184610c2d565b92915050565b6000604082019050610d9f6000830185610c2d565b610dac6020830184610c2d565b9392505050565b60006020820190508181036000830152610dcc81610c4b565b9050919050565b60006020820190508181036000830152610dec81610c6e565b9050919050565b60006020820190508181036000830152610e0c81610c91565b9050919050565b60006020820190508181036000830152610e2c81610cb4565b9050919050565b60006020820190508181036000830152610e4c81610cd7565b9050919050565b60006020820190508181036000830152610e6c81610cfa565b9050919050565b60006020820190508181036000830152610e8c81610d1d565b9050919050565b6000604082019050610ea86000830184610d40565b92915050565b600082825260208201905092915050565b6000610eca82610edd565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f436f6e7472616374206973206e6f742072656769737465726564000000000000600082015250565b7f436f6e7472616374206973206e6f7420617070726f7665640000000000000000600082015250565b7f526563697069656e7420616464726573732063616e6e6f74206265207a65726f600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f436f6e747261637420616464726573732063616e6e6f74206265207a65726f00600082015250565b7f436f6e747261637420697320616c726561647920617070726f76656400000000600082015250565b61104b81610ebf565b811461105657600080fd5b5056fea264697066735822122078ad584b1d2be93e1239d9997b2a4be465fb7c6edc9d5302878b3dd92587f49464736f6c63430008010033", + "rawByteCode": "608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6107be8061007e6000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063a0ee93181161005b578063a0ee93181461014d578063c375c2ef14610160578063d7e5fbf314610173578063f2fde38b1461018657600080fd5b806307f7aafb1461008d5780630ad1c2fa146100a2578063715018a61461012a5780638da5cb5b14610132575b600080fd5b6100a061009b3660046106fc565b610199565b005b6100ff6100b03660046106fc565b604080518082018252600080825260209182018190526001600160a01b039384168152600182528290208251808401909352549283168252600160a01b90920460ff1615159181019190915290565b6040805182516001600160a01b03168152602092830151151592810192909252015b60405180910390f35b6100a061028f565b6000546040516001600160a01b039091168152602001610121565b6100a061015b3660046106fc565b6102a3565b6100a061016e3660046106fc565b610381565b6100a061018136600461071e565b61041a565b6100a06101943660046106fc565b6105bd565b6101a1610636565b6001600160a01b03808216600090815260016020526040902080549091166101e45760405162461bcd60e51b81526004016101db90610751565b60405180910390fd5b8054600160a01b900460ff161561023d5760405162461bcd60e51b815260206004820152601c60248201527f436f6e747261637420697320616c726561647920617070726f7665640000000060448201526064016101db565b805460ff60a01b1916600160a01b1781556040516001600160a01b03831681527faf42961ad755cade79794d4122cb0afedc32bf55a0c716dd085fbee2afc6ac55906020015b60405180910390a15050565b610297610636565b6102a16000610690565b565b6102ab610636565b6001600160a01b03808216600090815260016020526040902080549091166102e55760405162461bcd60e51b81526004016101db90610751565b8054600160a01b900460ff1661033d5760405162461bcd60e51b815260206004820152601860248201527f436f6e7472616374206973206e6f7420617070726f766564000000000000000060448201526064016101db565b805460ff60a01b191681556040516001600160a01b03831681527f50132537991c16a2d6bbd27114ed077fb8c757768dcbb2c3c5736f1b1ed3cc3e90602001610283565b610389610636565b6001600160a01b03808216600090815260016020526040902080549091166103c35760405162461bcd60e51b81526004016101db90610751565b6001600160a01b03821660008181526001602090815260409182902080546001600160a81b031916905590519182527f8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b5659101610283565b6001600160a01b0382166104705760405162461bcd60e51b815260206004820152601f60248201527f436f6e747261637420616464726573732063616e6e6f74206265207a65726f0060448201526064016101db565b6001600160a01b0381166104c65760405162461bcd60e51b815260206004820181905260248201527f526563697069656e7420616464726573732063616e6e6f74206265207a65726f60448201526064016101db565b6001600160a01b038216600090815260016020526040902054600160a01b900460ff16156105365760405162461bcd60e51b815260206004820152601c60248201527f436f6e747261637420697320616c726561647920617070726f7665640000000060448201526064016101db565b6040805180820182526001600160a01b038381168083526000602080850182815288851680845260018352928790209551865491511515600160a01b026001600160a81b0319909216951694909417939093179093558351928352908201527f768fb430a0d4b201cb764ab221c316dd14d8babf2e4b2348e05964c6565318b69101610283565b6105c5610636565b6001600160a01b03811661062a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016101db565b61063381610690565b50565b6000546001600160a01b031633146102a15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101db565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80356001600160a01b03811681146106f757600080fd5b919050565b60006020828403121561070e57600080fd5b610717826106e0565b9392505050565b6000806040838503121561073157600080fd5b61073a836106e0565b9150610748602084016106e0565b90509250929050565b6020808252601a908201527f436f6e7472616374206973206e6f74207265676973746572656400000000000060408201526060019056fea26469706673582212209c9909f9fd809a16fec29eeab099fda8ddc415db17cc218c5acefb8b82b99b9864736f6c634300080f0033", "rawPrivateKey": "cfa6ef757dee2e50351620dca002d32b9c090cfda55fb81f37f1d26b273743f1", "rawAmount": "0", "rawGasLimit": 5000000, "rawGasPrice": "0", - "rawExpectedGasConsumed": 1332843, + "rawExpectedGasConsumed": 640071, "expectedStatus": 1, "expectedBalances": [], "comment": "deploy iip15Manager contract" @@ -29,7 +29,7 @@ "rawGasLimit": 1000000, "rawGasPrice": "0", "rawAccessList": [], - "rawExpectedGasConsumed": 43029, + "rawExpectedGasConsumed": 40652, "expectedStatus": 1, "expectedLogs": [{}], "rawReturnValue": "", @@ -41,7 +41,7 @@ "rawGasLimit": 6000000, "rawGasPrice": "0", "rawAccessList": [], - "rawExpectedGasConsumed": 17844, + "rawExpectedGasConsumed": 17390, "expectedStatus": 106, "expectedErrorMsg": "Contract address cannot be zero", "expectedLogs": [{}], @@ -54,7 +54,7 @@ "rawGasLimit": 6000000, "rawGasPrice": "0", "rawAccessList": [], - "rawExpectedGasConsumed": 17882, + "rawExpectedGasConsumed": 17428, "expectedStatus": 106, "expectedErrorMsg": "Recipient address cannot be zero", "expectedLogs": [{}], @@ -67,7 +67,7 @@ "rawGasLimit": 6000000, "rawGasPrice": "0", "rawAccessList": [], - "rawExpectedGasConsumed": 24078, + "rawExpectedGasConsumed": 23442, "expectedStatus": 1, "expectedLogs": [{}], "rawReturnValue": "", @@ -79,7 +79,7 @@ "rawGasLimit": 6000000, "rawGasPrice": "0", "rawAccessList": [], - "rawExpectedGasConsumed": 16288, + "rawExpectedGasConsumed": 15814, "expectedStatus": 106, "expectedErrorMsg": "Contract is not registered", "expectedLogs": [{}], @@ -93,7 +93,7 @@ "rawGasLimit": 6000000, "rawGasPrice": "0", "rawAccessList": [], - "rawExpectedGasConsumed": 16504, + "rawExpectedGasConsumed": 15076, "expectedStatus": 1, "expectedErrorMsg": "", "expectedLogs": [], @@ -121,7 +121,7 @@ "rawGasLimit": 6000000, "rawGasPrice": "0", "rawAccessList": [], - "rawExpectedGasConsumed": 16287, + "rawExpectedGasConsumed": 15813, "expectedStatus": 106, "expectedErrorMsg": "Contract is not registered", "expectedLogs": [], @@ -135,7 +135,7 @@ "rawGasLimit": 6000000, "rawGasPrice": "0", "rawAccessList": [], - "rawExpectedGasConsumed": 24074, + "rawExpectedGasConsumed": 23437, "expectedStatus": 1, "expectedErrorMsg": "", "expectedLogs": [{}], @@ -149,7 +149,7 @@ "rawGasLimit": 6000000, "rawGasPrice": "0", "rawAccessList": [], - "rawExpectedGasConsumed": 17196, + "rawExpectedGasConsumed": 16632, "expectedStatus": 106, "expectedErrorMsg": "Contract is not approved", "expectedLogs": [{}], @@ -177,7 +177,7 @@ "rawGasLimit": 6000000, "rawGasPrice": "0", "rawAccessList": [], - "rawExpectedGasConsumed": 23413, + "rawExpectedGasConsumed": 22299, "expectedStatus": 1, "expectedErrorMsg": "", "expectedLogs": [{}], @@ -191,7 +191,7 @@ "rawGasLimit": 6000000, "rawGasPrice": "0", "rawAccessList": [], - "rawExpectedGasConsumed": 11689, + "rawExpectedGasConsumed": 11468, "expectedStatus": 1, "expectedErrorMsg": "", "expectedLogs": [], @@ -204,7 +204,7 @@ "rawGasLimit": 6000000, "rawGasPrice": "0", "rawAccessList": [], - "rawExpectedGasConsumed": 15298, + "rawExpectedGasConsumed": 14868, "expectedStatus": 106, "expectedErrorMsg": "Ownable: caller is not the owner", "expectedLogs": [{}], @@ -217,7 +217,7 @@ "rawGasLimit": 6000000, "rawGasPrice": "0", "rawAccessList": [], - "rawExpectedGasConsumed": 24078, + "rawExpectedGasConsumed": 23442, "expectedStatus": 1, "expectedErrorMsg": "", "expectedLogs": [{}], @@ -230,7 +230,7 @@ "rawGasLimit": 6000000, "rawGasPrice": "0", "rawAccessList": [], - "rawExpectedGasConsumed": 12455, + "rawExpectedGasConsumed": 11353, "expectedStatus": 1, "expectedErrorMsg": "", "expectedLogs": [{}], diff --git a/action/protocol/execution/testdata-istanbul/iip15-manager.sol b/action/protocol/execution/testdata-istanbul/iip15-manager.sol index 90fd05db24..3ba099a84b 100644 --- a/action/protocol/execution/testdata-istanbul/iip15-manager.sol +++ b/action/protocol/execution/testdata-istanbul/iip15-manager.sol @@ -15,7 +15,7 @@ contract IIP15Manager is Ownable { event ContractRegistered(address contractAddress, address recipient); event ContractApproved(address contractAddress); - event ContractUnapproved(address contractAddress); + event ContractDisapproved(address contractAddress); event ContractRemoved(address contractAddress); function registerContract(address _contractAddress, address _recipient) public { @@ -39,7 +39,7 @@ contract IIP15Manager is Ownable { require(contractInfo.recipient != address(0), "Contract is not registered"); require(contractInfo.isApproved, "Contract is not approved"); contractInfo.isApproved = false; - emit ContractUnapproved(_contractAddress); + emit ContractDisapproved(_contractAddress); } function removeContract(address _contractAddress) public onlyOwner { diff --git a/blockchain/config.go b/blockchain/config.go index e2860a4db3..e73a779ac3 100644 --- a/blockchain/config.go +++ b/blockchain/config.go @@ -32,6 +32,7 @@ type ( BloomfilterIndexDBPath string `yaml:"bloomfilterIndexDBPath"` CandidateIndexDBPath string `yaml:"candidateIndexDBPath"` StakingIndexDBPath string `yaml:"stakingIndexDBPath"` + SGDIndexDBPath string `yaml:"sgdIndexDBPath"` ContractStakingIndexDBPath string `yaml:"contractStakingIndexDBPath"` ID uint32 `yaml:"id"` EVMNetworkID uint32 `yaml:"evmNetworkID"` @@ -84,6 +85,7 @@ var ( BloomfilterIndexDBPath: "/var/data/bloomfilter.index.db", CandidateIndexDBPath: "/var/data/candidate.index.db", StakingIndexDBPath: "/var/data/staking.index.db", + SGDIndexDBPath: "/var/data/sgd.index.db", ContractStakingIndexDBPath: "/var/data/contractstaking.index.db", ID: 1, EVMNetworkID: 4689, diff --git a/blockchain/genesis/genesis.go b/blockchain/genesis/genesis.go index c29e060400..eaca849e95 100644 --- a/blockchain/genesis/genesis.go +++ b/blockchain/genesis/genesis.go @@ -288,6 +288,10 @@ type ( SystemStakingContractAddress string `yaml:"systemStakingContractAddress"` // SystemStakingContractHeight is the height of system staking contract SystemStakingContractHeight uint64 `yaml:"systemStakingContractHeight"` + // SystemSGDContractAddress is the address of system sgd contract + SystemSGDContractAddress string `yaml:"systemSGDContractAddress"` + // SystemSGDContractHeight is the height of system sgd contract + SystemSGDContractHeight uint64 `yaml:"systemSGDContractHeight"` } // Delegate defines a delegate with address and votes Delegate struct { diff --git a/blockindex/indexpb/index.pb.go b/blockindex/indexpb/index.pb.go index fd3a42c5db..036216c432 100644 --- a/blockindex/indexpb/index.pb.go +++ b/blockindex/indexpb/index.pb.go @@ -8,8 +8,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.23.0 -// protoc v3.12.4 +// protoc-gen-go v1.26.0 +// protoc v3.17.3 // source: index.proto package indexpb @@ -138,6 +138,69 @@ func (x *ActionIndex) GetBlkHeight() uint64 { return 0 } +type SGDIndex struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Contract []byte `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"` + Receiver []byte `protobuf:"bytes,2,opt,name=receiver,proto3" json:"receiver,omitempty"` + Approved bool `protobuf:"varint,3,opt,name=approved,proto3" json:"approved,omitempty"` +} + +func (x *SGDIndex) Reset() { + *x = SGDIndex{} + if protoimpl.UnsafeEnabled { + mi := &file_index_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SGDIndex) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SGDIndex) ProtoMessage() {} + +func (x *SGDIndex) ProtoReflect() protoreflect.Message { + mi := &file_index_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SGDIndex.ProtoReflect.Descriptor instead. +func (*SGDIndex) Descriptor() ([]byte, []int) { + return file_index_proto_rawDescGZIP(), []int{2} +} + +func (x *SGDIndex) GetContract() []byte { + if x != nil { + return x.Contract + } + return nil +} + +func (x *SGDIndex) GetReceiver() []byte { + if x != nil { + return x.Receiver + } + return nil +} + +func (x *SGDIndex) GetApproved() bool { + if x != nil { + return x.Approved + } + return false +} + var File_index_proto protoreflect.FileDescriptor var file_index_proto_rawDesc = []byte{ @@ -151,7 +214,14 @@ var file_index_proto_rawDesc = []byte{ 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x2b, 0x0a, 0x0b, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x6c, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x62, 0x6c, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x22, 0x5e, 0x0a, 0x08, 0x53, 0x47, 0x44, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1a, 0x0a, + 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x63, + 0x65, 0x69, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x63, + 0x65, 0x69, 0x76, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, + 0x64, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2e, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x70, 0x62, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -166,10 +236,11 @@ func file_index_proto_rawDescGZIP() []byte { return file_index_proto_rawDescData } -var file_index_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_index_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_index_proto_goTypes = []interface{}{ (*BlockIndex)(nil), // 0: indexpb.BlockIndex (*ActionIndex)(nil), // 1: indexpb.ActionIndex + (*SGDIndex)(nil), // 2: indexpb.SGDIndex } var file_index_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type @@ -209,6 +280,18 @@ func file_index_proto_init() { return nil } } + file_index_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SGDIndex); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -216,7 +299,7 @@ func file_index_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_index_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 3, NumExtensions: 0, NumServices: 0, }, diff --git a/blockindex/indexpb/index.proto b/blockindex/indexpb/index.proto index 57fde6047d..701275cad3 100644 --- a/blockindex/indexpb/index.proto +++ b/blockindex/indexpb/index.proto @@ -4,7 +4,8 @@ // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. // To compile the proto, run: -// protoc --go_out=plugins=grpc:. *.proto +// protoc --go_out=. *.proto +// option go_package = "../indexpb"; is to specify the package name in the generated go file syntax = "proto3"; package indexpb; @@ -17,3 +18,9 @@ message BlockIndex { message ActionIndex { uint64 blkHeight = 1; } + +message SGDIndex { + bytes contract = 1; + bytes receiver = 2; + bool approved = 3; +} diff --git a/blockindex/sgd_indexer.go b/blockindex/sgd_indexer.go index 5d5e2532bb..ec3d0e9cdf 100644 --- a/blockindex/sgd_indexer.go +++ b/blockindex/sgd_indexer.go @@ -7,50 +7,481 @@ package blockindex import ( "context" + "strings" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/iotexproject/go-pkgs/hash" "github.com/iotexproject/iotex-address/address" + "github.com/iotexproject/iotex-proto/golang/iotextypes" + "github.com/pkg/errors" + "google.golang.org/protobuf/proto" + "github.com/iotexproject/iotex-core/action" "github.com/iotexproject/iotex-core/blockchain/block" "github.com/iotexproject/iotex-core/blockchain/blockdao" + "github.com/iotexproject/iotex-core/blockindex/indexpb" + "github.com/iotexproject/iotex-core/db" + "github.com/iotexproject/iotex-core/db/batch" + "github.com/iotexproject/iotex-core/pkg/util/byteutil" + "github.com/iotexproject/iotex-core/state" ) +var ( + _sgdABI abi.ABI +) + +const ( + _sgdContractInterfaceABI = `[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "contractAddress", + "type": "address" + } + ], + "name": "ContractApproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "ContractRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "contractAddress", + "type": "address" + } + ], + "name": "ContractRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "contractAddress", + "type": "address" + } + ], + "name": "ContractDisapproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + } +]` +) + +func init() { + var err error + _sgdABI, err = abi.JSON(strings.NewReader(_sgdContractInterfaceABI)) + if err != nil { + panic(err) + } +} + +const ( + _sgdBucket = "sg" + _sgdToHeightNS = "hh" + //TODO (millken): currently we fix the percentage to 30%, we can make it configurable in the future + _sgdPercentage = uint64(30) +) + +var _sgdCurrentHeight = []byte("currentHeight") + type ( // SGDRegistry is the interface for Sharing of Gas-fee with DApps SGDRegistry interface { - blockdao.BlockIndexer + blockdao.BlockIndexerWithStart // CheckContract returns the contract's eligibility for SGD and percentage CheckContract(context.Context, string) (address.Address, uint64, bool, error) + // FetchContracts returns all contracts that are eligible for SGD + FetchContracts(context.Context) ([]*SGDIndex, error) } sgdRegistry struct { + contract string + startHeight uint64 + kvStore db.KVStore + } + // SGDIndex is the struct for SGDIndex + SGDIndex struct { + Contract address.Address + Receiver address.Address + Approved bool } ) +func sgdIndexFromPb(pb *indexpb.SGDIndex) (*SGDIndex, error) { + contract, err := address.FromBytes(pb.Contract) + if err != nil { + return nil, err + } + receiver, err := address.FromBytes(pb.Receiver) + if err != nil { + return nil, err + } + return &SGDIndex{ + Contract: contract, + Receiver: receiver, + Approved: pb.Approved, + }, nil +} + +func newSgdIndex(contract, receiver []byte) *indexpb.SGDIndex { + return &indexpb.SGDIndex{ + Contract: contract, + Receiver: receiver, + } +} + // NewSGDRegistry creates a new SGDIndexer -func NewSGDRegistry() SGDRegistry { - return &sgdRegistry{} +func NewSGDRegistry(contract string, startHeight uint64, kv db.KVStore) SGDRegistry { + if kv == nil { + panic("nil kvstore") + } + if contract != "" { + if _, err := address.FromString(contract); err != nil { + panic("invalid contract address") + } + } + return &sgdRegistry{ + contract: contract, + startHeight: startHeight, + kvStore: kv, + } } +// Start starts the SGDIndexer func (sgd *sgdRegistry) Start(ctx context.Context) error { - return nil + err := sgd.kvStore.Start(ctx) + if err != nil { + return err + } + _, err = sgd.Height() + if err != nil && errors.Is(err, db.ErrNotExist) { + return sgd.kvStore.Put(_sgdToHeightNS, _sgdCurrentHeight, byteutil.Uint64ToBytesBigEndian(0)) + } + return err } +// Stop stops the SGDIndexer func (sgd *sgdRegistry) Stop(ctx context.Context) error { - return nil + return sgd.kvStore.Stop(ctx) } +// Height returns the current height of the SGDIndexer func (sgd *sgdRegistry) Height() (uint64, error) { - return 0, nil + h, err := sgd.kvStore.Get(_sgdToHeightNS, _sgdCurrentHeight) + if err != nil { + return 0, err + } + return byteutil.BytesToUint64BigEndian(h), nil +} + +// StartHeight returns the start height of the indexer +func (sgd *sgdRegistry) StartHeight() uint64 { + return sgd.startHeight } +// PutBlock puts a block into SGDIndexer func (sgd *sgdRegistry) PutBlock(ctx context.Context, blk *block.Block) error { + var ( + r *action.Receipt + ok bool + ) + b := batch.NewBatch() + receipts := getReceiptsFromBlock(blk) + for _, selp := range blk.Actions { + actHash, err := selp.Hash() + if err != nil { + continue + } + r, ok = receipts[actHash] + if !ok || r.Status != uint64(iotextypes.ReceiptStatus_Success) { + continue + } + for _, log := range r.Logs() { + if log.Address != sgd.contract { + continue + } + if err := sgd.handleEvent(b, log); err != nil { + return err + } + } + } + b.Put(_sgdToHeightNS, _sgdCurrentHeight, byteutil.Uint64ToBytesBigEndian(blk.Height()), "failed to put current height") + return sgd.kvStore.WriteBatch(b) +} + +func (sgd *sgdRegistry) handleEvent(b batch.KVStoreBatch, log *action.Log) error { + abiEvent, err := _sgdABI.EventByID(common.Hash(log.Topics[0])) + if err != nil { + return err + } + switch abiEvent.Name { + case "ContractRegistered": + return sgd.handleContractRegistered(b, log) + case "ContractApproved": + return sgd.handleContractApproved(b, log) + case "ContractDisapproved": + return sgd.handleContractDisapproved(b, log) + case "ContractRemoved": + return sgd.handleContractRemoved(b, log) + default: + //skip other events + } return nil } -func (sgd *sgdRegistry) DeleteTipBlock(context.Context, *block.Block) error { +func (sgd *sgdRegistry) handleContractRegistered(b batch.KVStoreBatch, log *action.Log) error { + var ( + sgdIndex *indexpb.SGDIndex + event struct { + ContractAddress common.Address + Recipient common.Address + } + ) + if err := _sgdABI.UnpackIntoInterface(&event, "ContractRegistered", log.Data); err != nil { + return err + } + + sgdIndex = newSgdIndex(event.ContractAddress.Bytes(), event.Recipient.Bytes()) + return sgd.putIndex(b, sgdIndex) +} + +func (sgd *sgdRegistry) handleContractApproved(b batch.KVStoreBatch, log *action.Log) error { + var ( + sgdIndex *indexpb.SGDIndex + err error + event struct { + ContractAddress common.Address + } + ) + if err := _sgdABI.UnpackIntoInterface(&event, "ContractApproved", log.Data); err != nil { + return err + } + + sgdIndex, err = sgd.getSGDIndex(event.ContractAddress.Bytes()) + if err != nil { + return err + } + if sgdIndex.Approved { + return errors.New("contract is approved") + } + sgdIndex.Approved = true + return sgd.putIndex(b, sgdIndex) +} + +func (sgd *sgdRegistry) handleContractDisapproved(b batch.KVStoreBatch, log *action.Log) error { + var ( + sgdIndex *indexpb.SGDIndex + err error + event struct { + ContractAddress common.Address + } + ) + if err := _sgdABI.UnpackIntoInterface(&event, "ContractDisapproved", log.Data); err != nil { + return err + } + + sgdIndex, err = sgd.getSGDIndex(event.ContractAddress.Bytes()) + if err != nil { + return err + } + if !sgdIndex.Approved { + return errors.New("contract is not approved") + } + sgdIndex.Approved = false + return sgd.putIndex(b, sgdIndex) +} + +func (sgd *sgdRegistry) handleContractRemoved(b batch.KVStoreBatch, log *action.Log) error { + var ( + event struct { + ContractAddress common.Address + } + ) + if err := _sgdABI.UnpackIntoInterface(&event, "ContractRemoved", log.Data); err != nil { + return err + } + return sgd.deleteIndex(b, event.ContractAddress.Bytes()) +} + +func (sgd *sgdRegistry) putIndex(b batch.KVStoreBatch, sgdIndex *indexpb.SGDIndex) error { + sgdIndexBytes, err := proto.Marshal(sgdIndex) + if err != nil { + return err + } + b.Put(_sgdBucket, sgdIndex.Contract, sgdIndexBytes, "failed to put sgd index") return nil } +func (sgd *sgdRegistry) deleteIndex(b batch.KVStoreBatch, contract []byte) error { + b.Delete(_sgdBucket, contract, "failed to delete sgd index") + return nil +} + +// DeleteTipBlock deletes the tip block from SGDIndexer +func (sgd *sgdRegistry) DeleteTipBlock(context.Context, *block.Block) error { + return errors.New("cannot remove block from indexer") +} + +// CheckContract checks if the contract is a SGD contract func (sgd *sgdRegistry) CheckContract(ctx context.Context, contract string) (address.Address, uint64, bool, error) { - return nil, 0, false, nil + addr, err := address.FromString(contract) + if err != nil { + return nil, 0, false, err + } + sgdIndex, err := sgd.getSGDIndex(addr.Bytes()) + if err != nil { + return nil, 0, false, err + } + + addr, err = address.FromBytes(sgdIndex.Receiver) + return addr, _sgdPercentage, sgdIndex.Approved, err +} + +// getSGDIndex returns the SGDIndex of the contract +func (sgd *sgdRegistry) getSGDIndex(contract []byte) (*indexpb.SGDIndex, error) { + buf, err := sgd.kvStore.Get(_sgdBucket, contract) + if err != nil { + return nil, err + } + sgdIndex := &indexpb.SGDIndex{} + if err := proto.Unmarshal(buf, sgdIndex); err != nil { + return nil, err + } + return sgdIndex, nil +} + +// FetchContracts returns all contracts that are eligible for SGD +func (sgd *sgdRegistry) FetchContracts(ctx context.Context) ([]*SGDIndex, error) { + _, values, err := sgd.kvStore.Filter(_sgdBucket, func(k, v []byte) bool { return true }, nil, nil) + if err != nil { + if errors.Cause(err) == db.ErrNotExist || errors.Cause(err) == db.ErrBucketNotExist { + return nil, errors.Wrapf(state.ErrStateNotExist, "failed to get sgd states of ns = %x", _sgdBucket) + } + return nil, err + } + sgdIndexes := make([]*SGDIndex, 0, len(values)) + sgdIndexPb := &indexpb.SGDIndex{} + for _, v := range values { + if err := proto.Unmarshal(v, sgdIndexPb); err != nil { + return nil, err + } + sgdIndex, err := sgdIndexFromPb(sgdIndexPb) + if err != nil { + return nil, err + } + sgdIndexes = append(sgdIndexes, sgdIndex) + } + return sgdIndexes, nil +} + +func getReceiptsFromBlock(blk *block.Block) map[hash.Hash256]*action.Receipt { + receipts := make(map[hash.Hash256]*action.Receipt, len(blk.Receipts)) + for _, receipt := range blk.Receipts { + receipts[receipt.ActionHash] = receipt + } + return receipts } diff --git a/chainservice/builder.go b/chainservice/builder.go index 4300554464..898d8aee11 100644 --- a/chainservice/builder.go +++ b/chainservice/builder.go @@ -280,7 +280,11 @@ func (builder *Builder) buildSGDRegistry(forTest bool) error { if forTest { builder.cs.sgdIndexer = nil } else { - builder.cs.sgdIndexer = blockindex.NewSGDRegistry() + kvStore, err := db.CreateKVStoreWithCache(builder.cfg.DB, builder.cfg.Chain.SGDIndexDBPath, 1000) + if err != nil { + return err + } + builder.cs.sgdIndexer = blockindex.NewSGDRegistry(builder.cfg.Genesis.SystemSGDContractAddress, builder.cfg.Genesis.SystemSGDContractHeight, kvStore) } return nil } diff --git a/e2etest/local_actpool_test.go b/e2etest/local_actpool_test.go index 1ab7558fca..4db2141952 100644 --- a/e2etest/local_actpool_test.go +++ b/e2etest/local_actpool_test.go @@ -183,12 +183,14 @@ func newActPoolConfig(t *testing.T) (config.Config, error) { r.NoError(err) testContractIndexPath, err := testutil.PathOfTempFile("contractindex") r.NoError(err) - + testSGDIndexPath, err := testutil.PathOfTempFile("sgdindex") + r.NoError(err) defer func() { testutil.CleanupPath(testTriePath) testutil.CleanupPath(testDBPath) testutil.CleanupPath(testIndexPath) testutil.CleanupPath(testContractIndexPath) + testutil.CleanupPath(testSGDIndexPath) }() cfg.Chain.TrieDBPatchFile = "" @@ -196,6 +198,7 @@ func newActPoolConfig(t *testing.T) (config.Config, error) { cfg.Chain.ChainDBPath = testDBPath cfg.Chain.IndexDBPath = testIndexPath cfg.Chain.ContractStakingIndexDBPath = testContractIndexPath + cfg.Chain.SGDIndexDBPath = testSGDIndexPath cfg.ActPool.MinGasPriceStr = "0" cfg.Consensus.Scheme = config.NOOPScheme cfg.Network.Port = testutil.RandomPort() diff --git a/e2etest/local_test.go b/e2etest/local_test.go index 3f8a99414c..2bd2532b5d 100644 --- a/e2etest/local_test.go +++ b/e2etest/local_test.go @@ -62,16 +62,20 @@ func TestLocalCommit(t *testing.T) { require.NoError(err) contractIndexDBPath, err := testutil.PathOfTempFile(_dBPath) require.NoError(err) + indexSGDDBPath, err := testutil.PathOfTempFile(_dBPath + "_sgd") + require.NoError(err) cfg.Chain.TrieDBPatchFile = "" cfg.Chain.TrieDBPath = testTriePath cfg.Chain.ChainDBPath = testDBPath cfg.Chain.IndexDBPath = indexDBPath cfg.Chain.ContractStakingIndexDBPath = contractIndexDBPath + cfg.Chain.SGDIndexDBPath = indexSGDDBPath defer func() { testutil.CleanupPath(testTriePath) testutil.CleanupPath(testDBPath) testutil.CleanupPath(indexDBPath) testutil.CleanupPath(contractIndexDBPath) + testutil.CleanupPath(indexSGDDBPath) }() // create server @@ -329,16 +333,20 @@ func TestLocalSync(t *testing.T) { require.NoError(err) contractIndexDBPath, err := testutil.PathOfTempFile(_dBPath) require.NoError(err) + indexSGDDBPath, err := testutil.PathOfTempFile(_dBPath + "_sgd") + require.NoError(err) cfg.Chain.TrieDBPatchFile = "" cfg.Chain.TrieDBPath = testTriePath cfg.Chain.ChainDBPath = testDBPath cfg.Chain.IndexDBPath = indexDBPath cfg.Chain.ContractStakingIndexDBPath = contractIndexDBPath + cfg.Chain.SGDIndexDBPath = indexSGDDBPath defer func() { testutil.CleanupPath(testTriePath) testutil.CleanupPath(testDBPath) testutil.CleanupPath(indexDBPath) testutil.CleanupPath(contractIndexDBPath) + testutil.CleanupPath(indexSGDDBPath) }() // bootnode @@ -389,7 +397,8 @@ func TestLocalSync(t *testing.T) { require.NoError(err) contractIndexDBPath2, err := testutil.PathOfTempFile(_dBPath2) require.NoError(err) - + indexSGDDBPath2, err := testutil.PathOfTempFile(_dBPath2 + "_sgd") + require.NoError(err) cfg, err = newTestConfig() require.NoError(err) cfg.Chain.TrieDBPatchFile = "" @@ -397,11 +406,13 @@ func TestLocalSync(t *testing.T) { cfg.Chain.ChainDBPath = testDBPath2 cfg.Chain.IndexDBPath = indexDBPath2 cfg.Chain.ContractStakingIndexDBPath = contractIndexDBPath2 + cfg.Chain.SGDIndexDBPath = indexSGDDBPath2 defer func() { testutil.CleanupPath(testTriePath2) testutil.CleanupPath(testDBPath2) testutil.CleanupPath(indexDBPath2) testutil.CleanupPath(contractIndexDBPath2) + testutil.CleanupPath(indexSGDDBPath2) }() // Create client @@ -452,6 +463,8 @@ func TestStartExistingBlockchain(t *testing.T) { require.NoError(err) testContractStakeIndexPath, err := testutil.PathOfTempFile(_dBPath) require.NoError(err) + testSGDIndexPath, err := testutil.PathOfTempFile(_dBPath + "_sgd") + require.NoError(err) // Disable block reward to make bookkeeping easier cfg := config.Default cfg.Chain.TrieDBPatchFile = "" @@ -459,6 +472,7 @@ func TestStartExistingBlockchain(t *testing.T) { cfg.Chain.ChainDBPath = testDBPath cfg.Chain.IndexDBPath = testIndexPath cfg.Chain.ContractStakingIndexDBPath = testContractStakeIndexPath + cfg.Chain.SGDIndexDBPath = testSGDIndexPath cfg.Chain.EnableAsyncIndexWrite = false cfg.ActPool.MinGasPriceStr = "0" cfg.Consensus.Scheme = config.NOOPScheme @@ -480,6 +494,7 @@ func TestStartExistingBlockchain(t *testing.T) { testutil.CleanupPath(testDBPath) testutil.CleanupPath(testIndexPath) testutil.CleanupPath(testContractStakeIndexPath) + testutil.CleanupPath(testSGDIndexPath) }() require.NoError(addTestingTsfBlocks(bc, ap)) @@ -511,6 +526,7 @@ func TestStartExistingBlockchain(t *testing.T) { // Build states from height 1 to 3 testutil.CleanupPath(testTriePath) testutil.CleanupPath(testContractStakeIndexPath) + testutil.CleanupPath(testSGDIndexPath) svr, err = itx.NewServer(cfg) require.NoError(err) require.NoError(svr.Start(ctx)) @@ -532,6 +548,7 @@ func TestStartExistingBlockchain(t *testing.T) { require.NoError(dao.Stop(ctx)) testutil.CleanupPath(testTriePath) testutil.CleanupPath(testContractStakeIndexPath) + testutil.CleanupPath(testSGDIndexPath) svr, err = itx.NewServer(cfg) require.NoError(err) // Build states from height 1 to 2 diff --git a/e2etest/local_transfer_test.go b/e2etest/local_transfer_test.go index cc434f2b27..dee9273f9c 100644 --- a/e2etest/local_transfer_test.go +++ b/e2etest/local_transfer_test.go @@ -303,6 +303,8 @@ func TestLocalTransfer(t *testing.T) { require.NoError(err) testContractStakeIndexPath, err := testutil.PathOfTempFile("contractStakeIndex") require.NoError(err) + sgdIndexDBPath, err := testutil.PathOfTempFile("sgdIndex") + require.NoError(err) defer func() { testutil.CleanupPath(testTriePath) @@ -312,11 +314,12 @@ func TestLocalTransfer(t *testing.T) { testutil.CleanupPath(testBloomfilterIndexPath) testutil.CleanupPath(testCandidateIndexPath) testutil.CleanupPath(testContractStakeIndexPath) + testutil.CleanupPath(sgdIndexDBPath) }() networkPort := 4689 apiPort := testutil.RandomPort() - cfg, err := newTransferConfig(testDBPath, testTriePath, testIndexPath, testBloomfilterIndexPath, testSystemLogPath, testCandidateIndexPath, testContractStakeIndexPath, networkPort, apiPort) + cfg, err := newTransferConfig(testDBPath, testTriePath, testIndexPath, sgdIndexDBPath, testBloomfilterIndexPath, testSystemLogPath, testCandidateIndexPath, testContractStakeIndexPath, networkPort, apiPort) defer func() { delete(cfg.Plugins, config.GatewayPlugin) }() @@ -584,6 +587,7 @@ func newTransferConfig( chainDBPath, trieDBPath, indexDBPath string, + sgdIndexDBPath string, bloomfilterIndex string, systemLogDBPath string, candidateIndexDBPath string, @@ -600,6 +604,7 @@ func newTransferConfig( cfg.Chain.TrieDBPath = trieDBPath cfg.Chain.TrieDBPatchFile = "" cfg.Chain.IndexDBPath = indexDBPath + cfg.Chain.SGDIndexDBPath = sgdIndexDBPath cfg.Chain.BloomfilterIndexDBPath = bloomfilterIndex cfg.System.SystemLogDBPath = systemLogDBPath cfg.Chain.CandidateIndexDBPath = candidateIndexDBPath diff --git a/e2etest/native_staking_test.go b/e2etest/native_staking_test.go index eb0eb452b3..fdb359c6b8 100644 --- a/e2etest/native_staking_test.go +++ b/e2etest/native_staking_test.go @@ -403,11 +403,14 @@ func TestNativeStaking(t *testing.T) { require.NoError(err) testSystemLogPath, err := testutil.PathOfTempFile("systemlog") require.NoError(err) + testSGDIndexPath, err := testutil.PathOfTempFile("sgdindex") + require.NoError(err) defer func() { testutil.CleanupPath(testTriePath) testutil.CleanupPath(testDBPath) testutil.CleanupPath(testIndexPath) testutil.CleanupPath(testSystemLogPath) + testutil.CleanupPath(testSGDIndexPath) // clear the gateway delete(cfg.Plugins, config.GatewayPlugin) }() @@ -418,6 +421,7 @@ func TestNativeStaking(t *testing.T) { cfg.Chain.ChainDBPath = testDBPath cfg.Chain.IndexDBPath = testIndexPath cfg.Chain.ContractStakingIndexDBPath = testIndexPath + cfg.Chain.SGDIndexDBPath = testSGDIndexPath cfg.System.SystemLogDBPath = testSystemLogPath cfg.Consensus.Scheme = config.NOOPScheme cfg.Chain.EnableAsyncIndexWrite = false diff --git a/e2etest/nodeinfo_test.go b/e2etest/nodeinfo_test.go index 62bca0d005..6b19b6a734 100644 --- a/e2etest/nodeinfo_test.go +++ b/e2etest/nodeinfo_test.go @@ -40,11 +40,16 @@ func newConfigForNodeInfoTest(triePath, dBPath, idxDBPath, contractIdxDBPath str if err != nil { return cfg, nil, err } + sgdIndexDBPath, err := testutil.PathOfTempFile(idxDBPath) + if err != nil { + return cfg, nil, err + } cfg.Chain.TrieDBPatchFile = "" cfg.Chain.TrieDBPath = testTriePath cfg.Chain.ChainDBPath = testDBPath cfg.Chain.IndexDBPath = indexDBPath cfg.Chain.ContractStakingIndexDBPath = contractIndexDBPath + cfg.Chain.SGDIndexDBPath = sgdIndexDBPath return cfg, func() { testutil.CleanupPath(testTriePath) testutil.CleanupPath(testDBPath) diff --git a/e2etest/rewarding_test.go b/e2etest/rewarding_test.go index f81b371d67..db99c9771a 100644 --- a/e2etest/rewarding_test.go +++ b/e2etest/rewarding_test.go @@ -71,7 +71,8 @@ func TestBlockReward(t *testing.T) { r.NoError(err) testContractIndexPath, err := testutil.PathOfTempFile("contractindex") r.NoError(err) - + testSGDIndexPath, err := testutil.PathOfTempFile("sgdindex") + r.NoError(err) cfg := config.Default cfg.Consensus.Scheme = config.RollDPoSScheme cfg.Genesis.NumDelegates = 1 @@ -96,6 +97,7 @@ func TestBlockReward(t *testing.T) { cfg.Chain.ChainDBPath = testDBPath cfg.Chain.IndexDBPath = testIndexPath cfg.Chain.ContractStakingIndexDBPath = testContractIndexPath + cfg.Chain.SGDIndexDBPath = testSGDIndexPath cfg.Network.Port = testutil.RandomPort() cfg.Genesis.PollMode = "lifeLong" diff --git a/e2etest/sgd_registry_test.go b/e2etest/sgd_registry_test.go new file mode 100644 index 0000000000..a0b050978a --- /dev/null +++ b/e2etest/sgd_registry_test.go @@ -0,0 +1,248 @@ +package e2etest + +import ( + "context" + "encoding/hex" + "math/big" + "sync/atomic" + "testing" + "time" + + "github.com/iotexproject/go-pkgs/crypto" + "github.com/iotexproject/iotex-address/address" + "github.com/iotexproject/iotex-core/action" + "github.com/iotexproject/iotex-core/action/protocol" + "github.com/iotexproject/iotex-core/action/protocol/account" + accountutil "github.com/iotexproject/iotex-core/action/protocol/account/util" + "github.com/iotexproject/iotex-core/action/protocol/execution" + "github.com/iotexproject/iotex-core/action/protocol/rewarding" + "github.com/iotexproject/iotex-core/action/protocol/rolldpos" + "github.com/iotexproject/iotex-core/actpool" + "github.com/iotexproject/iotex-core/blockchain" + "github.com/iotexproject/iotex-core/blockchain/block" + "github.com/iotexproject/iotex-core/blockchain/blockdao" + "github.com/iotexproject/iotex-core/blockchain/genesis" + "github.com/iotexproject/iotex-core/blockindex" + "github.com/iotexproject/iotex-core/config" + "github.com/iotexproject/iotex-core/db" + "github.com/iotexproject/iotex-core/state" + "github.com/iotexproject/iotex-core/state/factory" + "github.com/iotexproject/iotex-core/testutil" + "github.com/stretchr/testify/require" +) + +func TestSGDRegistry(t *testing.T) { + r := require.New(t) + ctx := context.Background() + cfg := config.Default + cfg.Chain.EnableAsyncIndexWrite = false + cfg.Genesis.EnableGravityChainVoting = false + cfg.Genesis.InitBalanceMap[_executor] = "1000000000000000000000000000" + registry := protocol.NewRegistry() + acc := account.NewProtocol(rewarding.DepositGas) + r.NoError(acc.Register(registry)) + rp := rolldpos.NewProtocol(cfg.Genesis.NumCandidateDelegates, cfg.Genesis.NumDelegates, cfg.Genesis.NumSubEpochs) + r.NoError(rp.Register(registry)) + factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis) + sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry)) + r.NoError(err) + genericValidator := protocol.NewGenericValidator(sf, accountutil.AccountState) + ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool) + r.NoError(err) + ap.AddActionEnvelopeValidators(genericValidator) + dao := blockdao.NewBlockDAOInMemForTest([]blockdao.BlockIndexer{sf}) + bc := blockchain.NewBlockchain( + cfg.Chain, + cfg.Genesis, + dao, + factory.NewMinter(sf, ap), + blockchain.BlockValidatorOption(block.NewValidator( + sf, + genericValidator, + )), + ) + r.NotNil(bc) + reward := rewarding.NewProtocol(cfg.Genesis.Rewarding) + r.NoError(reward.Register(registry)) + + ep := execution.NewProtocol(dao.GetBlockHash, rewarding.DepositGasWithSGD, nil) + r.NoError(ep.Register(registry)) + r.NoError(bc.Start(ctx)) + ctx = genesis.WithGenesisContext(ctx, cfg.Genesis) + r.NoError(sf.Start(ctx)) + defer r.NoError(bc.Stop(ctx)) + + _execPriKey, _ := crypto.HexStringToPrivateKey(_executorPriKey) + data, _ := hex.DecodeString("608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6107be8061007e6000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063a0ee93181161005b578063a0ee93181461014d578063c375c2ef14610160578063d7e5fbf314610173578063f2fde38b1461018657600080fd5b806307f7aafb1461008d5780630ad1c2fa146100a2578063715018a61461012a5780638da5cb5b14610132575b600080fd5b6100a061009b3660046106fc565b610199565b005b6100ff6100b03660046106fc565b604080518082018252600080825260209182018190526001600160a01b039384168152600182528290208251808401909352549283168252600160a01b90920460ff1615159181019190915290565b6040805182516001600160a01b03168152602092830151151592810192909252015b60405180910390f35b6100a061028f565b6000546040516001600160a01b039091168152602001610121565b6100a061015b3660046106fc565b6102a3565b6100a061016e3660046106fc565b610381565b6100a061018136600461071e565b61041a565b6100a06101943660046106fc565b6105bd565b6101a1610636565b6001600160a01b03808216600090815260016020526040902080549091166101e45760405162461bcd60e51b81526004016101db90610751565b60405180910390fd5b8054600160a01b900460ff161561023d5760405162461bcd60e51b815260206004820152601c60248201527f436f6e747261637420697320616c726561647920617070726f7665640000000060448201526064016101db565b805460ff60a01b1916600160a01b1781556040516001600160a01b03831681527faf42961ad755cade79794d4122cb0afedc32bf55a0c716dd085fbee2afc6ac55906020015b60405180910390a15050565b610297610636565b6102a16000610690565b565b6102ab610636565b6001600160a01b03808216600090815260016020526040902080549091166102e55760405162461bcd60e51b81526004016101db90610751565b8054600160a01b900460ff1661033d5760405162461bcd60e51b815260206004820152601860248201527f436f6e7472616374206973206e6f7420617070726f766564000000000000000060448201526064016101db565b805460ff60a01b191681556040516001600160a01b03831681527f50132537991c16a2d6bbd27114ed077fb8c757768dcbb2c3c5736f1b1ed3cc3e90602001610283565b610389610636565b6001600160a01b03808216600090815260016020526040902080549091166103c35760405162461bcd60e51b81526004016101db90610751565b6001600160a01b03821660008181526001602090815260409182902080546001600160a81b031916905590519182527f8d30d41865a0b811b9545d879520d2dde9f4cc49e4241f486ad9752bc904b5659101610283565b6001600160a01b0382166104705760405162461bcd60e51b815260206004820152601f60248201527f436f6e747261637420616464726573732063616e6e6f74206265207a65726f0060448201526064016101db565b6001600160a01b0381166104c65760405162461bcd60e51b815260206004820181905260248201527f526563697069656e7420616464726573732063616e6e6f74206265207a65726f60448201526064016101db565b6001600160a01b038216600090815260016020526040902054600160a01b900460ff16156105365760405162461bcd60e51b815260206004820152601c60248201527f436f6e747261637420697320616c726561647920617070726f7665640000000060448201526064016101db565b6040805180820182526001600160a01b038381168083526000602080850182815288851680845260018352928790209551865491511515600160a01b026001600160a81b0319909216951694909417939093179093558351928352908201527f768fb430a0d4b201cb764ab221c316dd14d8babf2e4b2348e05964c6565318b69101610283565b6105c5610636565b6001600160a01b03811661062a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016101db565b61063381610690565b50565b6000546001600160a01b031633146102a15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101db565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80356001600160a01b03811681146106f757600080fd5b919050565b60006020828403121561070e57600080fd5b610717826106e0565b9392505050565b6000806040838503121561073157600080fd5b61073a836106e0565b9150610748602084016106e0565b90509250929050565b6020808252601a908201527f436f6e7472616374206973206e6f74207265676973746572656400000000000060408201526060019056fea26469706673582212209c9909f9fd809a16fec29eeab099fda8ddc415db17cc218c5acefb8b82b99b9864736f6c634300080f0033") + fixedTime := time.Unix(cfg.Genesis.Timestamp, 0) + nonce := uint64(0) + exec, err := action.SignedExecution(action.EmptyAddress, _execPriKey, atomic.AddUint64(&nonce, 1), big.NewInt(0), 10000000, big.NewInt(9000000000000), data) + r.NoError(err) + deployHash, err := exec.Hash() + r.NoError(err) + r.NoError(ap.Add(context.Background(), exec)) + blk, err := bc.MintNewBlock(fixedTime) + r.NoError(err) + r.NoError(bc.CommitBlock(blk)) + receipt, err := dao.GetReceiptByActionHash(deployHash, 1) + r.NoError(err) + r.Equal(receipt.ContractAddress, "io1va03q4lcr608dr3nltwm64sfcz05czjuycsqgn") + height, err := dao.Height() + r.NoError(err) + r.Equal(uint64(1), height) + + contractAddress := receipt.ContractAddress + + indexSGDDBPath, err := testutil.PathOfTempFile(_dBPath + "_sgd") + r.NoError(err) + kvstore, err := db.CreateKVStore(db.DefaultConfig, indexSGDDBPath) + r.NoError(err) + sgdRegistry := blockindex.NewSGDRegistry(contractAddress, 0, kvstore) + r.NoError(sgdRegistry.Start(ctx)) + defer func() { + r.NoError(sgdRegistry.Stop(ctx)) + testutil.CleanupPath(indexSGDDBPath) + }() + + registerAddress, err := address.FromHex("5b38da6a701c568545dcfcb03fcb875f56beddc4") + r.NoError(err) + receiverAddress, err := address.FromHex("78731d3ca6b7e34ac0f824c42a7cc18a495cabab") + r.NoError(err) + expectPercentage := uint64(30) + t.Run("registerContract", func(t *testing.T) { + data, _ = hex.DecodeString("d7e5fbf30000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc400000000000000000000000078731d3ca6b7e34ac0f824c42a7cc18a495cabab") + exec, err = action.SignedExecution(contractAddress, _execPriKey, atomic.AddUint64(&nonce, 1), big.NewInt(0), 10000000, big.NewInt(9000000000000), data) + r.NoError(err) + r.NoError(ap.Add(context.Background(), exec)) + blk, err = bc.MintNewBlock(fixedTime) + r.NoError(err) + r.NoError(bc.CommitBlock(blk)) + height, err = dao.Height() + r.NoError(err) + r.Equal(uint64(2), height) + + ctx = genesis.WithGenesisContext( + protocol.WithBlockchainCtx( + protocol.WithRegistry(ctx, registry), + protocol.BlockchainCtx{ + Tip: protocol.TipInfo{ + Height: height, + Hash: blk.HashHeader(), + Timestamp: blk.Timestamp(), + }, + }), + cfg.Genesis, + ) + r.NoError(sgdRegistry.PutBlock(ctx, blk)) + receiver, percentage, isApproved, err := sgdRegistry.CheckContract(ctx, registerAddress.String()) + r.NoError(err) + r.Equal(expectPercentage, percentage) + r.Equal(receiverAddress, receiver) + r.False(isApproved) + + lists, err := sgdRegistry.FetchContracts(ctx) + r.NoError(err) + r.Equal(1, len(lists)) + r.Equal(registerAddress.Bytes(), lists[0].Contract.Bytes()) + r.Equal(receiverAddress.Bytes(), lists[0].Receiver.Bytes()) + r.False(lists[0].Approved) + }) + t.Run("approveContract", func(t *testing.T) { + data, _ = hex.DecodeString("07f7aafb0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4") + exec, err = action.SignedExecution(contractAddress, _execPriKey, atomic.AddUint64(&nonce, 1), big.NewInt(0), 10000000, big.NewInt(9000000000000), data) + r.NoError(err) + r.NoError(ap.Add(context.Background(), exec)) + blk, err = bc.MintNewBlock(fixedTime) + r.NoError(err) + r.NoError(bc.CommitBlock(blk)) + height, err = dao.Height() + r.NoError(err) + r.Equal(uint64(3), height) + + ctx = genesis.WithGenesisContext( + protocol.WithBlockchainCtx( + protocol.WithRegistry(ctx, registry), + protocol.BlockchainCtx{ + Tip: protocol.TipInfo{ + Height: height, + Hash: blk.HashHeader(), + Timestamp: blk.Timestamp(), + }, + }), + cfg.Genesis, + ) + r.NoError(sgdRegistry.PutBlock(ctx, blk)) + receiver, percentage, isApproved, err := sgdRegistry.CheckContract(ctx, registerAddress.String()) + r.NoError(err) + r.Equal(receiverAddress, receiver) + r.True(isApproved) + r.Equal(expectPercentage, percentage) + }) + + t.Run("disapproveContract", func(t *testing.T) { + data, _ = hex.DecodeString("a0ee93180000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4") + exec, err = action.SignedExecution(contractAddress, _execPriKey, atomic.AddUint64(&nonce, 1), big.NewInt(0), 10000000, big.NewInt(9000000000000), data) + r.NoError(err) + r.NoError(ap.Add(context.Background(), exec)) + blk, err = bc.MintNewBlock(fixedTime) + r.NoError(err) + r.NoError(bc.CommitBlock(blk)) + height, err = dao.Height() + r.NoError(err) + r.Equal(uint64(4), height) + + ctx = genesis.WithGenesisContext( + protocol.WithBlockchainCtx( + protocol.WithRegistry(ctx, registry), + protocol.BlockchainCtx{ + Tip: protocol.TipInfo{ + Height: height, + Hash: blk.HashHeader(), + Timestamp: blk.Timestamp(), + }, + }), + cfg.Genesis, + ) + r.NoError(sgdRegistry.PutBlock(ctx, blk)) + receiver, percentage, isApproved, err := sgdRegistry.CheckContract(ctx, registerAddress.String()) + r.NoError(err) + r.Equal(receiverAddress, receiver) + r.False(isApproved) + r.Equal(expectPercentage, percentage) + }) + + t.Run("removeContract", func(t *testing.T) { + data, _ = hex.DecodeString("c375c2ef0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4") + exec, err = action.SignedExecution(contractAddress, _execPriKey, atomic.AddUint64(&nonce, 1), big.NewInt(0), 10000000, big.NewInt(9000000000000), data) + r.NoError(err) + r.NoError(ap.Add(context.Background(), exec)) + blk, err = bc.MintNewBlock(fixedTime) + r.NoError(err) + r.NoError(bc.CommitBlock(blk)) + height, err = dao.Height() + r.NoError(err) + r.Equal(uint64(5), height) + + ctx = genesis.WithGenesisContext( + protocol.WithBlockchainCtx( + protocol.WithRegistry(ctx, registry), + protocol.BlockchainCtx{ + Tip: protocol.TipInfo{ + Height: height, + Hash: blk.HashHeader(), + Timestamp: blk.Timestamp(), + }, + }), + cfg.Genesis, + ) + r.NoError(sgdRegistry.PutBlock(ctx, blk)) + receiver, percentage, isApproved, err := sgdRegistry.CheckContract(ctx, registerAddress.String()) + r.ErrorContains(err, "not exist in DB") + r.Nil(receiver) + r.False(isApproved) + r.Equal(uint64(0), percentage) + + _, err = sgdRegistry.FetchContracts(ctx) + r.ErrorIs(err, state.ErrStateNotExist) + }) +} diff --git a/e2etest/staking_test.go b/e2etest/staking_test.go index 258896eb88..316aeeac8a 100644 --- a/e2etest/staking_test.go +++ b/e2etest/staking_test.go @@ -194,6 +194,8 @@ func TestStakingContract(t *testing.T) { require.NoError(err) testConsensusPath, err := testutil.PathOfTempFile("consensus") require.NoError(err) + testSGDIndexPath, err := testutil.PathOfTempFile("sgdIndex") + require.NoError(err) defer func() { testutil.CleanupPath(testTriePath) testutil.CleanupPath(testDBPath) @@ -203,6 +205,7 @@ func TestStakingContract(t *testing.T) { testutil.CleanupPath(testSystemLogPath) testutil.CleanupPath(testConsensusPath) testutil.CleanupPath(testContractStakeIndexPath) + testutil.CleanupPath(testSGDIndexPath) // clear the gateway delete(cfg.Plugins, config.GatewayPlugin) }() @@ -212,6 +215,7 @@ func TestStakingContract(t *testing.T) { cfg.Chain.TrieDBPath = testTriePath cfg.Chain.ChainDBPath = testDBPath cfg.Chain.IndexDBPath = testIndexPath + cfg.Chain.SGDIndexDBPath = testSGDIndexPath cfg.Chain.BloomfilterIndexDBPath = testBloomfilterIndexPath cfg.Chain.CandidateIndexDBPath = testCandidateIndexPath cfg.Chain.ContractStakingIndexDBPath = testContractStakeIndexPath diff --git a/ioctl/newcmd/contract/contractcompile_test.go b/ioctl/newcmd/contract/contractcompile_test.go index 37cd6818a7..42eada3e14 100644 --- a/ioctl/newcmd/contract/contractcompile_test.go +++ b/ioctl/newcmd/contract/contractcompile_test.go @@ -19,6 +19,7 @@ import ( ) func TestNewContractCompileCmd(t *testing.T) { + t.Skip("skip this test because it requires special solc version installed") skipWithoutSolc(t) require := require.New(t) ctrl := gomock.NewController(t) diff --git a/server/itx/heartbeat_test.go b/server/itx/heartbeat_test.go index f988b977a6..9168782edb 100644 --- a/server/itx/heartbeat_test.go +++ b/server/itx/heartbeat_test.go @@ -28,10 +28,13 @@ func TestNewHeartbeatHandler(t *testing.T) { testutil.CleanupPath(triePath) indexPath, err := testutil.PathOfTempFile("index.db") require.NoError(err) + sgdIndexPath, err := testutil.PathOfTempFile("sgdindex.db") + require.NoError(err) defer func() { testutil.CleanupPath(dbPath) testutil.CleanupPath(triePath) testutil.CleanupPath(indexPath) + testutil.CleanupPath(sgdIndexPath) }() cfg := config.Default cfg.API.GRPCPort = testutil.RandomPort() @@ -40,6 +43,7 @@ func TestNewHeartbeatHandler(t *testing.T) { cfg.Chain.ChainDBPath = dbPath cfg.Chain.TrieDBPath = triePath cfg.Chain.ContractStakingIndexDBPath = indexPath + cfg.Chain.SGDIndexDBPath = sgdIndexPath cfg.Chain.TrieDBPatchFile = "" s, err := NewServer(cfg) cfg.Consensus.Scheme = config.RollDPoSScheme diff --git a/server/itx/server_test.go b/server/itx/server_test.go index 5f4f32fc3c..4198e9f2f4 100644 --- a/server/itx/server_test.go +++ b/server/itx/server_test.go @@ -80,12 +80,15 @@ func newConfig(t *testing.T) (config.Config, func()) { require.NoError(err) contractIndexPath, err := testutil.PathOfTempFile("contractindxer.db") require.NoError(err) + sgdPath, err := testutil.PathOfTempFile("sgdindex.db") + require.NoError(err) cfg := config.Default cfg.API.GRPCPort = testutil.RandomPort() cfg.API.HTTPPort = testutil.RandomPort() cfg.API.WebSocketPort = testutil.RandomPort() cfg.Chain.ChainDBPath = dbPath cfg.Chain.TrieDBPath = triePath + cfg.Chain.SGDIndexDBPath = sgdPath cfg.Chain.TrieDBPatchFile = "" cfg.Chain.ContractStakingIndexDBPath = contractIndexPath return cfg, func() { @@ -93,5 +96,6 @@ func newConfig(t *testing.T) (config.Config, func()) { testutil.CleanupPath(triePath) testutil.CleanupPath(indexPath) testutil.CleanupPath(contractIndexPath) + testutil.CleanupPath(sgdPath) } }