1515// See the License for the specific language governing permissions and
1616// limitations under the License.
1717//! Utility impl for the RPC types.
18- use super :: { ReceiptInfo , TransactionInfo , TransactionSigned } ;
18+ use super :: * ;
1919use sp_core:: U256 ;
2020
2121impl TransactionInfo {
@@ -33,8 +33,108 @@ impl TransactionInfo {
3333}
3434
3535impl ReceiptInfo {
36+ /// Initialize a new Receipt
37+ pub fn new (
38+ block_hash : H256 ,
39+ block_number : U256 ,
40+ contract_address : Option < Address > ,
41+ from : Address ,
42+ logs : Vec < Log > ,
43+ to : Option < Address > ,
44+ effective_gas_price : U256 ,
45+ gas_used : U256 ,
46+ success : bool ,
47+ transaction_hash : H256 ,
48+ transaction_index : U256 ,
49+ r#type : Byte ,
50+ ) -> Self {
51+ let logs_bloom = Self :: logs_bloom ( & logs) ;
52+ ReceiptInfo {
53+ block_hash,
54+ block_number,
55+ contract_address,
56+ from,
57+ logs,
58+ logs_bloom,
59+ to,
60+ effective_gas_price,
61+ gas_used,
62+ status : Some ( if success { U256 :: one ( ) } else { U256 :: zero ( ) } ) ,
63+ transaction_hash,
64+ transaction_index,
65+ r#type : Some ( r#type) ,
66+ ..Default :: default ( )
67+ }
68+ }
69+
3670 /// Returns `true` if the transaction was successful.
3771 pub fn is_success ( & self ) -> bool {
3872 self . status . map_or ( false , |status| status == U256 :: one ( ) )
3973 }
74+
75+ /// Calculate receipt logs bloom.
76+ fn logs_bloom ( logs : & [ Log ] ) -> Bytes256 {
77+ let mut bloom = [ 0u8 ; 256 ] ;
78+ for log in logs {
79+ m3_2048 ( & mut bloom, & log. address . as_ref ( ) ) ;
80+ for topic in & log. topics {
81+ m3_2048 ( & mut bloom, topic. as_ref ( ) ) ;
82+ }
83+ }
84+ bloom. into ( )
85+ }
86+ }
87+ /// Specialised Bloom filter that sets three bits out of 2048, given an
88+ /// arbitrary byte sequence.
89+ ///
90+ /// See Section 4.4.1 "Transaction Receipt" of the [Ethereum Yellow Paper][ref].
91+ ///
92+ /// [ref]: https://ethereum.github.io/yellowpaper/paper.pdf
93+ fn m3_2048 ( bloom : & mut [ u8 ; 256 ] , bytes : & [ u8 ] ) {
94+ let hash = sp_core:: keccak_256 ( bytes) ;
95+ for i in [ 0 , 2 , 4 ] {
96+ let bit = ( hash[ i + 1 ] as usize + ( ( hash[ i] as usize ) << 8 ) ) & 0x7FF ;
97+ bloom[ 256 - 1 - bit / 8 ] |= 1 << ( bit % 8 ) ;
98+ }
99+ }
100+
101+ #[ test]
102+ fn logs_bloom_works ( ) {
103+ let receipt: ReceiptInfo = serde_json:: from_str (
104+ r#"
105+ {
106+ "blockHash": "0x835ee379aaabf4802a22a93ad8164c02bbdde2cc03d4552d5c642faf4e09d1f3",
107+ "blockNumber": "0x2",
108+ "contractAddress": null,
109+ "cumulativeGasUsed": "0x5d92",
110+ "effectiveGasPrice": "0x2dcd5c2d",
111+ "from": "0xb4f1f9ecfe5a28633a27f57300bda217e99b8969",
112+ "gasUsed": "0x5d92",
113+ "logs": [
114+ {
115+ "address": "0x82bdb002b9b1f36c42df15fbdc6886abcb2ab31d",
116+ "topics": [
117+ "0x1585375487296ff2f0370daeec4214074a032b31af827c12622fa9a58c16c7d0",
118+ "0x000000000000000000000000b4f1f9ecfe5a28633a27f57300bda217e99b8969"
119+ ],
120+ "data": "0x00000000000000000000000000000000000000000000000000000000000030390000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000b48656c6c6f20776f726c64000000000000000000000000000000000000000000",
121+ "blockNumber": "0x2",
122+ "transactionHash": "0xad0075127962bdf73d787f2944bdb5f351876f23c35e6a48c1f5b6463a100af4",
123+ "transactionIndex": "0x0",
124+ "blockHash": "0x835ee379aaabf4802a22a93ad8164c02bbdde2cc03d4552d5c642faf4e09d1f3",
125+ "logIndex": "0x0",
126+ "removed": false
127+ }
128+ ],
129+ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000008000000000000000000000000000000000000000000000000800000000040000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000004000000000000000800000000000000000080000000000000000000000000000000000000000000",
130+ "status": "0x1",
131+ "to": "0x82bdb002b9b1f36c42df15fbdc6886abcb2ab31d",
132+ "transactionHash": "0xad0075127962bdf73d787f2944bdb5f351876f23c35e6a48c1f5b6463a100af4",
133+ "transactionIndex": "0x0",
134+ "type": "0x2"
135+ }
136+ "# ,
137+ )
138+ . unwrap ( ) ;
139+ assert_eq ! ( receipt. logs_bloom, ReceiptInfo :: logs_bloom( & receipt. logs) ) ;
40140}
0 commit comments