diff --git a/common/releases/contract.go b/common/releases/contract.go index 11f226cbe7..0e17d9f6fe 100644 --- a/common/releases/contract.go +++ b/common/releases/contract.go @@ -4,6 +4,7 @@ package releases import ( + "math/big" "strings" "github.com/ethereum/go-ethereum/accounts/abi" @@ -13,10 +14,10 @@ import ( ) // ReleaseOracleABI is the input ABI used to generate the binding from. -const ReleaseOracleABI = `[{"constant":true,"inputs":[],"name":"AuthProposals","outputs":[{"name":"","type":"address[]"}],"type":"function"},{"constant":false,"inputs":[{"name":"user","type":"address"}],"name":"Promote","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"user","type":"address"},{"name":"authorize","type":"bool"}],"name":"updateStatus","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"user","type":"address"}],"name":"Demote","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"user","type":"address"}],"name":"AuthVotes","outputs":[{"name":"promote","type":"address[]"},{"name":"demote","type":"address[]"}],"type":"function"},{"constant":true,"inputs":[],"name":"Signers","outputs":[{"name":"","type":"address[]"}],"type":"function"},{"inputs":[],"type":"constructor"}]` +const ReleaseOracleABI = `[{"constant":false,"inputs":[],"name":"Nuke","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"major","type":"uint32"},{"name":"minor","type":"uint32"},{"name":"patch","type":"uint32"},{"name":"commit","type":"bytes20"}],"name":"Release","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"AuthProposals","outputs":[{"name":"","type":"address[]"}],"type":"function"},{"constant":true,"inputs":[],"name":"CurrentVersion","outputs":[{"name":"major","type":"uint32"},{"name":"minor","type":"uint32"},{"name":"patch","type":"uint32"},{"name":"commit","type":"bytes20"},{"name":"time","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"ProposedVersion","outputs":[{"name":"major","type":"uint32"},{"name":"minor","type":"uint32"},{"name":"patch","type":"uint32"},{"name":"commit","type":"bytes20"},{"name":"pass","type":"address[]"},{"name":"fail","type":"address[]"}],"type":"function"},{"constant":false,"inputs":[{"name":"user","type":"address"}],"name":"Promote","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"major","type":"uint32"},{"name":"minor","type":"uint32"},{"name":"patch","type":"uint32"},{"name":"commit","type":"bytes20"},{"name":"release","type":"bool"}],"name":"updateRelease","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"user","type":"address"}],"name":"Demote","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"user","type":"address"}],"name":"AuthVotes","outputs":[{"name":"promote","type":"address[]"},{"name":"demote","type":"address[]"}],"type":"function"},{"constant":true,"inputs":[],"name":"Signers","outputs":[{"name":"","type":"address[]"}],"type":"function"},{"constant":false,"inputs":[{"name":"user","type":"address"},{"name":"authorize","type":"bool"}],"name":"updateSigner","outputs":[],"type":"function"},{"inputs":[],"type":"constructor"}]` // ReleaseOracleBin is the compiled bytecode used for deploying new contracts. -const ReleaseOracleBin = `0x6060604052600160a060020a0333166000908152602081905260409020805460ff1916600190811790915580548082018083558281838015829011606257818360005260206000209182019101606291905b808211156094576000815584016051565b505050919090600052602060002090016000508054600160a060020a03191633179055506108d3806100986000396000f35b509056606060405236156100565760e060020a6000350463282fe4e581146100585780636195db9c146100c45780637444144b146100d557806380bbbd4a1461015b578063a29226f21461016c578063f04c475814610266575b005b604080516020818101835260008252600380548451818402810184019095528085526102d294928301828280156102c757602002820191906000526020600020908154600160a060020a03168152600191909101906020018083116102a8575b505050505090506102cf565b6100566004356103a18160016100df565b6100566004356024355b33600160a060020a0316600090815260208190526040812054819060ff161561088557600160a060020a038416815260026020526040812091505b81548110156103a457815433600160a060020a0316908390839081101561000257600091825260209091200154600160a060020a031614156103ef57610885565b6100566004356103a18160006100df565b61031c6004356040805160208181018352600080835283518083018552818152600160a060020a03861682526002835290849020805485518185028101850190965280865293949193909260018401929184918301828280156101f957602002820191906000526020600020905b8154600160a060020a03168152600191909101906020018083116101da575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561025657602002820191906000526020600020905b8154600160a060020a0316815260019190910190602001808311610237575b5050505050905091509150915091565b604080516020818101835260008252600180548451818402810184019095528085526102d294928301828280156102c757602002820191906000526020600020905b8154600160a060020a03168152600191909101906020018083116102a8575b505050505090505b90565b60405180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600f02600301f1509050019250505060405180910390f35b6040518080602001806020018381038352858181518152602001915080519060200190602002808383829060006004602084601f0104600f02600301f1509050018381038252848181518152602001915080519060200190602002808383829060006004602084601f0104600f02600301f15090500194505050505060405180910390f35b50565b5060005b60018201548110156103f75733600160a060020a03168260010160005082815481101561000257600091825260209091200154600160a060020a0316141561044157610885565b60010161011a565b8154600014801561040c575060018201546000145b1561046957600380546001810180835582818380158290116104495781836000526020600020918201910161044991906104ef565b6001016103a8565b5050506000928352506020909120018054600160a060020a031916851790555b821561050757815460018101808455839190828183801582901161053c5760008381526020902061053c9181019083016104ef565b5050506000928352506020909120018054600160a060020a031916851790555b600160a060020a03841660009081526002602090815260408220805483825581845291832090929161077091908101905b8082111561050357600081556001016104ef565b5090565b8160010160005080548060010182818154818355818115116105f8578183600052602060002091820191016105f891906104ef565b5050506000928352506020909120018054600160a060020a0319163317905560015482546002909104901161057057610885565b8280156105965750600160a060020a03841660009081526020819052604090205460ff16155b1561062f57600160a060020a0384166000908152602081905260409020805460ff191660019081179091558054808201808355828183801582901161049e57600083905261049e906000805160206108b38339815191529081019083016104ef565b5050506000928352506020909120018054600160a060020a0319163317905560018054908301546002909104901161057057610885565b821580156106555750600160a060020a03841660009081526020819052604090205460ff165b156104be5750600160a060020a0383166000908152602081905260408120805460ff191690555b6001548110156104be5783600160a060020a03166001600050828154811015610002576000919091526000805160206108b38339815191520154600160a060020a0316141561075f57600180546000198101908110156100025760009182526000805160206108b383398151915201909054906101000a9004600160a060020a03166001600050828154811015610002576000805160206108b3833981519152018054600160a060020a031916909217909155805460001981018083559091908280158290116107675781836000526020600020918201910161076791906104ef565b60010161067c565b505050506104be565b5060018201805460008083559182526020909120610790918101906104ef565b506000925050505b6003548110156108855783600160a060020a03166003600050828154811015610002576000919091526000805160206108938339815191520154600160a060020a0316141561088b576003805460001981019081101561000257600091825260008051602061089383398151915201909054906101000a9004600160a060020a0316600360005082815481101561000257600080516020610893833981519152018054600160a060020a0319169092179091558054600019810180835590919082801582901161088057610880906000805160206108938339815191529081019083016104ef565b505050505b50505050565b60010161079856c2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85bb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6` +const ReleaseOracleBin = `0x6060604052600160a060020a0333166000908152602081905260409020805460ff1916600190811790915580548082018083558281838015829011606257818360005260206000209182019101606291905b808211156094576000815584016051565b505050919090600052602060002090016000508054600160a060020a03191633179055506111e7806100986000396000f35b5090566060604052361561008d5760e060020a60003504630443b1ad811461008f5780630d618178146100a0578063282fe4e5146100bd5780632b225f291461012c5780634c327071146101da5780636195db9c146102ff578063645dce721461031057806380bbbd4a1461035f578063a29226f214610370578063f04c47581461046a578063f460590b146104d6575b005b61008d610720600080808080610323565b61008d60043560243560443560643561071a848484846001610323565b61055c6040805160208181018352600082528251600380548084028301840190955284825292939092918301828280156104cb57602002820191906000526020600020908154600160a060020a03168152600191909101906020018083116104ac575b505050505090506104d3565b6105a660088054600091829182918291829182916000198101908110156100025791526004027ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee38101547ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee49091015463ffffffff82811698640100000000840482169850604060020a84049091169650606060020a92839004909202945067ffffffffffffffff1692509050565b6105da604080516020818101835260008083528351808301855281815260045460068054875181870281018701909852808852939687968796879691959463ffffffff818116956401000000008304821695604060020a840490921694606060020a938490049093029390926007929184919083018282801561028757602002820191906000526020600020905b8154600160a060020a0316815260019190910190602001808311610268575b50505050509150808054806020026020016040519081016040528092919081815260200182805480156102e457602002820191906000526020600020905b8154600160a060020a03168152600191909101906020018083116102c5575b50505050509050955095509550955095509550909192939495565b61008d6004356107128160016104e0565b61008d6004356024356044356064356084355b600160a060020a033316600090815260208190526040812054819060ff161561117e5782158015610355575060065481145b15610c065761117e565b61008d6004356107128160006104e0565b61068d6004356040805160208181018352600080835283518083018552818152600160a060020a03861682526002835290849020805485518185028101850190965280865293949193909260018401929184918301828280156103fd57602002820191906000526020600020905b8154600160a060020a03168152600191909101906020018083116103de575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561045a57602002820191906000526020600020905b8154600160a060020a031681526001919091019060200180831161043b575b5050505050905091509150915091565b6040805160208181018352600082526001805484518184028101840190955280855261055c94928301828280156104cb57602002820191906000526020600020905b8154600160a060020a03168152600191909101906020018083116104ac575b505050505090505b90565b61008d6004356024355b600160a060020a033316600090815260208190526040812054819060ff161561071a57600160a060020a038416815260026020526040812091505b8154811015610722578154600160a060020a033316908390839081101561000257600091825260209091200154600160a060020a0316141561076d5761071a565b60405180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600f02600301f1509050019250505060405180910390f35b6040805163ffffffff9687168152948616602086015294909216838501526060830152608082015290519081900360a00190f35b604051808763ffffffff1681526020018663ffffffff1681526020018563ffffffff16815260200184815260200180602001806020018381038352858181518152602001915080519060200190602002808383829060006004602084601f0104600f02600301f1509050018381038252848181518152602001915080519060200190602002808383829060006004602084601f0104600f02600301f1509050019850505050505050505060405180910390f35b6040518080602001806020018381038352858181518152602001915080519060200190602002808383829060006004602084601f0104600f02600301f1509050018381038252848181518152602001915080519060200190602002808383829060006004602084601f0104600f02600301f15090500194505050505060405180910390f35b50565b505050505b50505050565b565b5060005b60018201548110156107755733600160a060020a03168260010160005082815481101561000257600091825260209091200154600160a060020a031614156107bf5761071a565b60010161051b565b8154600014801561078a575060018201546000145b156107e757600380546001810180835582818380158290116107c7578183600052602060002091820191016107c7919061086d565b600101610726565b5050506000928352506020909120018054600160a060020a031916851790555b82156108855781546001810180845583919082818380158290116108ba576000838152602090206108ba91810190830161086d565b5050506000928352506020909120018054600160a060020a031916851790555b600160a060020a038416600090815260026020908152604082208054838255818452918320909291610aee91908101905b80821115610881576000815560010161086d565b5090565b81600101600050805480600101828181548183558181151161097657818360005260206000209182019101610976919061086d565b5050506000928352506020909120018054600160a060020a031916331790556001548254600290910490116108ee5761071a565b8280156109145750600160a060020a03841660009081526020819052604090205460ff16155b156109ad57600160a060020a0384166000908152602081905260409020805460ff191660019081179091558054808201808355828183801582901161081c57600083905261081c906000805160206111c783398151915290810190830161086d565b5050506000928352506020909120018054600160a060020a031916331790556001805490830154600290910490116108ee5761071a565b821580156109d35750600160a060020a03841660009081526020819052604090205460ff165b1561083c5750600160a060020a0383166000908152602081905260408120805460ff191690555b60015481101561083c5783600160a060020a03166001600050828154811015610002576000919091526000805160206111c78339815191520154600160a060020a03161415610add57600180546000198101908110156100025760009182526000805160206111c783398151915201909054906101000a9004600160a060020a03166001600050828154811015610002576000805160206111c7833981519152018054600160a060020a03191690921790915580546000198101808355909190828015829011610ae557818360005260206000209182019101610ae5919061086d565b6001016109fa565b5050505061083c565b5060018201805460008083559182526020909120610b0e9181019061086d565b506000925050505b60035481101561071a5783600160a060020a03166003600050828154811015610002576000919091526000805160206111a78339815191520154600160a060020a03161415610bfe57600380546000198101908110156100025760009182526000805160206111a783398151915201909054906101000a9004600160a060020a03166003600050828154811015610002576000805160206111a7833981519152018054600160a060020a0319169092179091558054600019810180835590919082801582901161071557610715906000805160206111a783398151915290810190830161086d565b600101610b16565b60065460001415610c64576004805463ffffffff1916881767ffffffff0000000019166401000000008802176bffffffff00000000000000001916604060020a8702176bffffffffffffffffffffffff16606060020a808704021790555b828015610cce575060045463ffffffff8881169116141580610c9a5750600454640100000000900463ffffffff90811690871614155b80610cb7575060045463ffffffff808716604060020a9092041614155b80610cce5750600454606060020a90819004028414155b15610cd85761117e565b506006905060005b8154811015610d21578154600160a060020a033316908390839081101561000257600091825260209091200154600160a060020a03161415610d6c5761117e565b5060005b6001820154811015610d745733600160a060020a03168260010160005082815481101561000257600091825260209091200154600160a060020a03161415610dab5761117e565b600101610ce0565b8215610db3578154600181018084558391908281838015829011610de857818360005260206000209182019101610de8919061086d565b600101610d25565b816001016000508054806001018281815481835581811511610e6b57818360005260206000209182019101610e6b919061086d565b5050506000928352506020909120018054600160a060020a03191633179055600154825460029091049011610e1c5761117e565b8215610ea2576005805467ffffffffffffffff19164217905560088054600181018083558281838015829011610ef757600402816004028360005260206000209182019101610ef79190611010565b5050506000928352506020909120018054600160a060020a03191633179055600180549083015460029091049011610e1c5761117e565b600060048181556005805467ffffffffffffffff19169055600680548382558184529192918290611187907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f9081019061086d565b5050509190906000526020600020906004020160005060048054825463ffffffff191663ffffffff9182161780845582546401000000009081900483160267ffffffff000000001991909116178084558254604060020a908190049092169091026bffffffff00000000000000001991909116178083558154606060020a908190048102819004026bffffffffffffffffffffffff9190911617825560055460018301805467ffffffffffffffff191667ffffffffffffffff90921691909117905560068054600284018054828255600082815260209020949594919283929182019185821561106f5760005260206000209182015b8281111561106f578254825591600101919060010190610fed565b505050506001015b8082111561088157600080825560018201805467ffffffffffffffff1916905560028201805482825581835260208320839161104f919081019061086d565b50600182018054600080835591825260209091206110089181019061086d565b506110959291505b80821115610881578054600160a060020a0319168155600101611077565b50506001818101805491840180548083556000838152602090209293830192909182156110e35760005260206000209182015b828111156110e35782548255916001019190600101906110c8565b506110ef929150611077565b5050600060048181556005805467ffffffffffffffff191690556006805483825581845291975091955090935084925061114e91507ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f9081019061086d565b506001820180546000808355918252602090912061116e9181019061086d565b505050505061117e565b50505050505b50505050505050565b50600182018054600080835591825260209091206111789181019061086d56c2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85bb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6` // DeployReleaseOracle deploys a new Ethereum contract, binding an instance of ReleaseOracle to it. func DeployReleaseOracle(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ReleaseOracle, error) { @@ -220,6 +221,106 @@ func (_ReleaseOracle *ReleaseOracleCallerSession) AuthVotes(user common.Address) return _ReleaseOracle.Contract.AuthVotes(&_ReleaseOracle.CallOpts, user) } +// CurrentVersion is a free data retrieval call binding the contract method 0x2b225f29. +// +// Solidity: function CurrentVersion() constant returns(major uint32, minor uint32, patch uint32, commit bytes20, time uint256) +func (_ReleaseOracle *ReleaseOracleCaller) CurrentVersion(opts *bind.CallOpts) (struct { + Major uint32 + Minor uint32 + Patch uint32 + Commit [20]byte + Time *big.Int +}, error) { + ret := new(struct { + Major uint32 + Minor uint32 + Patch uint32 + Commit [20]byte + Time *big.Int + }) + out := ret + err := _ReleaseOracle.contract.Call(opts, out, "CurrentVersion") + return *ret, err +} + +// CurrentVersion is a free data retrieval call binding the contract method 0x2b225f29. +// +// Solidity: function CurrentVersion() constant returns(major uint32, minor uint32, patch uint32, commit bytes20, time uint256) +func (_ReleaseOracle *ReleaseOracleSession) CurrentVersion() (struct { + Major uint32 + Minor uint32 + Patch uint32 + Commit [20]byte + Time *big.Int +}, error) { + return _ReleaseOracle.Contract.CurrentVersion(&_ReleaseOracle.CallOpts) +} + +// CurrentVersion is a free data retrieval call binding the contract method 0x2b225f29. +// +// Solidity: function CurrentVersion() constant returns(major uint32, minor uint32, patch uint32, commit bytes20, time uint256) +func (_ReleaseOracle *ReleaseOracleCallerSession) CurrentVersion() (struct { + Major uint32 + Minor uint32 + Patch uint32 + Commit [20]byte + Time *big.Int +}, error) { + return _ReleaseOracle.Contract.CurrentVersion(&_ReleaseOracle.CallOpts) +} + +// ProposedVersion is a free data retrieval call binding the contract method 0x4c327071. +// +// Solidity: function ProposedVersion() constant returns(major uint32, minor uint32, patch uint32, commit bytes20, pass address[], fail address[]) +func (_ReleaseOracle *ReleaseOracleCaller) ProposedVersion(opts *bind.CallOpts) (struct { + Major uint32 + Minor uint32 + Patch uint32 + Commit [20]byte + Pass []common.Address + Fail []common.Address +}, error) { + ret := new(struct { + Major uint32 + Minor uint32 + Patch uint32 + Commit [20]byte + Pass []common.Address + Fail []common.Address + }) + out := ret + err := _ReleaseOracle.contract.Call(opts, out, "ProposedVersion") + return *ret, err +} + +// ProposedVersion is a free data retrieval call binding the contract method 0x4c327071. +// +// Solidity: function ProposedVersion() constant returns(major uint32, minor uint32, patch uint32, commit bytes20, pass address[], fail address[]) +func (_ReleaseOracle *ReleaseOracleSession) ProposedVersion() (struct { + Major uint32 + Minor uint32 + Patch uint32 + Commit [20]byte + Pass []common.Address + Fail []common.Address +}, error) { + return _ReleaseOracle.Contract.ProposedVersion(&_ReleaseOracle.CallOpts) +} + +// ProposedVersion is a free data retrieval call binding the contract method 0x4c327071. +// +// Solidity: function ProposedVersion() constant returns(major uint32, minor uint32, patch uint32, commit bytes20, pass address[], fail address[]) +func (_ReleaseOracle *ReleaseOracleCallerSession) ProposedVersion() (struct { + Major uint32 + Minor uint32 + Patch uint32 + Commit [20]byte + Pass []common.Address + Fail []common.Address +}, error) { + return _ReleaseOracle.Contract.ProposedVersion(&_ReleaseOracle.CallOpts) +} + // Signers is a free data retrieval call binding the contract method 0xf04c4758. // // Solidity: function Signers() constant returns(address[]) @@ -267,6 +368,27 @@ func (_ReleaseOracle *ReleaseOracleTransactorSession) Demote(user common.Address return _ReleaseOracle.Contract.Demote(&_ReleaseOracle.TransactOpts, user) } +// Nuke is a paid mutator transaction binding the contract method 0x0443b1ad. +// +// Solidity: function Nuke() returns() +func (_ReleaseOracle *ReleaseOracleTransactor) Nuke(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReleaseOracle.contract.Transact(opts, "Nuke") +} + +// Nuke is a paid mutator transaction binding the contract method 0x0443b1ad. +// +// Solidity: function Nuke() returns() +func (_ReleaseOracle *ReleaseOracleSession) Nuke() (*types.Transaction, error) { + return _ReleaseOracle.Contract.Nuke(&_ReleaseOracle.TransactOpts) +} + +// Nuke is a paid mutator transaction binding the contract method 0x0443b1ad. +// +// Solidity: function Nuke() returns() +func (_ReleaseOracle *ReleaseOracleTransactorSession) Nuke() (*types.Transaction, error) { + return _ReleaseOracle.Contract.Nuke(&_ReleaseOracle.TransactOpts) +} + // Promote is a paid mutator transaction binding the contract method 0x6195db9c. // // Solidity: function Promote(user address) returns() @@ -288,23 +410,65 @@ func (_ReleaseOracle *ReleaseOracleTransactorSession) Promote(user common.Addres return _ReleaseOracle.Contract.Promote(&_ReleaseOracle.TransactOpts, user) } -// UpdateStatus is a paid mutator transaction binding the contract method 0x7444144b. +// Release is a paid mutator transaction binding the contract method 0x0d618178. // -// Solidity: function updateStatus(user address, authorize bool) returns() -func (_ReleaseOracle *ReleaseOracleTransactor) UpdateStatus(opts *bind.TransactOpts, user common.Address, authorize bool) (*types.Transaction, error) { - return _ReleaseOracle.contract.Transact(opts, "updateStatus", user, authorize) +// Solidity: function Release(major uint32, minor uint32, patch uint32, commit bytes20) returns() +func (_ReleaseOracle *ReleaseOracleTransactor) Release(opts *bind.TransactOpts, major uint32, minor uint32, patch uint32, commit [20]byte) (*types.Transaction, error) { + return _ReleaseOracle.contract.Transact(opts, "Release", major, minor, patch, commit) } -// UpdateStatus is a paid mutator transaction binding the contract method 0x7444144b. +// Release is a paid mutator transaction binding the contract method 0x0d618178. // -// Solidity: function updateStatus(user address, authorize bool) returns() -func (_ReleaseOracle *ReleaseOracleSession) UpdateStatus(user common.Address, authorize bool) (*types.Transaction, error) { - return _ReleaseOracle.Contract.UpdateStatus(&_ReleaseOracle.TransactOpts, user, authorize) +// Solidity: function Release(major uint32, minor uint32, patch uint32, commit bytes20) returns() +func (_ReleaseOracle *ReleaseOracleSession) Release(major uint32, minor uint32, patch uint32, commit [20]byte) (*types.Transaction, error) { + return _ReleaseOracle.Contract.Release(&_ReleaseOracle.TransactOpts, major, minor, patch, commit) } -// UpdateStatus is a paid mutator transaction binding the contract method 0x7444144b. +// Release is a paid mutator transaction binding the contract method 0x0d618178. // -// Solidity: function updateStatus(user address, authorize bool) returns() -func (_ReleaseOracle *ReleaseOracleTransactorSession) UpdateStatus(user common.Address, authorize bool) (*types.Transaction, error) { - return _ReleaseOracle.Contract.UpdateStatus(&_ReleaseOracle.TransactOpts, user, authorize) +// Solidity: function Release(major uint32, minor uint32, patch uint32, commit bytes20) returns() +func (_ReleaseOracle *ReleaseOracleTransactorSession) Release(major uint32, minor uint32, patch uint32, commit [20]byte) (*types.Transaction, error) { + return _ReleaseOracle.Contract.Release(&_ReleaseOracle.TransactOpts, major, minor, patch, commit) +} + +// UpdateRelease is a paid mutator transaction binding the contract method 0x645dce72. +// +// Solidity: function updateRelease(major uint32, minor uint32, patch uint32, commit bytes20, release bool) returns() +func (_ReleaseOracle *ReleaseOracleTransactor) UpdateRelease(opts *bind.TransactOpts, major uint32, minor uint32, patch uint32, commit [20]byte, release bool) (*types.Transaction, error) { + return _ReleaseOracle.contract.Transact(opts, "updateRelease", major, minor, patch, commit, release) +} + +// UpdateRelease is a paid mutator transaction binding the contract method 0x645dce72. +// +// Solidity: function updateRelease(major uint32, minor uint32, patch uint32, commit bytes20, release bool) returns() +func (_ReleaseOracle *ReleaseOracleSession) UpdateRelease(major uint32, minor uint32, patch uint32, commit [20]byte, release bool) (*types.Transaction, error) { + return _ReleaseOracle.Contract.UpdateRelease(&_ReleaseOracle.TransactOpts, major, minor, patch, commit, release) +} + +// UpdateRelease is a paid mutator transaction binding the contract method 0x645dce72. +// +// Solidity: function updateRelease(major uint32, minor uint32, patch uint32, commit bytes20, release bool) returns() +func (_ReleaseOracle *ReleaseOracleTransactorSession) UpdateRelease(major uint32, minor uint32, patch uint32, commit [20]byte, release bool) (*types.Transaction, error) { + return _ReleaseOracle.Contract.UpdateRelease(&_ReleaseOracle.TransactOpts, major, minor, patch, commit, release) +} + +// UpdateSigner is a paid mutator transaction binding the contract method 0xf460590b. +// +// Solidity: function updateSigner(user address, authorize bool) returns() +func (_ReleaseOracle *ReleaseOracleTransactor) UpdateSigner(opts *bind.TransactOpts, user common.Address, authorize bool) (*types.Transaction, error) { + return _ReleaseOracle.contract.Transact(opts, "updateSigner", user, authorize) +} + +// UpdateSigner is a paid mutator transaction binding the contract method 0xf460590b. +// +// Solidity: function updateSigner(user address, authorize bool) returns() +func (_ReleaseOracle *ReleaseOracleSession) UpdateSigner(user common.Address, authorize bool) (*types.Transaction, error) { + return _ReleaseOracle.Contract.UpdateSigner(&_ReleaseOracle.TransactOpts, user, authorize) +} + +// UpdateSigner is a paid mutator transaction binding the contract method 0xf460590b. +// +// Solidity: function updateSigner(user address, authorize bool) returns() +func (_ReleaseOracle *ReleaseOracleTransactorSession) UpdateSigner(user common.Address, authorize bool) (*types.Transaction, error) { + return _ReleaseOracle.Contract.UpdateSigner(&_ReleaseOracle.TransactOpts, user, authorize) } diff --git a/common/releases/contract.sol b/common/releases/contract.sol index 239c160935..992af87595 100644 --- a/common/releases/contract.sol +++ b/common/releases/contract.sol @@ -14,7 +14,6 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . - // ReleaseOracle is an Ethereum contract to store the current and previous // versions of the go-ethereum implementation. Its goal is to allow Geth to // check for new releases automatically without the need to consult a central @@ -29,6 +28,17 @@ contract ReleaseOracle { address[] fail; // List of signers voting to fail a proposal } + // Version is the version details of a particular Geth release + struct Version { + uint32 major; // Major version component of the release + uint32 minor; // Minor version component of the release + uint32 patch; // Patch version component of the release + bytes20 commit; // Git SHA1 commit hash of the release + + uint64 time; // Timestamp of the release approval + Votes votes; // Votes that passed this release + } + // Oracle authorization details mapping(address => bool) authorized; // Set of accounts allowed to vote on updating the contract address[] signers; // List of addresses currently accepted as signers @@ -37,6 +47,9 @@ contract ReleaseOracle { mapping(address => Votes) authProps; // Currently running user authorization proposals address[] authPend; // List of addresses being voted on (map indexes) + Version verProp; // Currently proposed release being voted on + Version[] releases; // All the positively voted releases + // isSigner is a modifier to authorize contract transactions. modifier isSigner() { if (authorized[msg.sender]) { @@ -68,21 +81,46 @@ contract ReleaseOracle { return (authProps[user].pass, authProps[user].fail); } + // CurrentVersion retrieves the semantic version, commit hash and release time + // of the currently votec active release. + function CurrentVersion() constant returns (uint32 major, uint32 minor, uint32 patch, bytes20 commit, uint time) { + var release = releases[releases.length - 1]; + + return (release.major, release.minor, release.patch, release.commit, release.time); + } + + // ProposedVersion retrieves the semantic version, commit hash and the current + // votes for the next proposed release. + function ProposedVersion() constant returns (uint32 major, uint32 minor, uint32 patch, bytes20 commit, address[] pass, address[] fail) { + return (verProp.major, verProp.minor, verProp.patch, verProp.commit, verProp.votes.pass, verProp.votes.fail); + } + // Promote pitches in on a voting campaign to promote a new user to a signer // position. function Promote(address user) { - updateStatus(user, true); + updateSigner(user, true); } // Demote pitches in on a voting campaign to demote an authorized user from // its signer position. function Demote(address user) { - updateStatus(user, false); + updateSigner(user, false); } - // updateStatus marks a vote for changing the status of an Ethereum user, - // either for or against the user being an authorized signer. - function updateStatus(address user, bool authorize) isSigner { + // Release votes for a particular version to be included as the next release. + function Release(uint32 major, uint32 minor, uint32 patch, bytes20 commit) { + updateRelease(major, minor, patch, commit, true); + } + + // Nuke votes for the currently proposed version to not be included as the next + // release. Nuking doesn't require a specific version number for simplicity. + function Nuke() { + updateRelease(0, 0, 0, 0, false); + } + + // updateSigner marks a vote for changing the status of an Ethereum user, either + // for or against the user being an authorized signer. + function updateSigner(address user, bool authorize) isSigner { // Gather the current votes and ensure we don't double vote Votes votes = authProps[user]; for (uint i = 0; i < votes.pass.length; i++) { @@ -137,119 +175,56 @@ contract ReleaseOracle { } } } -/* - address[] public parties; // owners/signers - address[] public deleteAcks; // votes to suicide contract - uint public deleteAcksReq; // number of votes needed - V[] public versions; - modifier canAccess(address addr) { - bool access = false; - for (uint i = 0; i < parties.length; i++) { - if (parties[i] == addr) { - access = true; - break; - } - } - if (access == false) { - throw; - } - _ + // updateRelease votes for a particular version to be included as the next release, + // or for the currently proposed release to be nuked out. + function updateRelease(uint32 major, uint32 minor, uint32 patch, bytes20 commit, bool release) isSigner { + // Skip nuke votes if no proposal is pending + if (!release && verProp.votes.pass.length == 0) { + return; } - - function Versions(address[] addrs) { - if (addrs.length < 2) { - throw; - } - - parties = addrs; - deleteAcksReq = (addrs.length / 2) + 1; + // Mark a new release if no proposal is pending + if (verProp.votes.pass.length == 0) { + verProp.major = major; + verProp.minor = minor; + verProp.patch = patch; + verProp.commit = commit; } - - // TODO: use dynamic array when solidity adds proper support for returning them - function GetVersions() returns (bytes32[10], uint64[10], uint[10]) { - bytes32[10] memory vs; - uint64[10] memory ts; - uint[10] memory ss; - for (uint i = 0; i < versions.length; i++) { - vs[i] = versions[i].v; - ts[i] = versions[i].ts; - ss[i] = versions[i].signers.length; - } - return (vs, ts, ss); + // Make sure positive votes match the current proposal + if (release && (verProp.major != major || verProp.minor != minor || verProp.patch != patch || verProp.commit != commit)) { + return; } - - // either submit a new version or acknowledge an existing one - function AckVersion(bytes32 ver) - canAccess(msg.sender) - { - for (uint i = 0; i < versions.length; i++) { - if (versions[i].v == ver) { - for (uint j = 0; j < versions[i].signers.length; j++) { - if (versions[i].signers[j] == msg.sender) { - // already signed - throw; - } - } - // add sender as signer of existing version - versions[i].signers.push(msg.sender); - return; - } - } - - // version is new, add it - // due to dynamic array, push it first then set values - V memory v; - versions.push(v); - versions[versions.length - 1].v = ver; - // signers is dynamic array; have to extend size manually - versions[versions.length - 1].signers.length++; - versions[versions.length - 1].signers[0] = msg.sender; - versions[versions.length - 1].ts = uint64(block.timestamp); + // Gather the current votes and ensure we don't double vote + Votes votes = verProp.votes; + for (uint i = 0; i < votes.pass.length; i++) { + if (votes.pass[i] == msg.sender) { + return; + } } - - // remove vote for a version, if present - function NackVersion(bytes32 ver) - canAccess(msg.sender) - { - for (uint i = 0; i < versions.length; i++) { - if (versions[i].v == ver) { - for (uint j = 0; j < versions[i].signers.length; j++) { - if (versions[i].signers[j] == msg.sender) { - delete versions[i].signers[j]; - } - } - } - } + for (i = 0; i < votes.fail.length; i++) { + if (votes.fail[i] == msg.sender) { + return; + } } - - // delete-this-contract vote, suicide if enough votes - function AckDelete() - canAccess(msg.sender) - { - for (uint i = 0; i < deleteAcks.length; i++) { - if (deleteAcks[i] == msg.sender) { - throw; // already acked delete - } - } - deleteAcks.push(msg.sender); - if (deleteAcks.length >= deleteAcksReq) { - suicide(msg.sender); - } + // Cast the vote and return if the proposal cannot be resolved yet + if (release) { + votes.pass.push(msg.sender); + if (votes.pass.length <= signers.length / 2) { + return; + } + } else { + votes.fail.push(msg.sender); + if (votes.fail.length <= signers.length / 2) { + return; + } } - - // remove sender's delete-this-contract vote, if present - function NackDelete() - canAccess(msg.sender) - { - uint len = deleteAcks.length; - for (uint i = 0; i < len; i++) { - if (deleteAcks[i] == msg.sender) { - if (len > 1) { - deleteAcks[i] = deleteAcks[len-1]; - } - deleteAcks.length -= 1; - } - } - }*/ + // Proposal resolved in our favor, execute whatever we voted on + if (release) { + verProp.time = uint64(now); + releases.push(verProp); + delete verProp; + } else { + delete verProp; + } + } } diff --git a/common/releases/contract_test.go b/common/releases/contract_test.go index 67dff3daaf..5fa802bffb 100644 --- a/common/releases/contract_test.go +++ b/common/releases/contract_test.go @@ -195,3 +195,60 @@ func TestSignerDemotion(t *testing.T) { } } } + +// Tests that new versions can be released, honouring both voting rights as well +// as the minimum required vote count. +func TestVersionRelease(t *testing.T) { + // Prefund a few accounts to authorize with and create the oracle + keys := make([]*ecdsa.PrivateKey, 5) + for i := 0; i < len(keys); i++ { + keys[i], _ = crypto.GenerateKey() + } + key, oracle, sim := setupReleaseTest(t, keys...) + + // Gradually push releases, always requiring more signers than previously + keys = append([]*ecdsa.PrivateKey{key}, keys...) + for i := 1; i < len(keys); i++ { + // Check that no votes are accepted from the not yet authed user + if _, err := oracle.Release(bind.NewKeyedTransactor(keys[i]), 0, 0, 0, [20]byte{0}); err != nil { + t.Fatalf("Iter #%d: failed invalid release attempt: %v", i, err) + } + sim.Commit() + + prop, err := oracle.ProposedVersion(nil) + if err != nil { + t.Fatalf("Iter #%d: failed to retrieve active proposal: %v", i, err) + } + if len(prop.Pass) != 0 { + t.Fatalf("Iter #%d: proposal vote count mismatch: have %d, want 0", i, len(prop.Pass)) + } + /*// Promote with half - 1 voters and check that the user's not yet authorized + for j := 0; j < i/2; j++ { + if _, err = oracle.Promote(bind.NewKeyedTransactor(keys[j]), crypto.PubkeyToAddress(keys[i].PublicKey)); err != nil { + t.Fatalf("Iter #%d: failed valid promotion attempt: %v", i, err) + } + } + sim.Commit() + + signers, err := oracle.Signers(nil) + if err != nil { + t.Fatalf("Iter #%d: failed to retrieve list of signers: %v", i, err) + } + if len(signers) != i { + t.Fatalf("Iter #%d: signer count mismatch: have %v, want %v", i, len(signers), i) + } + // Promote with the last one needed to pass the promotion + if _, err = oracle.Promote(bind.NewKeyedTransactor(keys[i/2]), crypto.PubkeyToAddress(keys[i].PublicKey)); err != nil { + t.Fatalf("Iter #%d: failed valid promotion completion attempt: %v", i, err) + } + sim.Commit() + + signers, err = oracle.Signers(nil) + if err != nil { + t.Fatalf("Iter #%d: failed to retrieve list of signers: %v", i, err) + } + if len(signers) != i+1 { + t.Fatalf("Iter #%d: signer count mismatch: have %v, want %v", i, len(signers), i+1) + }*/ + } +}