diff --git a/command/loadbot/abis.go b/command/loadbot/abis.go new file mode 100644 index 0000000000..c3cc8821ce --- /dev/null +++ b/command/loadbot/abis.go @@ -0,0 +1,637 @@ +package loadbot + +const ( + ERC20ABI = `[ + { + "inputs":[ + { + "internalType":"uint256", + "name":"total", + "type":"uint256" + }, + { + "internalType":"string", + "name":"coinName", + "type":"string" + }, + { + "internalType":"string", + "name":"coinSymbol", + "type":"string" + } + ], + "stateMutability":"nonpayable", + "type":"constructor" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"tokenOwner", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"spender", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"tokens", + "type":"uint256" + } + ], + "name":"Approval", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"from", + "type":"address" + }, + { + "indexed":true, + "internalType":"address", + "name":"to", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"tokens", + "type":"uint256" + } + ], + "name":"Transfer", + "type":"event" + }, + { + "stateMutability":"payable", + "type":"fallback" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"owner", + "type":"address" + }, + { + "internalType":"address", + "name":"delegate", + "type":"address" + } + ], + "name":"allowance", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"delegate", + "type":"address" + }, + { + "internalType":"uint256", + "name":"numTokens", + "type":"uint256" + } + ], + "name":"approve", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"tokenOwner", + "type":"address" + } + ], + "name":"balanceOf", + "outputs":[ + { + "internalType":"uint256", + "name":"balance", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"decimals", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"name", + "outputs":[ + { + "internalType":"string", + "name":"", + "type":"string" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"symbol", + "outputs":[ + { + "internalType":"string", + "name":"", + "type":"string" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"totalSupply", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"receiver", + "type":"address" + }, + { + "internalType":"uint256", + "name":"numTokens", + "type":"uint256" + } + ], + "name":"transfer", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"owner", + "type":"address" + }, + { + "internalType":"address", + "name":"buyer", + "type":"address" + }, + { + "internalType":"uint256", + "name":"numTokens", + "type":"uint256" + } + ], + "name":"transferFrom", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "stateMutability":"payable", + "type":"receive" + } + ]` + //nolint:lll + ERC20BIN = "60806040523480156200001157600080fd5b506040516200146538038062001465833981810160405281019062000037919062000363565b81600090805190602001906200004f929190620000db565b50806001908051906020019062000068929190620000db565b506005600260006101000a81548160ff021916908360ff16021790555082600581905550600554600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050505062000462565b828054620000e9906200042c565b90600052602060002090601f0160209004810192826200010d576000855562000159565b82601f106200012857805160ff191683800117855562000159565b8280016001018555821562000159579182015b82811115620001585782518255916020019190600101906200013b565b5b5090506200016891906200016c565b5090565b5b80821115620001875760008160009055506001016200016d565b5090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b620001b4816200019f565b8114620001c057600080fd5b50565b600081519050620001d481620001a9565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200022f82620001e4565b810181811067ffffffffffffffff82111715620002515762000250620001f5565b5b80604052505050565b6000620002666200018b565b905062000274828262000224565b919050565b600067ffffffffffffffff821115620002975762000296620001f5565b5b620002a282620001e4565b9050602081019050919050565b60005b83811015620002cf578082015181840152602081019050620002b2565b83811115620002df576000848401525b50505050565b6000620002fc620002f68462000279565b6200025a565b9050828152602081018484840111156200031b576200031a620001df565b5b62000328848285620002af565b509392505050565b600082601f830112620003485762000347620001da565b5b81516200035a848260208601620002e5565b91505092915050565b6000806000606084860312156200037f576200037e62000195565b5b60006200038f86828701620001c3565b935050602084015167ffffffffffffffff811115620003b357620003b26200019a565b5b620003c18682870162000330565b925050604084015167ffffffffffffffff811115620003e557620003e46200019a565b5b620003f38682870162000330565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200044557607f821691505b602082108114156200045c576200045b620003fd565b5b50919050565b610ff380620004726000396000f3fe60806040526004361061008a5760003560e01c8063313ce56711610059578063313ce5671461016957806370a082311461019457806395d89b41146101d1578063a9059cbb146101fc578063dd62ed3e1461023957610094565b806306fdde0314610099578063095ea7b3146100c457806318160ddd1461010157806323b872dd1461012c57610094565b3661009457600080fd5b600080fd5b3480156100a557600080fd5b506100ae610276565b6040516100bb9190610a9b565b60405180910390f35b3480156100d057600080fd5b506100eb60048036038101906100e69190610b56565b610304565b6040516100f89190610bb1565b60405180910390f35b34801561010d57600080fd5b506101166103f6565b6040516101239190610bdb565b60405180910390f35b34801561013857600080fd5b50610153600480360381019061014e9190610bf6565b610400565b6040516101609190610bb1565b60405180910390f35b34801561017557600080fd5b5061017e6106f2565b60405161018b9190610c65565b60405180910390f35b3480156101a057600080fd5b506101bb60048036038101906101b69190610c80565b610705565b6040516101c89190610bdb565b60405180910390f35b3480156101dd57600080fd5b506101e661074e565b6040516101f39190610a9b565b60405180910390f35b34801561020857600080fd5b50610223600480360381019061021e9190610b56565b6107dc565b6040516102309190610bb1565b60405180910390f35b34801561024557600080fd5b50610260600480360381019061025b9190610cad565b61097b565b60405161026d9190610bdb565b60405180910390f35b6000805461028390610d1c565b80601f01602080910402602001604051908101604052809291908181526020018280546102af90610d1c565b80156102fc5780601f106102d1576101008083540402835291602001916102fc565b820191906000526020600020905b8154815290600101906020018083116102df57829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516103e49190610bdb565b60405180910390a36001905092915050565b6000600554905090565b6000600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115610484576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161047b90610dc0565b60405180910390fd5b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115610543576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161053a90610e52565b60405180910390fd5b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546105929190610ea1565b9250508190555081600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546106259190610ea1565b9250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461067b9190610ed5565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516106df9190610bdb565b60405180910390a3600190509392505050565b600260009054906101000a900460ff1681565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6001805461075b90610d1c565b80601f016020809104026020016040519081016040528092919081815260200182805461078790610d1c565b80156107d45780601f106107a9576101008083540402835291602001916107d4565b820191906000526020600020905b8154815290600101906020018083116107b757829003601f168201915b505050505081565b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115610860576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085790610f9d565b60405180910390fd5b81600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546108af9190610ea1565b9250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546109059190610ed5565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109699190610bdb565b60405180910390a36001905092915050565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610a3c578082015181840152602081019050610a21565b83811115610a4b576000848401525b50505050565b6000601f19601f8301169050919050565b6000610a6d82610a02565b610a778185610a0d565b9350610a87818560208601610a1e565b610a9081610a51565b840191505092915050565b60006020820190508181036000830152610ab58184610a62565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610aed82610ac2565b9050919050565b610afd81610ae2565b8114610b0857600080fd5b50565b600081359050610b1a81610af4565b92915050565b6000819050919050565b610b3381610b20565b8114610b3e57600080fd5b50565b600081359050610b5081610b2a565b92915050565b60008060408385031215610b6d57610b6c610abd565b5b6000610b7b85828601610b0b565b9250506020610b8c85828601610b41565b9150509250929050565b60008115159050919050565b610bab81610b96565b82525050565b6000602082019050610bc66000830184610ba2565b92915050565b610bd581610b20565b82525050565b6000602082019050610bf06000830184610bcc565b92915050565b600080600060608486031215610c0f57610c0e610abd565b5b6000610c1d86828701610b0b565b9350506020610c2e86828701610b0b565b9250506040610c3f86828701610b41565b9150509250925092565b600060ff82169050919050565b610c5f81610c49565b82525050565b6000602082019050610c7a6000830184610c56565b92915050565b600060208284031215610c9657610c95610abd565b5b6000610ca484828501610b0b565b91505092915050565b60008060408385031215610cc457610cc3610abd565b5b6000610cd285828601610b0b565b9250506020610ce385828601610b0b565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610d3457607f821691505b60208210811415610d4857610d47610ced565b5b50919050565b7f546865206f776e657220646f65736e2774206861766520656e6f75676820667560008201527f6e647320746f206d616b6520746865207472616e736665722100000000000000602082015250565b6000610daa603983610a0d565b9150610db582610d4e565b604082019050919050565b60006020820190508181036000830152610dd981610d9d565b9050919050565b7f5468652064656c656761746520646f73656e2774206861766520656e6f75676860008201527f20616c6c6f77616e636520746f206d616b6520746865207472616e7366657221602082015250565b6000610e3c604083610a0d565b9150610e4782610de0565b604082019050919050565b60006020820190508181036000830152610e6b81610e2f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610eac82610b20565b9150610eb783610b20565b925082821015610eca57610ec9610e72565b5b828203905092915050565b6000610ee082610b20565b9150610eeb83610b20565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115610f2057610f1f610e72565b5b828201905092915050565b7f5468652073656e64657220646f73656e2774206861766520656e6f756768206660008201527f756e647320746f206d616b6520746865207472616e7366657221000000000000602082015250565b6000610f87603a83610a0d565b9150610f9282610f2b565b604082019050919050565b60006020820190508181036000830152610fb681610f7a565b905091905056fea2646970667358221220b323d4c936f691bb75019e448b4dad3aadc00d047eba1c01d09c1d4c10b373d464736f6c634300080b0033" + + ERC721ABI = `[ + { + "inputs": [ + { + "internalType": "string", + "name": "tokenName", + "type": "string" + }, + { + "internalType": "string", + "name": "tokenSymbol", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "tokenURI", + "type": "string" + } + ], + "name": "createNFT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ]` + //nolint:lll + ERC721BIN = "60806040523480156200001157600080fd5b5060405162002f8838038062002f88833981810160405281019062000037919062000197565b818181600090805190602001906200005192919062000075565b5080600190805190602001906200006a92919062000075565b50505050506200037a565b82805462000083906200029f565b90600052602060002090601f016020900481019282620000a75760008555620000f3565b82601f10620000c257805160ff1916838001178555620000f3565b82800160010185558215620000f3579182015b82811115620000f2578251825591602001919060010190620000d5565b5b50905062000102919062000106565b5090565b5b808211156200012157600081600090555060010162000107565b5090565b60006200013c620001368462000233565b6200020a565b9050828152602081018484840111156200015557600080fd5b6200016284828562000269565b509392505050565b600082601f8301126200017c57600080fd5b81516200018e84826020860162000125565b91505092915050565b60008060408385031215620001ab57600080fd5b600083015167ffffffffffffffff811115620001c657600080fd5b620001d4858286016200016a565b925050602083015167ffffffffffffffff811115620001f257600080fd5b62000200858286016200016a565b9150509250929050565b60006200021662000229565b9050620002248282620002d5565b919050565b6000604051905090565b600067ffffffffffffffff8211156200025157620002506200033a565b5b6200025c8262000369565b9050602081019050919050565b60005b83811015620002895780820151818401526020810190506200026c565b8381111562000299576000848401525b50505050565b60006002820490506001821680620002b857607f821691505b60208210811415620002cf57620002ce6200030b565b5b50919050565b620002e08262000369565b810181811067ffffffffffffffff821117156200030257620003016200033a565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612bfe806200038a6000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806370a082311161008c578063b88d4fde11610066578063b88d4fde1461025b578063c87b56dd14610277578063da2ed03e146102a7578063e985e9c5146102d7576100ea565b806370a08231146101f157806395d89b4114610221578063a22cb4651461023f576100ea565b8063095ea7b3116100c8578063095ea7b31461016d57806323b872dd1461018957806342842e0e146101a55780636352211e146101c1576100ea565b806301ffc9a7146100ef57806306fdde031461011f578063081812fc1461013d575b600080fd5b61010960048036038101906101049190611c6a565b610307565b60405161011691906120b1565b60405180910390f35b6101276103e9565b60405161013491906120cc565b60405180910390f35b61015760048036038101906101529190611cfd565b61047b565b604051610164919061204a565b60405180910390f35b61018760048036038101906101829190611c2e565b610500565b005b6101a3600480360381019061019e9190611b28565b610618565b005b6101bf60048036038101906101ba9190611b28565b610678565b005b6101db60048036038101906101d69190611cfd565b610698565b6040516101e8919061204a565b60405180910390f35b61020b60048036038101906102069190611ac3565b61074a565b60405161021891906122ee565b60405180910390f35b610229610802565b60405161023691906120cc565b60405180910390f35b61025960048036038101906102549190611bf2565b610894565b005b61027560048036038101906102709190611b77565b6108aa565b005b610291600480360381019061028c9190611cfd565b61090c565b60405161029e91906120cc565b60405180910390f35b6102c160048036038101906102bc9190611cbc565b610a5e565b6040516102ce91906122ee565b60405180910390f35b6102f160048036038101906102ec9190611aec565b610a94565b6040516102fe91906120b1565b60405180910390f35b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103d257507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103e257506103e182610b28565b5b9050919050565b6060600080546103f890612544565b80601f016020809104026020016040519081016040528092919081815260200182805461042490612544565b80156104715780601f1061044657610100808354040283529160200191610471565b820191906000526020600020905b81548152906001019060200180831161045457829003601f168201915b5050505050905090565b600061048682610b92565b6104c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104bc9061226e565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061050b82610698565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561057c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610573906122ae565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661059b610bfe565b73ffffffffffffffffffffffffffffffffffffffff1614806105ca57506105c9816105c4610bfe565b610a94565b5b610609576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610600906121ae565b60405180910390fd5b6106138383610c06565b505050565b610629610623610bfe565b82610cbf565b610668576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161065f906122ce565b60405180910390fd5b610673838383610d9d565b505050565b610693838383604051806020016040528060008152506108aa565b505050565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610741576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610738906121ee565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156107bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b2906121ce565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60606001805461081190612544565b80601f016020809104026020016040519081016040528092919081815260200182805461083d90612544565b801561088a5780601f1061085f5761010080835404028352916020019161088a565b820191906000526020600020905b81548152906001019060200180831161086d57829003601f168201915b5050505050905090565b6108a661089f610bfe565b8383611004565b5050565b6108bb6108b5610bfe565b83610cbf565b6108fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108f1906122ce565b60405180910390fd5b61090684848484611171565b50505050565b606061091782610b92565b610956576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161094d9061224e565b60405180910390fd5b600060066000848152602001908152602001600020805461097690612544565b80601f01602080910402602001604051908101604052809291908181526020018280546109a290612544565b80156109ef5780601f106109c4576101008083540402835291602001916109ef565b820191906000526020600020905b8154815290600101906020018083116109d257829003601f168201915b505050505090506000610a006111cd565b9050600081511415610a16578192505050610a59565b600082511115610a4b578082604051602001610a33929190612026565b60405160208183030381529060405292505050610a59565b610a54846111e4565b925050505b919050565b600080610a6b600761128b565b9050610a773382611299565b610a8181846112b7565b610a8b600761132b565b80915050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16610c7983610698565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610cca82610b92565b610d09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d009061218e565b60405180910390fd5b6000610d1483610698565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610d8357508373ffffffffffffffffffffffffffffffffffffffff16610d6b8461047b565b73ffffffffffffffffffffffffffffffffffffffff16145b80610d945750610d938185610a94565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16610dbd82610698565b73ffffffffffffffffffffffffffffffffffffffff1614610e13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0a9061210e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610e83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e7a9061214e565b60405180910390fd5b610e8e838383611341565b610e99600082610c06565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610ee9919061245a565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610f4091906123d3565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610fff838383611346565b505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611073576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106a9061216e565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161116491906120b1565b60405180910390a3505050565b61117c848484610d9d565b6111888484848461134b565b6111c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111be906120ee565b60405180910390fd5b50505050565b606060405180602001604052806000815250905090565b60606111ef82610b92565b61122e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112259061228e565b60405180910390fd5b60006112386111cd565b905060008151116112585760405180602001604052806000815250611283565b80611262846114e2565b604051602001611273929190612026565b6040516020818303038152906040525b915050919050565b600081600001549050919050565b6112b382826040518060200160405280600081525061168f565b5050565b6112c082610b92565b6112ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112f69061220e565b60405180910390fd5b806006600084815260200190815260200160002090805190602001906113269291906118e7565b505050565b6001816000016000828254019250508190555050565b505050565b505050565b600061136c8473ffffffffffffffffffffffffffffffffffffffff166116ea565b156114d5578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611395610bfe565b8786866040518563ffffffff1660e01b81526004016113b79493929190612065565b602060405180830381600087803b1580156113d157600080fd5b505af192505050801561140257506040513d601f19601f820116820180604052508101906113ff9190611c93565b60015b611485573d8060008114611432576040519150601f19603f3d011682016040523d82523d6000602084013e611437565b606091505b5060008151141561147d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611474906120ee565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506114da565b600190505b949350505050565b6060600082141561152a576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061168a565b600082905060005b6000821461155c578080611545906125a7565b915050600a826115559190612429565b9150611532565b60008167ffffffffffffffff81111561159e577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156115d05781602001600182028036833780820191505090505b5090505b60008514611683576001826115e9919061245a565b9150600a856115f891906125f0565b603061160491906123d3565b60f81b818381518110611640577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561167c9190612429565b94506115d4565b8093505050505b919050565b611699838361170d565b6116a6600084848461134b565b6116e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116dc906120ee565b60405180910390fd5b505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561177d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117749061222e565b60405180910390fd5b61178681610b92565b156117c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117bd9061212e565b60405180910390fd5b6117d260008383611341565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461182291906123d3565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46118e360008383611346565b5050565b8280546118f390612544565b90600052602060002090601f016020900481019282611915576000855561195c565b82601f1061192e57805160ff191683800117855561195c565b8280016001018555821561195c579182015b8281111561195b578251825591602001919060010190611940565b5b509050611969919061196d565b5090565b5b8082111561198657600081600090555060010161196e565b5090565b600061199d6119988461232e565b612309565b9050828152602081018484840111156119b557600080fd5b6119c0848285612502565b509392505050565b60006119db6119d68461235f565b612309565b9050828152602081018484840111156119f357600080fd5b6119fe848285612502565b509392505050565b600081359050611a1581612b6c565b92915050565b600081359050611a2a81612b83565b92915050565b600081359050611a3f81612b9a565b92915050565b600081519050611a5481612b9a565b92915050565b600082601f830112611a6b57600080fd5b8135611a7b84826020860161198a565b91505092915050565b600082601f830112611a9557600080fd5b8135611aa58482602086016119c8565b91505092915050565b600081359050611abd81612bb1565b92915050565b600060208284031215611ad557600080fd5b6000611ae384828501611a06565b91505092915050565b60008060408385031215611aff57600080fd5b6000611b0d85828601611a06565b9250506020611b1e85828601611a06565b9150509250929050565b600080600060608486031215611b3d57600080fd5b6000611b4b86828701611a06565b9350506020611b5c86828701611a06565b9250506040611b6d86828701611aae565b9150509250925092565b60008060008060808587031215611b8d57600080fd5b6000611b9b87828801611a06565b9450506020611bac87828801611a06565b9350506040611bbd87828801611aae565b925050606085013567ffffffffffffffff811115611bda57600080fd5b611be687828801611a5a565b91505092959194509250565b60008060408385031215611c0557600080fd5b6000611c1385828601611a06565b9250506020611c2485828601611a1b565b9150509250929050565b60008060408385031215611c4157600080fd5b6000611c4f85828601611a06565b9250506020611c6085828601611aae565b9150509250929050565b600060208284031215611c7c57600080fd5b6000611c8a84828501611a30565b91505092915050565b600060208284031215611ca557600080fd5b6000611cb384828501611a45565b91505092915050565b600060208284031215611cce57600080fd5b600082013567ffffffffffffffff811115611ce857600080fd5b611cf484828501611a84565b91505092915050565b600060208284031215611d0f57600080fd5b6000611d1d84828501611aae565b91505092915050565b611d2f8161248e565b82525050565b611d3e816124a0565b82525050565b6000611d4f82612390565b611d5981856123a6565b9350611d69818560208601612511565b611d72816126dd565b840191505092915050565b6000611d888261239b565b611d9281856123b7565b9350611da2818560208601612511565b611dab816126dd565b840191505092915050565b6000611dc18261239b565b611dcb81856123c8565b9350611ddb818560208601612511565b80840191505092915050565b6000611df46032836123b7565b9150611dff826126ee565b604082019050919050565b6000611e176025836123b7565b9150611e228261273d565b604082019050919050565b6000611e3a601c836123b7565b9150611e458261278c565b602082019050919050565b6000611e5d6024836123b7565b9150611e68826127b5565b604082019050919050565b6000611e806019836123b7565b9150611e8b82612804565b602082019050919050565b6000611ea3602c836123b7565b9150611eae8261282d565b604082019050919050565b6000611ec66038836123b7565b9150611ed18261287c565b604082019050919050565b6000611ee9602a836123b7565b9150611ef4826128cb565b604082019050919050565b6000611f0c6029836123b7565b9150611f178261291a565b604082019050919050565b6000611f2f602e836123b7565b9150611f3a82612969565b604082019050919050565b6000611f526020836123b7565b9150611f5d826129b8565b602082019050919050565b6000611f756031836123b7565b9150611f80826129e1565b604082019050919050565b6000611f98602c836123b7565b9150611fa382612a30565b604082019050919050565b6000611fbb602f836123b7565b9150611fc682612a7f565b604082019050919050565b6000611fde6021836123b7565b9150611fe982612ace565b604082019050919050565b60006120016031836123b7565b915061200c82612b1d565b604082019050919050565b612020816124f8565b82525050565b60006120328285611db6565b915061203e8284611db6565b91508190509392505050565b600060208201905061205f6000830184611d26565b92915050565b600060808201905061207a6000830187611d26565b6120876020830186611d26565b6120946040830185612017565b81810360608301526120a68184611d44565b905095945050505050565b60006020820190506120c66000830184611d35565b92915050565b600060208201905081810360008301526120e68184611d7d565b905092915050565b6000602082019050818103600083015261210781611de7565b9050919050565b6000602082019050818103600083015261212781611e0a565b9050919050565b6000602082019050818103600083015261214781611e2d565b9050919050565b6000602082019050818103600083015261216781611e50565b9050919050565b6000602082019050818103600083015261218781611e73565b9050919050565b600060208201905081810360008301526121a781611e96565b9050919050565b600060208201905081810360008301526121c781611eb9565b9050919050565b600060208201905081810360008301526121e781611edc565b9050919050565b6000602082019050818103600083015261220781611eff565b9050919050565b6000602082019050818103600083015261222781611f22565b9050919050565b6000602082019050818103600083015261224781611f45565b9050919050565b6000602082019050818103600083015261226781611f68565b9050919050565b6000602082019050818103600083015261228781611f8b565b9050919050565b600060208201905081810360008301526122a781611fae565b9050919050565b600060208201905081810360008301526122c781611fd1565b9050919050565b600060208201905081810360008301526122e781611ff4565b9050919050565b60006020820190506123036000830184612017565b92915050565b6000612313612324565b905061231f8282612576565b919050565b6000604051905090565b600067ffffffffffffffff821115612349576123486126ae565b5b612352826126dd565b9050602081019050919050565b600067ffffffffffffffff82111561237a576123796126ae565b5b612383826126dd565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b60006123de826124f8565b91506123e9836124f8565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561241e5761241d612621565b5b828201905092915050565b6000612434826124f8565b915061243f836124f8565b92508261244f5761244e612650565b5b828204905092915050565b6000612465826124f8565b9150612470836124f8565b92508282101561248357612482612621565b5b828203905092915050565b6000612499826124d8565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b8381101561252f578082015181840152602081019050612514565b8381111561253e576000848401525b50505050565b6000600282049050600182168061255c57607f821691505b602082108114156125705761256f61267f565b5b50919050565b61257f826126dd565b810181811067ffffffffffffffff8211171561259e5761259d6126ae565b5b80604052505050565b60006125b2826124f8565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156125e5576125e4612621565b5b600182019050919050565b60006125fb826124f8565b9150612606836124f8565b92508261261657612615612650565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b7f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60008201527f6578697374656e7420746f6b656e000000000000000000000000000000000000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f45524337323155524953746f726167653a2055524920717565727920666f722060008201527f6e6f6e6578697374656e7420746f6b656e000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b612b758161248e565b8114612b8057600080fd5b50565b612b8c816124a0565b8114612b9757600080fd5b50565b612ba3816124ac565b8114612bae57600080fd5b50565b612bba816124f8565b8114612bc557600080fd5b5056fea26469706673582212201cec1003a2d2dbbf3e0f120c6b7e02ea19f30e76950ea5407df6d12f2c17030c64736f6c63430008040033" +) diff --git a/command/loadbot/deploy_contract.go b/command/loadbot/deploy_contract.go new file mode 100644 index 0000000000..81fba72277 --- /dev/null +++ b/command/loadbot/deploy_contract.go @@ -0,0 +1,100 @@ +package loadbot + +import ( + "context" + "fmt" + "sync/atomic" + "time" + + "github.com/0xPolygon/polygon-edge/command/loadbot/generator" + "github.com/0xPolygon/polygon-edge/helper/tests" + txpoolOp "github.com/0xPolygon/polygon-edge/txpool/proto" + "github.com/0xPolygon/polygon-edge/types" + + "github.com/umbracle/go-web3/jsonrpc" +) + +func (l *Loadbot) deployContract( + grpcClient txpoolOp.TxnPoolOperatorClient, + jsonClient *jsonrpc.Client, + receiptTimeout time.Duration) error { + start := time.Now() + + _, ok := l.generator.(generator.ContractTxnGenerator) + if !ok { + return fmt.Errorf("invalid generator type, it needs to be a generator.ContractTxnGenerator interface") + } + + // deploy SC + txHash, err := l.executeTxn(grpcClient) + if err != nil { + //nolint:forcetypeassert + l.generator.(generator.ContractTxnGenerator).MarkFailedContractTxn(&generator.FailedContractTxnInfo{ + TxHash: txHash.String(), + Error: &generator.TxnError{ + Error: err, + ErrorType: generator.AddErrorType, + }, + }) + atomic.AddUint64(&l.metrics.ContractMetrics.FailedContractTransactionsCount, 1) + + return fmt.Errorf("could not execute transaction, %w", err) + } + + // set timeout + ctx, cancel := context.WithTimeout(context.Background(), receiptTimeout) + defer cancel() + + // and wait for receipt + receipt, err := tests.WaitForReceipt(ctx, jsonClient.Eth(), txHash) + + if err != nil { + //nolint:forcetypeassert + l.generator.(generator.ContractTxnGenerator).MarkFailedContractTxn(&generator.FailedContractTxnInfo{ + TxHash: txHash.String(), + Error: &generator.TxnError{ + Error: err, + ErrorType: generator.ReceiptErrorType, + }, + }) + atomic.AddUint64(&l.metrics.ContractMetrics.FailedContractTransactionsCount, 1) + + return fmt.Errorf("could not get the receipt, %w", err) + } + + end := time.Now() + // initialize gas metrics map with block nuber as index + l.metrics.ContractMetrics.ContractGasMetrics.Blocks[receipt.BlockNumber] = GasMetrics{} + // fetch contract address + l.metrics.ContractMetrics.ContractAddress = receipt.ContractAddress + // set contract address in order to get new example txn and gas estimate + //nolint:forcetypeassert + l.generator.(generator.ContractTxnGenerator).SetContractAddress(types.StringToAddress( + receipt.ContractAddress.String(), + )) + + // we're done with SC deployment + // we defined SC address and + // now get new gas estimates for CS token transfers + if err := l.updateGasEstimate(jsonClient); err != nil { + return fmt.Errorf("unable to get gas estimate, %w", err) + } + + // record contract deployment metrics + l.metrics.ContractMetrics.ContractDeploymentDuration.reportTurnAroundTime( + txHash, + &metadata{ + turnAroundTime: end.Sub(start), + blockNumber: receipt.BlockNumber, + }, + ) + // calculate contract deployment metrics + if err := l.calculateGasMetrics(jsonClient, l.metrics.ContractMetrics.ContractGasMetrics); err != nil { + return fmt.Errorf("unable to calculate contract block gas metrics: %w", err) + } + + l.metrics.ContractMetrics.ContractDeploymentDuration.calcTurnAroundMetrics() + l.metrics.ContractMetrics.ContractDeploymentDuration.TotalExecTime = end.Sub(start) + + return nil +} diff --git a/command/loadbot/execution.go b/command/loadbot/execution.go index 318a84c56d..fce4af4906 100644 --- a/command/loadbot/execution.go +++ b/command/loadbot/execution.go @@ -4,15 +4,16 @@ import ( "context" "crypto/ecdsa" "fmt" + "math/big" + "sync" + "sync/atomic" + "time" + "github.com/0xPolygon/polygon-edge/command/loadbot/generator" "github.com/0xPolygon/polygon-edge/helper/tests" txpoolOp "github.com/0xPolygon/polygon-edge/txpool/proto" "github.com/golang/protobuf/ptypes/any" "github.com/umbracle/go-web3/jsonrpc" - "math/big" - "sync" - "sync/atomic" - "time" "github.com/0xPolygon/polygon-edge/types" "github.com/umbracle/go-web3" @@ -20,7 +21,7 @@ import ( const ( maxReceiptWait = 5 * time.Minute - minReceiptWait = 30 * time.Second + minReceiptWait = 1 * time.Minute defaultFastestTurnAround = time.Hour * 24 defaultSlowestTurnAround = time.Duration(0) @@ -33,6 +34,8 @@ type Mode string const ( transfer Mode = "transfer" deploy Mode = "deploy" + erc20 Mode = "erc20" + erc721 Mode = "erc721" ) type Account struct { @@ -54,6 +57,8 @@ type Configuration struct { GasPrice *big.Int GasLimit *big.Int ContractArtifact *generator.ContractArtifact + ConstructorArgs []byte // smart contract constructor args + MaxWait uint64 // max wait time for receipts in minutes } type metadata struct { @@ -64,10 +69,30 @@ type metadata struct { blockNumber uint64 } +type GasMetrics struct { + GasUsed uint64 + GasLimit uint64 + Utilization float64 +} + +type BlockGasMetrics struct { + Blocks map[uint64]GasMetrics + BlockGasMutex *sync.Mutex +} + +type ContractMetricsData struct { + FailedContractTransactionsCount uint64 + ContractDeploymentDuration ExecDuration + ContractAddress web3.Address + ContractGasMetrics *BlockGasMetrics +} + type Metrics struct { TotalTransactionsSentCount uint64 FailedTransactionsCount uint64 TransactionDuration ExecDuration + ContractMetrics ContractMetricsData + GasMetrics *BlockGasMetrics } type Loadbot struct { @@ -85,6 +110,19 @@ func NewLoadbot(cfg *Configuration) *Loadbot { TransactionDuration: ExecDuration{ blockTransactions: make(map[uint64]uint64), }, + ContractMetrics: ContractMetricsData{ + ContractDeploymentDuration: ExecDuration{ + blockTransactions: make(map[uint64]uint64), + }, + ContractGasMetrics: &BlockGasMetrics{ + Blocks: make(map[uint64]GasMetrics), + BlockGasMutex: &sync.Mutex{}, + }, + }, + GasMetrics: &BlockGasMetrics{ + Blocks: make(map[uint64]GasMetrics), + BlockGasMutex: &sync.Mutex{}, + }, }, } } @@ -135,17 +173,21 @@ func (l *Loadbot) Run() error { // Set up the transaction generator generatorParams := &generator.GeneratorParams{ - Nonce: nonce, - ChainID: l.cfg.ChainID, - SenderAddress: sender.Address, - SenderKey: sender.PrivateKey, - GasPrice: gasPrice, - Value: l.cfg.Value, + Nonce: nonce, + ChainID: l.cfg.ChainID, + SenderAddress: sender.Address, + RecieverAddress: l.cfg.Receiver, + SenderKey: sender.PrivateKey, + GasPrice: gasPrice, + Value: l.cfg.Value, + ContractArtifact: l.cfg.ContractArtifact, + ConstructorArgs: l.cfg.ConstructorArgs, } var ( - txnGenerator generator.TransactionGenerator - genErr error = nil + txnGenerator generator.TransactionGenerator + tokenTxnGenerator generator.ContractTxnGenerator + genErr error ) switch l.cfg.GeneratorMode { @@ -153,42 +195,48 @@ func (l *Loadbot) Run() error { txnGenerator, genErr = generator.NewTransferGenerator(generatorParams) case deploy: txnGenerator, genErr = generator.NewDeployGenerator(generatorParams) + case erc20: + tokenTxnGenerator, genErr = generator.NewERC20Generator(generatorParams) + case erc721: + tokenTxnGenerator, genErr = generator.NewERC721Generator(generatorParams) } if genErr != nil { return fmt.Errorf("unable to start generator, %w", genErr) } - l.generator = txnGenerator - - // Get the gas estimate - exampleTxn, err := l.generator.GetExampleTransaction() - if err != nil { - return fmt.Errorf("unable to get example transaction, %w", err) + switch l.cfg.GeneratorMode { + case erc20, erc721: + l.generator = tokenTxnGenerator + default: + l.generator = txnGenerator } - gasLimit := l.cfg.GasLimit - if gasLimit == nil { - // No gas limit specified, query the network for an estimation - gasEstimate, estimateErr := estimateGas(jsonClient, exampleTxn) - if estimateErr != nil { - return fmt.Errorf("unable to get gas estimate, %w", err) - } - - gasLimit = new(big.Int).SetUint64(gasEstimate) + if err := l.updateGasEstimate(jsonClient); err != nil { + return fmt.Errorf("could not update gas estimate, %w", err) } - l.generator.SetGasEstimate(gasLimit.Uint64()) - ticker := time.NewTicker(1 * time.Second / time.Duration(l.cfg.TPS)) defer ticker.Stop() - var wg sync.WaitGroup - - receiptTimeout := calcMaxTimeout(l.cfg.Count, l.cfg.TPS) + var receiptTimeout time.Duration + // if max-wait flag is not set it will be calculated dynamically + if l.cfg.MaxWait == 0 { + receiptTimeout = calcMaxTimeout(l.cfg.Count, l.cfg.TPS) + } else { + receiptTimeout = time.Duration(l.cfg.MaxWait) * time.Minute + } startTime := time.Now() + if l.isTokenTransferMode() { + if err := l.deployContract(grpcClient, jsonClient, receiptTimeout); err != nil { + return fmt.Errorf("unable to deploy smart contract, %w", err) + } + } + + var wg sync.WaitGroup + for i := uint64(0); i < l.cfg.Count; i++ { <-ticker.C @@ -236,6 +284,8 @@ func (l *Loadbot) Run() error { return } + l.initGasMetricsBlocksMap(receipt.BlockNumber) + // Stop the performance timer end := time.Now() @@ -253,6 +303,10 @@ func (l *Loadbot) Run() error { endTime := time.Now() + if err := l.calculateGasMetrics(jsonClient, l.metrics.GasMetrics); err != nil { + return fmt.Errorf("unable to calculate block gas metrics: %w", err) + } + // Calculate the turn around metrics now that the loadbot is done l.metrics.TransactionDuration.calcTurnAroundMetrics() l.metrics.TransactionDuration.TotalExecTime = endTime.Sub(startTime) diff --git a/command/loadbot/generator/base.go b/command/loadbot/generator/base.go index 2357f37cd0..a79d3cea1d 100644 --- a/command/loadbot/generator/base.go +++ b/command/loadbot/generator/base.go @@ -1,8 +1,9 @@ package generator import ( - "github.com/0xPolygon/polygon-edge/crypto" "sync" + + "github.com/0xPolygon/polygon-edge/crypto" ) type BaseGenerator struct { diff --git a/command/loadbot/generator/contract_txn_generator.go b/command/loadbot/generator/contract_txn_generator.go new file mode 100644 index 0000000000..f608fa1f03 --- /dev/null +++ b/command/loadbot/generator/contract_txn_generator.go @@ -0,0 +1,87 @@ +package generator + +import ( + "math/big" + "sync" + "sync/atomic" + + "github.com/0xPolygon/polygon-edge/types" +) + +type ContractTxnsGenerator struct { + BaseGenerator + + contractBytecode []byte + encodedParams []byte + + contractAddress *types.Address + failedContractTxns []*FailedContractTxnInfo + failedContractTxnsLock sync.RWMutex +} + +// Returns contract deployment tx if contractAddress is empty, otherwise returns +// a token transfer tx +func (gen *ContractTxnsGenerator) GetExampleTransaction() (*types.Transaction, error) { + if gen.contractAddress == nil { + // contract not deployed yet + // generate contract deployment tx + return gen.signer.SignTx(&types.Transaction{ + From: gen.params.SenderAddress, + Value: big.NewInt(0), + GasPrice: gen.params.GasPrice, + Input: gen.contractBytecode, + V: big.NewInt(1), // it is necessary to encode in rlp + }, gen.params.SenderKey) + } + + // return token transfer tx + return gen.signer.SignTx(&types.Transaction{ + From: gen.params.SenderAddress, + To: gen.contractAddress, + Value: big.NewInt(0), + GasPrice: gen.params.GasPrice, + Input: gen.encodedParams, + V: big.NewInt(1), // it is necessary to encode in rlp + }, gen.params.SenderKey) +} + +func (gen *ContractTxnsGenerator) GenerateTransaction() (*types.Transaction, error) { + newNextNonce := atomic.AddUint64(&gen.params.Nonce, 1) + + if gen.contractAddress == nil { + // contract not deployed yet + // generate contract deployment tx + return gen.signer.SignTx(&types.Transaction{ + From: gen.params.SenderAddress, + Value: big.NewInt(0), + Gas: gen.estimatedGas, + GasPrice: gen.params.GasPrice, + Nonce: newNextNonce - 1, + Input: gen.contractBytecode, + V: big.NewInt(1), // it is necessary to encode in rlp + }, gen.params.SenderKey) + } + + // return token transfer tx + return gen.signer.SignTx(&types.Transaction{ + From: gen.params.SenderAddress, + To: gen.contractAddress, + Value: big.NewInt(0), + Gas: gen.estimatedGas, + GasPrice: gen.params.GasPrice, + Nonce: newNextNonce - 1, + Input: gen.encodedParams, + V: big.NewInt(1), // it is necessary to encode in rlp + }, gen.params.SenderKey) +} + +func (gen *ContractTxnsGenerator) MarkFailedContractTxn(failedContractTxn *FailedContractTxnInfo) { + gen.failedContractTxnsLock.Lock() + defer gen.failedContractTxnsLock.Unlock() + + gen.failedContractTxns = append(gen.failedContractTxns, failedContractTxn) +} + +func (gen *ContractTxnsGenerator) SetContractAddress(addr types.Address) { + gen.contractAddress = &addr +} diff --git a/command/loadbot/generator/deploy_generator.go b/command/loadbot/generator/deploy_generator.go index f3716adc9a..355d1a1b3f 100644 --- a/command/loadbot/generator/deploy_generator.go +++ b/command/loadbot/generator/deploy_generator.go @@ -3,10 +3,11 @@ package generator import ( "encoding/hex" "fmt" - "github.com/0xPolygon/polygon-edge/crypto" - "github.com/0xPolygon/polygon-edge/types" "math/big" "sync/atomic" + + "github.com/0xPolygon/polygon-edge/crypto" + "github.com/0xPolygon/polygon-edge/types" ) type DeployGenerator struct { diff --git a/command/loadbot/generator/erc_generators.go b/command/loadbot/generator/erc_generators.go new file mode 100644 index 0000000000..72c56d4440 --- /dev/null +++ b/command/loadbot/generator/erc_generators.go @@ -0,0 +1,62 @@ +package generator + +import ( + "encoding/hex" + "fmt" + + "github.com/0xPolygon/polygon-edge/crypto" +) + +// call ERC20 contract method and encode parameters +func NewERC20Generator(params *GeneratorParams) (*ContractTxnsGenerator, error) { + gen := &ContractTxnsGenerator{} + + gen.BaseGenerator = BaseGenerator{ + failedTxns: make([]*FailedTxnInfo, 0), + params: params, + signer: crypto.NewEIP155Signer(params.ChainID), + } + + buf, err := hex.DecodeString(params.ContractArtifact.Bytecode) + if err != nil { + return nil, fmt.Errorf("unable to decode bytecode, %w", err) + } + + gen.contractBytecode = buf + gen.contractBytecode = append(gen.contractBytecode, params.ConstructorArgs...) + + if gen.encodedParams, err = params.ContractArtifact.ABI.Methods["transfer"].Encode( + []string{params.RecieverAddress.String(), + "0.001", // token has 5 decimals + }); err != nil { + return nil, fmt.Errorf("cannot encode ERC20 transfer method params: %w", err) + } + + return gen, nil +} + +// call ERC721 contract method and encode parameters +func NewERC721Generator(params *GeneratorParams) (*ContractTxnsGenerator, error) { + gen := &ContractTxnsGenerator{} + + gen.BaseGenerator = BaseGenerator{ + failedTxns: make([]*FailedTxnInfo, 0), + params: params, + signer: crypto.NewEIP155Signer(params.ChainID), + } + + buf, err := hex.DecodeString(params.ContractArtifact.Bytecode) + if err != nil { + return nil, fmt.Errorf("unable to decode bytecode, %w", err) + } + + gen.contractBytecode = buf + gen.contractBytecode = append(gen.contractBytecode, params.ConstructorArgs...) + + if gen.encodedParams, err = params.ContractArtifact.ABI.Methods["createNFT"].Encode( + []string{"https://really-valuable-nft-page.io"}); err != nil { + return nil, fmt.Errorf("cannot encode ERC721 createNFT method params: %w", err) + } + + return gen, nil +} diff --git a/command/loadbot/generator/generator.go b/command/loadbot/generator/generator.go index 559f68f0c9..f93d2c647c 100644 --- a/command/loadbot/generator/generator.go +++ b/command/loadbot/generator/generator.go @@ -3,24 +3,34 @@ package generator import ( "crypto/ecdsa" "encoding/json" - "github.com/0xPolygon/polygon-edge/types" "io/ioutil" "math/big" + + "github.com/0xPolygon/polygon-edge/types" + "github.com/umbracle/go-web3" + "github.com/umbracle/go-web3/abi" ) type TransactionGenerator interface { GenerateTransaction() (*types.Transaction, error) GetExampleTransaction() (*types.Transaction, error) GetTransactionErrors() []*FailedTxnInfo - MarkFailedTxn(failedTxn *FailedTxnInfo) SetGasEstimate(gasEstimate uint64) + MarkFailedTxn(failedTxn *FailedTxnInfo) +} + +type ContractTxnGenerator interface { + TransactionGenerator + MarkFailedContractTxn(failedContractTxn *FailedContractTxnInfo) + SetContractAddress(types.Address) } type TxnErrorType string const ( - ReceiptErrorType TxnErrorType = "ReceiptErrorType" - AddErrorType TxnErrorType = "AddErrorType" + ReceiptErrorType TxnErrorType = "ReceiptErrorType" + AddErrorType TxnErrorType = "AddErrorType" + ContractDeployType TxnErrorType = "ContractDeployErrorType" ) const ( @@ -29,7 +39,8 @@ const ( ) type ContractArtifact struct { - Bytecode string `json:"bytecode"` + Bytecode string `json:"bytecode"` + ABI *abi.ABI `json:"abi"` } type TxnError struct { @@ -43,14 +54,22 @@ type FailedTxnInfo struct { Error *TxnError } +type FailedContractTxnInfo struct { + TxHash string + Error *TxnError +} + type GeneratorParams struct { Nonce uint64 ChainID uint64 SenderAddress types.Address + RecieverAddress types.Address SenderKey *ecdsa.PrivateKey Value *big.Int GasPrice *big.Int ContractArtifact *ContractArtifact + ConstructorArgs []byte // smart contract constructor arguments + ContractAddress web3.Address } // ReadContractArtifact reads the contract bytecode from the specified path diff --git a/command/loadbot/generator/transfer_generator.go b/command/loadbot/generator/transfer_generator.go index 26b96b537c..3b9fb920fc 100644 --- a/command/loadbot/generator/transfer_generator.go +++ b/command/loadbot/generator/transfer_generator.go @@ -2,10 +2,11 @@ package generator import ( "fmt" - "github.com/0xPolygon/polygon-edge/crypto" - "github.com/0xPolygon/polygon-edge/types" "math/big" "sync/atomic" + + "github.com/0xPolygon/polygon-edge/crypto" + "github.com/0xPolygon/polygon-edge/types" ) type TransferGenerator struct { diff --git a/command/loadbot/generators.go b/command/loadbot/generators.go index 8fe98ba494..db496191fe 100644 --- a/command/loadbot/generators.go +++ b/command/loadbot/generators.go @@ -2,14 +2,15 @@ package loadbot import ( "fmt" + "os" + "strings" + "github.com/0xPolygon/polygon-edge/crypto" txpoolOp "github.com/0xPolygon/polygon-edge/txpool/proto" "github.com/0xPolygon/polygon-edge/types" "github.com/umbracle/go-web3/jsonrpc" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - "os" - "strings" ) func createJSONRPCClient(endpoint string, maxConns int) (*jsonrpc.Client, error) { diff --git a/command/loadbot/helper.go b/command/loadbot/helper.go index 133c3a822a..c9b6687f57 100644 --- a/command/loadbot/helper.go +++ b/command/loadbot/helper.go @@ -1,11 +1,16 @@ package loadbot import ( + "context" "fmt" + "math/big" + "time" + + "golang.org/x/sync/errgroup" + "github.com/0xPolygon/polygon-edge/types" "github.com/umbracle/go-web3" "github.com/umbracle/go-web3/jsonrpc" - "time" ) // getInitialSenderNonce queries the sender account nonce before starting the loadbot run. @@ -52,6 +57,76 @@ func estimateGas(client *jsonrpc.Client, txn *types.Transaction) (uint64, error) return gasEstimate, nil } +// calculate block utilization in percents +func calculateBlockUtilization(blockInfo GasMetrics) float64 { + return float64(blockInfo.GasUsed) / float64(blockInfo.GasLimit) * 100 +} + +// calculate average block utilization across all blocks +func calculateAvgBlockUtil(gasData map[uint64]GasMetrics) float64 { + sum := float64(0) + for _, i := range gasData { + sum += i.Utilization + } + + return sum / float64(len(gasData)) +} + +// fetch block gas usage and gas limit and calculate block utilization +func (l *Loadbot) calculateGasMetrics(jsonClient *jsonrpc.Client, gasMetrics *BlockGasMetrics) error { + errGr, _ := errgroup.WithContext(context.Background()) + + for num, data := range gasMetrics.Blocks { + blockNum := num + blockData := data + + errGr.Go(func() error { + blockInfom, err := jsonClient.Eth().GetBlockByNumber(web3.BlockNumber(blockNum), false) + if err != nil { + return fmt.Errorf("could not fetch block %d by number, %w", blockNum, err) + } + + blockData.GasLimit = blockInfom.GasLimit + blockData.GasUsed = blockInfom.GasUsed + blockData.Utilization = calculateBlockUtilization(blockData) + gasMetrics.Blocks[blockNum] = blockData + + return nil + }) + } + + if err := errGr.Wait(); err != nil { + return err + } + + return nil +} + +func (l *Loadbot) updateGasEstimate(jsonClient *jsonrpc.Client) error { + //nolint: ifshort + gasLimit := l.cfg.GasLimit + + if gasLimit == nil { + // Get the gas estimate + exampleTxn, err := l.generator.GetExampleTransaction() + if err != nil { + return fmt.Errorf("unable to get example transaction, %w", err) + } + + // No gas limit specified, query the network for an estimation + gasEstimate, estimateErr := estimateGas(jsonClient, exampleTxn) + if estimateErr != nil { + return fmt.Errorf("unable to get gas estimate, %w", err) + } + + gasLimit = new(big.Int).SetUint64(gasEstimate) + + l.generator.SetGasEstimate(gasLimit.Uint64()) + } + + return nil +} + // calcMaxTimeout calculates the max timeout for transactions receipts // based on the transaction count and tps params func calcMaxTimeout(count, tps uint64) time.Duration { @@ -67,3 +142,20 @@ func calcMaxTimeout(count, tps uint64) time.Duration { return waitTime + waitFactor } + +// returns true if this is erc20 or erc721 mode +func (l *Loadbot) isTokenTransferMode() bool { + switch l.cfg.GeneratorMode { + case erc20, erc721: + return true + default: + return false + } +} + +//initialze gas metrics blocks map with block number as key +func (l *Loadbot) initGasMetricsBlocksMap(blockNum uint64) { + l.metrics.GasMetrics.BlockGasMutex.Lock() + l.metrics.GasMetrics.Blocks[blockNum] = GasMetrics{} + l.metrics.GasMetrics.BlockGasMutex.Unlock() +} diff --git a/command/loadbot/loadbot_command.go b/command/loadbot/loadbot_command.go index fd71eaf4a7..c92eb926a3 100644 --- a/command/loadbot/loadbot_command.go +++ b/command/loadbot/loadbot_command.go @@ -2,6 +2,7 @@ package loadbot import ( "fmt" + "github.com/0xPolygon/polygon-edge/command" "github.com/0xPolygon/polygon-edge/command/helper" "github.com/spf13/cobra" @@ -29,28 +30,28 @@ func setFlags(cmd *cobra.Command) { ¶ms.tps, tpsFlag, 100, - "number of transactions to send per second. Default: 100", + "number of transactions to send per second.", ) cmd.Flags().Uint64Var( ¶ms.chainID, chainIDFlag, 100, - "the network chain ID. Default: 100", + "the network chain ID.", ) cmd.Flags().Uint64Var( ¶ms.count, countFlag, 1000, - "the number of transactions to sent in total. Default: 1000", + "the number of transactions to sent in total.", ) cmd.Flags().StringVar( ¶ms.modeRaw, modeFlag, string(transfer), - "the mode of operation [transfer, deploy]. Default: transfer", + "the mode of operation [transfer, deploy, erc20, erc721].", ) cmd.Flags().StringVar( @@ -71,8 +72,10 @@ func setFlags(cmd *cobra.Command) { ¶ms.valueRaw, valueFlag, "0x100", - "the value sent in each transaction in wei. Default: 100", + "the value sent in each transaction in wei.", ) + // override default value for help output + cmd.Flag(valueFlag).DefValue = "100" cmd.Flags().StringVar( ¶ms.gasPriceRaw, @@ -102,14 +105,21 @@ func setFlags(cmd *cobra.Command) { ¶ms.detailed, detailedFlag, false, - "flag indicating if the error logs should be shown. Default: false", + "flag indicating if the error logs should be shown. (default: false)", ) cmd.Flags().Uint64Var( ¶ms.maxConns, maxConnsFlag, - 2*params.tps, - "sets the maximum no.of connections allowed per host. Default: 2*tps", + 1000000, + "sets the maximum no. of connections allowed per host.", + ) + + cmd.Flags().Uint64Var( + ¶ms.maxWait, + maxWaitFlag, + 0, + "sets the maximum wait time for transactions receipts in minutes.", ) } @@ -124,6 +134,11 @@ func runPreRun(cmd *cobra.Command, _ []string) error { return err } + // initialize raw parameters + if err := params.initRawParams(); err != nil { + return errInvalidValues + } + if _, err := helper.ParseGRPCAddress( helper.GetGRPCAddress(cmd), ); err != nil { @@ -170,6 +185,7 @@ func runLoadbot(config *Configuration, detailed bool) (*LoadbotResult, error) { result := newLoadbotResult( loadbot.GetMetrics(), + config.GeneratorMode, ) if detailed { diff --git a/command/loadbot/params.go b/command/loadbot/params.go index 055571a812..d8772849eb 100644 --- a/command/loadbot/params.go +++ b/command/loadbot/params.go @@ -3,10 +3,12 @@ package loadbot import ( "errors" "fmt" - "github.com/0xPolygon/polygon-edge/command/loadbot/generator" - "github.com/0xPolygon/polygon-edge/types" "math/big" "strings" + + "github.com/0xPolygon/polygon-edge/command/loadbot/generator" + "github.com/0xPolygon/polygon-edge/types" + "github.com/umbracle/go-web3/abi" ) var ( @@ -19,6 +21,18 @@ var ( errContractPath = errors.New("contract path not specified") ) +const ( + // arbitrary value for total token supply + // token has 5 decimals + // transfers are done with 0.001 amount + erc20TokenSupply = "5000000000" + erc20TokenName = "ZexCoin" + erc20TokenSymbol = "ZEX" + + erc721TokenName = "ZexNFT" + erc721TokenSymbol = "ZEXES" +) + const ( tpsFlag = "tps" modeFlag = "mode" @@ -32,6 +46,7 @@ const ( gasPriceFlag = "gas-price" gasLimitFlag = "gas-limit" contractFlag = "contract" + maxWaitFlag = "max-wait" ) type loadbotParams struct { @@ -39,6 +54,7 @@ type loadbotParams struct { chainID uint64 count uint64 maxConns uint64 + maxWait uint64 contractPath string @@ -58,22 +74,18 @@ type loadbotParams struct { gasPrice *big.Int gasLimit *big.Int contractArtifact *generator.ContractArtifact + constructorArgs []byte } func (p *loadbotParams) validateFlags() error { - // Validate the correct mode type - convMode := Mode(strings.ToLower(p.modeRaw)) - if convMode != transfer && convMode != deploy { - return errInvalidMode - } - - // Validate the correct mode params - if convMode == deploy && p.contractPath == "" { - return errContractPath + // check if valid mode is selected + if err := p.isValidMode(); err != nil { + return err } - if err := p.initRawParams(); err != nil { - return errInvalidValues + // validate the correct mode params + if err := p.hasValidDeployParams(); err != nil { + return err } return nil @@ -96,6 +108,10 @@ func (p *loadbotParams) initRawParams() error { return err } + if err := p.initContractArtifactAndArgs(); err != nil { + return err + } + return nil } @@ -187,5 +203,73 @@ func (p *loadbotParams) generateConfig( GasPrice: p.gasPrice, GasLimit: p.gasLimit, ContractArtifact: p.contractArtifact, + ConstructorArgs: p.constructorArgs, + MaxWait: p.maxWait, + } +} + +func (p *loadbotParams) isValidMode() error { + // Set and validate the correct mode type + p.mode = Mode(strings.ToLower(p.modeRaw)) + + switch p.mode { + case transfer, deploy, erc20, erc721: + return nil + + default: + return errInvalidMode + } +} + +func (p *loadbotParams) hasValidDeployParams() error { + // fail if mode is deploy but we have no contract + if p.mode == deploy && p.contractPath == "" { + return errContractPath + } + + return nil +} + +func (p *loadbotParams) initContractArtifactAndArgs() error { + var ( + ctrArtifact *generator.ContractArtifact + ctrArgs []byte + err error + ) + + switch p.mode { + case erc20: + ctrArtifact = &generator.ContractArtifact{ + Bytecode: ERC20BIN, + ABI: abi.MustNewABI(ERC20ABI), + } + + if ctrArgs, err = abi.Encode( + []string{erc20TokenSupply, erc20TokenName, erc20TokenSymbol}, ctrArtifact.ABI.Constructor.Inputs); err != nil { + return fmt.Errorf("failed to encode erc20 constructor parameters: %w", err) + } + + case erc721: + ctrArtifact = &generator.ContractArtifact{ + Bytecode: ERC721BIN, + ABI: abi.MustNewABI(ERC721ABI), + } + + if ctrArgs, err = abi.Encode( + []string{erc721TokenName, erc721TokenSymbol}, + ctrArtifact.ABI.Constructor.Inputs); err != nil { + return fmt.Errorf("failed to encode erc721 constructor parameters: %w", err) + } + + default: + ctrArtifact = &generator.ContractArtifact{ + Bytecode: generator.DefaultContractBytecode, + } + ctrArgs = nil } + + p.contractArtifact = ctrArtifact + p.constructorArgs = ctrArgs + + return nil } diff --git a/command/loadbot/result.go b/command/loadbot/result.go index 2d91d62cd0..1a8f131a9d 100644 --- a/command/loadbot/result.go +++ b/command/loadbot/result.go @@ -3,12 +3,13 @@ package loadbot import ( "bytes" "fmt" + "math" + "sort" + "github.com/0xPolygon/polygon-edge/command/helper" "github.com/0xPolygon/polygon-edge/command/loadbot/generator" "github.com/0xPolygon/polygon-edge/helper/common" "github.com/umbracle/go-web3" - "math" - "sort" ) const ( @@ -33,6 +34,9 @@ type TxnBlockData struct { // BlockTransactionsMap maps the block number to the number of loadbot transactions in it BlockTransactionsMap map[uint64]uint64 `json:"block_transactions_map"` + + // Total amount of gas used in block + GasData map[uint64]GasMetrics `json:"gas_used"` } type TxnDetailedErrorData struct { @@ -42,11 +46,14 @@ type TxnDetailedErrorData struct { } type LoadbotResult struct { - CountData TxnCountData `json:"count_data"` - TurnAroundData TxnTurnAroundData `json:"turn_around_data"` - BlockData TxnBlockData `json:"block_data"` - DetailedErrorData TxnDetailedErrorData `json:"detailed_error_data,omitempty"` - ApproxTPS uint64 `json:"approx_tps"` + CountData TxnCountData `json:"count_data"` + TurnAroundData TxnTurnAroundData `json:"turn_around_data"` + ContractTurnAroundData TxnTurnAroundData `json:"contract_turn_around_data"` + BlockData TxnBlockData `json:"block_data"` + DetailedErrorData TxnDetailedErrorData `json:"detailed_error_data,omitempty"` + ApproxTPS uint64 `json:"approx_tps"` + ContractAddress web3.Address `json:"contract_address,omitempty"` + ContractBlockData TxnBlockData `json:"contract_block_data,omitempty"` } func (lr *LoadbotResult) initExecutionData(metrics *Metrics) { @@ -78,6 +85,34 @@ func (lr *LoadbotResult) initExecutionData(metrics *Metrics) { lr.BlockData = TxnBlockData{ BlocksRequired: uint64(len(metrics.TransactionDuration.blockTransactions)), BlockTransactionsMap: metrics.TransactionDuration.blockTransactions, + GasData: metrics.GasMetrics.Blocks, + } +} + +func (lr *LoadbotResult) initContractDeploymentModesExecutionData(metrics *Metrics) { + // set contract deployment metrics + lr.ContractTurnAroundData.FastestTurnAround = common.ToFixedFloat( + metrics.ContractMetrics.ContractDeploymentDuration.FastestTurnAround.Seconds(), + durationPrecision, + ) + lr.ContractTurnAroundData.SlowestTurnAround = common.ToFixedFloat( + metrics.ContractMetrics.ContractDeploymentDuration.SlowestTurnAround.Seconds(), + durationPrecision, + ) + lr.ContractTurnAroundData.AverageTurnAround = common.ToFixedFloat( + metrics.ContractMetrics.ContractDeploymentDuration.AverageTurnAround.Seconds(), + durationPrecision, + ) + lr.ContractTurnAroundData.TotalExecTime = common.ToFixedFloat( + metrics.ContractMetrics.ContractDeploymentDuration.TotalExecTime.Seconds(), + durationPrecision, + ) + // set contract address + lr.ContractAddress = metrics.ContractMetrics.ContractAddress + lr.ContractBlockData = TxnBlockData{ + BlocksRequired: uint64(len(metrics.ContractMetrics.ContractDeploymentDuration.blockTransactions)), + BlockTransactionsMap: metrics.ContractMetrics.ContractDeploymentDuration.blockTransactions, + GasData: metrics.ContractMetrics.ContractGasMetrics.Blocks, } } @@ -103,18 +138,22 @@ func (lr *LoadbotResult) initDetailedErrors(gen generator.TransactionGenerator) lr.DetailedErrorData.DetailedErrorMap = errMap } -func (lr *LoadbotResult) writeBlockData(buffer bytes.Buffer) { +func (lr *LoadbotResult) writeBlockData(buffer *bytes.Buffer) { + //nolint: ifshort + blockData := &lr.BlockData + buffer.WriteString("\n\n[BLOCK DATA]\n") + buffer.WriteString(helper.FormatKV([]string{ - fmt.Sprintf("Blocks required|%d", lr.BlockData.BlocksRequired), + fmt.Sprintf("Blocks required|%d", blockData.BlocksRequired), })) - if lr.BlockData.BlocksRequired != 0 { + if blockData.BlocksRequired != 0 { buffer.WriteString("\n\n") - keys := make([]uint64, 0, lr.BlockData.BlocksRequired) + keys := make([]uint64, 0, blockData.BlocksRequired) - for k := range lr.BlockData.BlockTransactionsMap { + for k := range blockData.BlockTransactionsMap { keys = append(keys, k) } @@ -126,15 +165,20 @@ func (lr *LoadbotResult) writeBlockData(buffer bytes.Buffer) { for _, blockNumber := range keys { formattedStrings = append(formattedStrings, - fmt.Sprintf("Block #%d|%d txns", blockNumber, lr.BlockData.BlockTransactionsMap[blockNumber]), - ) + fmt.Sprintf("Block #%d|%d txns (%d gasUsed / %d gasLimit) utilization | %.2f%%", + blockNumber, + blockData.BlockTransactionsMap[blockNumber], + blockData.GasData[blockNumber].GasUsed, + blockData.GasData[blockNumber].GasLimit, + blockData.GasData[blockNumber].Utilization, + )) } buffer.WriteString(helper.FormatKV(formattedStrings)) } } -func (lr *LoadbotResult) writeErrorData(buffer bytes.Buffer) { +func (lr *LoadbotResult) writeErrorData(buffer *bytes.Buffer) { // Write out the error logs if detailed view // is requested if len(lr.DetailedErrorData.DetailedErrorMap) != 0 { @@ -176,26 +220,35 @@ func (lr *LoadbotResult) writeErrorData(buffer bytes.Buffer) { } func (lr *LoadbotResult) GetOutput() string { - var buffer bytes.Buffer + buffer := new(bytes.Buffer) lr.writeLoadbotResults(buffer) return buffer.String() } -func (lr *LoadbotResult) writeLoadbotResults(buffer bytes.Buffer) { +func (lr *LoadbotResult) writeLoadbotResults(buffer *bytes.Buffer) { buffer.WriteString("\n=====[LOADBOT RUN]=====\n") lr.writeCountData(buffer) lr.writeApproximateTPSData(buffer) + lr.writeContractDeploymentData(buffer) lr.writeTurnAroundData(buffer) lr.writeBlockData(buffer) + lr.writeAverageBlockUtilization(buffer) lr.writeErrorData(buffer) buffer.WriteString("\n") } -func (lr *LoadbotResult) writeCountData(buffer bytes.Buffer) { +func (lr *LoadbotResult) writeAverageBlockUtilization(buffer *bytes.Buffer) { + buffer.WriteString("\n\n[AVERAGE BLOCK UTILIZATION]\n") + buffer.WriteString(helper.FormatKV([]string{ + fmt.Sprintf("Average utilization acorss all blocks|%.2f%%", calculateAvgBlockUtil(lr.BlockData.GasData)), + })) +} + +func (lr *LoadbotResult) writeCountData(buffer *bytes.Buffer) { buffer.WriteString("\n[COUNT DATA]\n") buffer.WriteString(helper.FormatKV([]string{ fmt.Sprintf("Transactions submitted|%d", lr.CountData.Total), @@ -203,14 +256,14 @@ func (lr *LoadbotResult) writeCountData(buffer bytes.Buffer) { })) } -func (lr *LoadbotResult) writeApproximateTPSData(buffer bytes.Buffer) { +func (lr *LoadbotResult) writeApproximateTPSData(buffer *bytes.Buffer) { buffer.WriteString("\n\n[APPROXIMATE TPS]\n") buffer.WriteString(helper.FormatKV([]string{ fmt.Sprintf("Approximate number of transactions per second|%d", lr.ApproxTPS), })) } -func (lr *LoadbotResult) writeTurnAroundData(buffer bytes.Buffer) { +func (lr *LoadbotResult) writeTurnAroundData(buffer *bytes.Buffer) { buffer.WriteString("\n\n[TURN AROUND DATA]\n") buffer.WriteString(helper.FormatKV([]string{ fmt.Sprintf("Average transaction turn around|%fs", lr.TurnAroundData.AverageTurnAround), @@ -220,7 +273,41 @@ func (lr *LoadbotResult) writeTurnAroundData(buffer bytes.Buffer) { })) } -func newLoadbotResult(metrics *Metrics) *LoadbotResult { +func (lr *LoadbotResult) writeContractDeploymentData(buffer *bytes.Buffer) { + // skip if contract was not deployed + if lr.ContractAddress == web3.ZeroAddress { + return + } + + buffer.WriteString("\n\n[CONTRACT DEPLOYMENT INFO]\n") + buffer.WriteString(helper.FormatKV([]string{ + fmt.Sprintf("Contract address|%s", lr.ContractAddress), + fmt.Sprintf("Total execution time|%fs", lr.ContractTurnAroundData.TotalExecTime), + })) + + buffer.WriteString("\n\n[CONTRACT DEPLOYMENT BLOCK DATA]\n") + buffer.WriteString(helper.FormatKV([]string{ + fmt.Sprintf("Blocks required|%d", lr.ContractBlockData.BlocksRequired), + })) + buffer.WriteString("\n") + + formattedStrings := make([]string, 0) + + for blockNumber := range lr.ContractBlockData.BlockTransactionsMap { + formattedStrings = append(formattedStrings, + fmt.Sprintf("Block #%d|%d txns (%d gasUsed / %d gasLimit) utilization | %.2f%%", + blockNumber, + lr.ContractBlockData.BlockTransactionsMap[blockNumber], + lr.ContractBlockData.GasData[blockNumber].GasUsed, + lr.ContractBlockData.GasData[blockNumber].GasLimit, + lr.ContractBlockData.GasData[blockNumber].Utilization, + )) + } + + buffer.WriteString(helper.FormatKV(formattedStrings)) +} + +func newLoadbotResult(metrics *Metrics, mode Mode) *LoadbotResult { res := &LoadbotResult{ CountData: TxnCountData{ Total: metrics.TotalTransactionsSentCount, @@ -228,6 +315,10 @@ func newLoadbotResult(metrics *Metrics) *LoadbotResult { }, } + if mode == erc20 || mode == erc721 { + res.initContractDeploymentModesExecutionData(metrics) + } + res.initExecutionData(metrics) return res diff --git a/go.mod b/go.mod index b51cd68583..0b8e312639 100644 --- a/go.mod +++ b/go.mod @@ -53,6 +53,7 @@ require ( github.com/mitchellh/mapstructure v1.4.3 // indirect github.com/valyala/fastjson v1.6.3 // indirect go.uber.org/zap v1.20.0 // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect golang.org/x/tools v0.1.9 // indirect google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect diff --git a/jsonrpc/eth_blockchain_test.go b/jsonrpc/eth_blockchain_test.go index 8f49e51e44..a32f585227 100644 --- a/jsonrpc/eth_blockchain_test.go +++ b/jsonrpc/eth_blockchain_test.go @@ -3,13 +3,14 @@ package jsonrpc import ( "errors" "fmt" + "math/big" + "strconv" + "testing" + "github.com/0xPolygon/polygon-edge/helper/progress" "github.com/0xPolygon/polygon-edge/state/runtime" "github.com/0xPolygon/polygon-edge/types" "github.com/stretchr/testify/assert" - "math/big" - "strconv" - "testing" ) func TestEth_Block_GetBlockByNumber(t *testing.T) { @@ -318,7 +319,7 @@ func TestEth_Syncing(t *testing.T) { res, err := eth.Syncing() assert.NoError(t, err) - // nolint:forcetypeassert + //nolint:forcetypeassert assert.False(t, res.(bool)) }) } diff --git a/jsonrpc/eth_state_test.go b/jsonrpc/eth_state_test.go index 721e7a2be6..f4885b168f 100644 --- a/jsonrpc/eth_state_test.go +++ b/jsonrpc/eth_state_test.go @@ -4,6 +4,9 @@ import ( "bytes" "errors" "fmt" + "math/big" + "testing" + "github.com/0xPolygon/polygon-edge/chain" "github.com/0xPolygon/polygon-edge/helper/hex" "github.com/0xPolygon/polygon-edge/state" @@ -11,8 +14,6 @@ import ( "github.com/0xPolygon/polygon-edge/types" "github.com/stretchr/testify/assert" "github.com/umbracle/fastrlp" - "math/big" - "testing" ) var ( diff --git a/state/txn.go b/state/txn.go index 102590b0e2..5c4362807d 100644 --- a/state/txn.go +++ b/state/txn.go @@ -1,4 +1,3 @@ -//nolint:forcetypeassert package state import ( @@ -355,7 +354,7 @@ func (txn *Txn) GetState(addr types.Address, key types.Hash) types.Hash { if val == nil { return types.Hash{} } - + //nolint:forcetypeassert return types.BytesToHash(val.([]byte)) } } @@ -416,6 +415,7 @@ func (txn *Txn) GetCode(addr types.Address) []byte { v, ok := txn.codeCache.Get(addr) if ok { + //nolint:forcetypeassert return v.([]byte) } @@ -482,7 +482,7 @@ func (txn *Txn) Logs() []*types.Log { } txn.txn.Delete(logIndex) - + //nolint:forcetypeassert return data.([]*types.Log) } @@ -492,6 +492,7 @@ func (txn *Txn) GetRefund() uint64 { return 0 } + //nolint:forcetypeassert return data.(uint64) } diff --git a/vendor/modules.txt b/vendor/modules.txt index 32bbbfbe42..c8d803c2c4 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -624,6 +624,7 @@ golang.org/x/net/ipv6 golang.org/x/net/route golang.org/x/net/trace # golang.org/x/sync v0.0.0-20210220032951-036812b2e83c +## explicit golang.org/x/sync/errgroup # golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 ## explicit